1 chuck 1.2 //%2003////////////////////////////////////////////////////////////////////////
2 //
3 // Copyright (c) 2000, 2001, 2002 BMC Software, Hewlett-Packard Development
4 // Company, L. P., IBM Corp., The Open Group, Tivoli Systems.
5 // Copyright (c) 2003 BMC Software; Hewlett-Packard Development Company, L. P.;
6 // IBM Corp.; EMC Corporation, The Open Group.
7 //
8 // Permission is hereby granted, free of charge, to any person obtaining a copy
9 // of this software and associated documentation files (the "Software"), to
10 // deal in the Software without restriction, including without limitation the
11 // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
12 // sell copies of the Software, and to permit persons to whom the Software is
13 // furnished to do so, subject to the following conditions:
14 //
15 // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
16 // ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED
17 // "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
18 // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
19 // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
20 // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
21 // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22 chuck 1.2 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 //
24 //==============================================================================
25 //
26 // Authors: David Rosckes (rosckes@us.ibm.com)
27 // Bert Rivero (hurivero@us.ibm.com)
28 // Chuck Carmack (carmack@us.ibm.com)
29 // Brian Lucier (lucier@us.ibm.com)
30 //
31 // Modified By:
32 //
33 //%/////////////////////////////////////////////////////////////////////////////
|
34 lucier 1.7
|
35 chuck 1.2 #include <Pegasus/CQL/CQLUtilities.h>
|
36 lucier 1.7
37 // Query includes
38 #include <Pegasus/Query/QueryCommon/QueryException.h>
39
40 // Pegasus Common includes
41 #include <Pegasus/Common/Tracer.h>
42
43 // standard includes
|
44 chuck 1.3 #include <errno.h>
|
45 chuck 1.2
|
46 lucier 1.7 // symbol defines
|
47 chuck 1.2 #define PEGASUS_SINT64_MIN (PEGASUS_SINT64_LITERAL(0x8000000000000000))
48 #define PEGASUS_UINT64_MAX PEGASUS_UINT64_LITERAL(0xFFFFFFFFFFFFFFFF)
49
|
50 lucier 1.7 // required for the windows compile
|
51 lucier 1.5 #ifndef _MSC_VER
52 #define _MSC_VER 0
53 #endif
54
|
55 chuck 1.2 PEGASUS_NAMESPACE_BEGIN
56
|
57 lucier 1.4 inline Uint8 _CQLUtilities_hexCharToNumeric(const Char16 c)
|
58 chuck 1.2 {
59 Uint8 n;
60
61 if (isdigit(c))
62 n = (c - '0');
63 else if (isupper(c))
64 n = (c - 'A' + 10);
65 else // if (islower(c))
66 n = (c - 'a' + 10);
67
68 return n;
69 }
70
71 Uint64 CQLUtilities::stringToUint64(const String &stringNum)
72 {
|
73 lucier 1.7 PEG_METHOD_ENTER(TRC_CQL,"CQLUtilities::stringToUint64()");
74
|
75 chuck 1.2 Uint64 x = 0;
76 const Char16* p = stringNum.getChar16Data();
77 const Char16* pStart = p;
78
|
79 lucier 1.8 if (String::equal(stringNum, String::EMPTY))
80 {
81 MessageLoaderParms mload(String("CQL.CQLUtilities.EMPTY_STRING"),
82 String("String cannot be empty."));
83 throw CQLRuntimeException(mload);
84 }
85
|
86 chuck 1.2 if (!p)
|
87 lucier 1.7 {
88 MessageLoaderParms mload(String("CQL.CQLUtilities.NULL_INPUT"),
|
89 lucier 1.8 String("String cannot be NULL."));
|
90 lucier 1.7 throw CQLRuntimeException(mload);
91 }
|
92 chuck 1.2
93 // There cannot be a negative '-' sign
94 if (*p == '-')
|
95 lucier 1.7 {
96 MessageLoaderParms mload(String("CQL.CQLUtilities.INVALID_NEG"),
|
97 lucier 1.8 String("String $0 cannot begin with '-'."),
|
98 lucier 1.7 stringNum);
99 throw CQLRuntimeException(mload);
100 }
|
101 chuck 1.2 if (*p == '+')
102 p++; // skip over the positive sign
103
104 if (!isdigit(*p))
|
105 lucier 1.7 {
106 MessageLoaderParms mload(String("CQL.CQLUtilities.INVALID_NUM_FORMAT"),
|
107 lucier 1.9 String("String '$0' is badly formed. It must be of the form; [+][0-9]*"),
|
108 lucier 1.7 stringNum);
109 throw CQLRuntimeException(mload);
110 }
|
111 chuck 1.2
112 // if binary
113 Uint32 endString = stringNum.size() - 1;
114 if ( (pStart[endString] == 'b') || (pStart[endString] == 'B') )
115 {
116 // Add on each digit, checking for overflow errors
117 while ((*p == '0') || (*p == '1'))
118 {
119 // Make sure we won't overflow when we multiply by 2
120 if (x > PEGASUS_UINT64_MAX/2)
|
121 lucier 1.7 {
122 MessageLoaderParms mload(String("CQL.CQLUtilities.OVERFLOW"),
123 String("String $0 caused an overflow."),
124 stringNum);
125 throw CQLRuntimeException(mload);
126 }
|
127 chuck 1.2
128 x = x << 1;
129
130 // We can't overflow when we add the next digit
131 Uint64 newDigit = 0;
132 if (*p++ == '1')
133 newDigit = 1;
134 if (PEGASUS_UINT64_MAX - x < newDigit)
|
135 lucier 1.7 {
136 MessageLoaderParms mload(String("CQL.CQLUtilities.OVERFLOW"),
137 String("String $0 caused an overflow."),
138 stringNum);
139 throw CQLRuntimeException(mload);
140 }
|
141 chuck 1.2
142 x = x + newDigit;
143 }
144
145 // If we found a non-binary digit, report an error
146 if (*p && (*p != 'b') && (*p != 'B'))
|
147 lucier 1.7 {
148 MessageLoaderParms mload(String("CQL.CQLUtilities.INVALID_BIN_CHAR"),
|
149 lucier 1.9 String("Character '$0' in string '$1' is not a binary digit."),
150 String(p, 1), stringNum);
|
151 lucier 1.7 throw CQLRuntimeException(mload);
152 }
|
153 chuck 1.2
154 // return value from the binary string
|
155 lucier 1.7 PEG_METHOD_EXIT();
|
156 chuck 1.2 return x;
157 } // end if binary
158
159 // if hexidecimal
160 if ( (*p == '0') && ((p[1] == 'x') || (p[1] == 'X')) )
161 {
162 // Convert a hexadecimal string
163
164 // Skip over the "0x"
165 p+=2;
166
167 // At least one hexadecimal digit is required
168 if (!*p)
|
169 lucier 1.7 {
170 MessageLoaderParms mload(String("CQL.CQLUtilities.INVALID_HEX_FORMAT"),
|
171 lucier 1.9 String("String '$0' needs a hexadecimal digit character following '0x'"),
|
172 lucier 1.7 stringNum);
173 throw CQLRuntimeException(mload);
174 }
|
175 chuck 1.2
176 // Add on each digit, checking for overflow errors
177 while (isxdigit(*p))
178 {
179 // Make sure we won't overflow when we multiply by 16
180 if (x > PEGASUS_UINT64_MAX/16)
|
181 lucier 1.7 {
182 MessageLoaderParms mload(String("CQL.CQLUtilities.OVERFLOW"),
183 String("String $0 caused an overflow."),
184 stringNum);
185 throw CQLRuntimeException(mload);
186 }
|
187 chuck 1.2
188 x = x << 4;
189
190 // We can't overflow when we add the next digit
191 Uint64 newDigit = Uint64(_CQLUtilities_hexCharToNumeric(*p++));
192 if (PEGASUS_UINT64_MAX - x < newDigit)
|
193 lucier 1.7 {
194 MessageLoaderParms mload(String("CQL.CQLUtilities.OVERFLOW"),
195 String("String $0 caused an overflow."),
196 stringNum);
197 throw CQLRuntimeException(mload);
198 }
|
199 chuck 1.2
200 x = x + newDigit;
201 }
202
203 // If we found a non-hexadecimal digit, report an error
204 if (*p)
|
205 lucier 1.7 {
206 MessageLoaderParms mload(String("CQL.CQLUtilities.INVALID_HEX_CHAR"),
|
207 lucier 1.9 String("Character '$0' in string '$1' is not a hexidecimal digit."),
208 String(p, 1), stringNum);
|
209 lucier 1.7 throw CQLRuntimeException(mload);
210 }
|
211 chuck 1.2
212 // return value from the hex string
|
213 lucier 1.7 PEG_METHOD_EXIT();
|
214 chuck 1.2 return x;
215 } // end if hexidecimal
216
217
218 // Expect a positive decimal digit:
219
220 // Add on each digit, checking for overflow errors
221 while (isdigit(*p))
222 {
223 // Make sure we won't overflow when we multiply by 10
224 if (x > PEGASUS_UINT64_MAX/10)
|
225 lucier 1.7 {
226 MessageLoaderParms mload(String("CQL.CQLUtilities.OVERFLOW"),
227 String("String $0 caused an overflow."),
228 stringNum);
229 throw CQLRuntimeException(mload);
230 }
|
231 chuck 1.2 x = 10 * x;
232
233 // Make sure we won't overflow when we add the next digit
234 Uint64 newDigit = (*p++ - '0');
235 if (PEGASUS_UINT64_MAX - x < newDigit)
|
236 lucier 1.7 {
237 MessageLoaderParms mload(String("CQL.CQLUtilities.OVERFLOW"),
238 String("String $0 caused an overflow."),
239 stringNum);
240 throw CQLRuntimeException(mload);
241 }
|
242 chuck 1.2
243 x = x + newDigit;
244 }
245
|
246 lucier 1.9 // If we found a non-decimal digit, report an error
|
247 chuck 1.2 if (*p)
|
248 lucier 1.7 {
|
249 lucier 1.9 MessageLoaderParms mload(String("CQL.CQLUtilities.INVALID_DECIMAL_CHAR"),
250 String("Character '$0' in string '$1' is not a decimal digit."),
251 String(p, 1), stringNum);
252 throw CQLRuntimeException(mload);
|
253 lucier 1.7 }
|
254 chuck 1.2
255 // return the value for the decimal string
|
256 lucier 1.7 PEG_METHOD_EXIT();
|
257 chuck 1.2 return x;
258 }
259
260 Sint64 CQLUtilities::stringToSint64(const String &stringNum)
261 {
|
262 lucier 1.7 PEG_METHOD_ENTER(TRC_CQL,"CQLUtilities::stringToSint64()");
263
|
264 chuck 1.2 Sint64 x = 0;
265 Boolean invert = false;
266 const Char16* p = stringNum.getChar16Data();
267 const Char16* pStart = p;
268
|
269 lucier 1.8 if (String::equal(stringNum, String::EMPTY))
270 {
271 MessageLoaderParms mload(String("CQL.CQLUtilities.EMPTY_STRING"),
272 String("String cannot be empty."));
273 throw CQLRuntimeException(mload);
274 }
275
|
276 chuck 1.2 if (!p)
|
277 lucier 1.7 {
278 MessageLoaderParms mload(String("CQL.CQLUtilities.NULL_INPUT"),
|
279 lucier 1.8 String("String cannot be NULL."));
|
280 lucier 1.7 throw CQLRuntimeException(mload);
281 }
|
282 chuck 1.2
283 // skip over the sign if there is one
284 if (*p == '-')
285 {
286 invert = true;
287 p++;
288 }
289 if (*p == '+')
290 p++;
291
292 if (!isdigit(*p))
|
293 lucier 1.7 {
294 MessageLoaderParms mload(String("CQL.CQLUtilities.INVALID_NUM_FORMAT"),
|
295 lucier 1.9 String("String '$0' is badly formed. It must be of the form; [+-][0-9]*"),
|
296 lucier 1.7 stringNum);
297 throw CQLRuntimeException(mload);
298 }
|
299 chuck 1.2
300 // ********************
301 // Build the Sint64 as a negative number, regardless of the
302 // eventual sign (negative numbers can be bigger than positive ones)
303 // ********************
304
305 // if binary
306 Uint32 endString = stringNum.size() - 1;
307 if ( (pStart[endString] == 'b') || (pStart[endString] == 'B') )
308 {
309 // Add on each digit, checking for overflow errors
310 while ((*p == '0') || (*p == '1'))
311 {
312 // Make sure we won't overflow when we multiply by 2
313 if (x < PEGASUS_SINT64_MIN/2)
|
314 lucier 1.7 {
315 MessageLoaderParms mload(String("CQL.CQLUtilities.OVERFLOW"),
316 String("String $0 caused an overflow."),
317 stringNum);
318 throw CQLRuntimeException(mload);
319 }
|
320 chuck 1.2
321 x = x << 1;
322
323 // We can't overflow when we add the next digit
324 Sint64 newDigit = 0;
325 if (*p++ == '1')
326 newDigit = 1;
327 if (PEGASUS_SINT64_MIN - x > -newDigit)
|
328 lucier 1.7 {
329 MessageLoaderParms mload(String("CQL.CQLUtilities.OVERFLOW"),
330 String("String $0 caused an overflow."),
331 stringNum);
332 throw CQLRuntimeException(mload);
333 }
|
334 chuck 1.2
335 x = x - newDigit;
336 }
337
338 // If we found a non-binary digit, report an error
339 if (*p && (*p != 'b') && (*p != 'B'))
|
340 lucier 1.7 {
341 MessageLoaderParms mload(String("CQL.CQLUtilities.INVALID_BIN_CHAR"),
|
342 lucier 1.9 String("Character '$0' in string '$1' is not a binary digit."),
343 String(p, 1), stringNum);
|
344 lucier 1.7 throw CQLRuntimeException(mload);
345 }
|
346 chuck 1.2
347 // Return the integer to positive, if necessary, checking for an
348 // overflow error
349 if (!invert)
350 {
351 if (x == PEGASUS_SINT64_MIN)
|
352 lucier 1.7 {
353 MessageLoaderParms mload(String("CQL.CQLUtilities.OVERFLOW"),
354 String("String $0 caused an overflow."),
355 stringNum);
356 throw CQLRuntimeException(mload);
357 }
|
358 chuck 1.2 x = -x;
359 }
360
361 // return value from the binary string
|
362 lucier 1.7 PEG_METHOD_EXIT();
|
363 chuck 1.2 return x;
364 } // end if binary
365
366 // if hexidecimal
367 if ( (*p == '0') && ((p[1] == 'x') || (p[1] == 'X')) )
368 {
369 // Convert a hexadecimal string
370
371 // Skip over the "0x"
372 p+=2;
373
|
374 lucier 1.9 // At least one hexidecimal digit is required
|
375 chuck 1.2 if (!*p)
|
376 lucier 1.7 {
377 MessageLoaderParms mload(String("CQL.CQLUtilities.INVALID_HEX_FORMAT"),
|
378 lucier 1.9 String("String '$0' needs a hexidecimal digit character following '0x'"),
|
379 lucier 1.7 stringNum);
380 throw CQLRuntimeException(mload);
381 }
|
382 chuck 1.2
383 // Add on each digit, checking for overflow errors
384 while (isxdigit(*p))
385 {
386 // Make sure we won't overflow when we multiply by 16
|
387 lucier 1.4 if (x < PEGASUS_SINT64_MIN/16)
|
388 lucier 1.7 {
389 MessageLoaderParms mload(String("CQL.CQLUtilities.OVERFLOW"),
390 String("String $0 caused an overflow."),
391 stringNum);
392 throw CQLRuntimeException(mload);
393 }
|
394 chuck 1.2
395 x = x << 4;
396
397 // We can't overflow when we add the next digit
398 Sint64 newDigit = Sint64(_CQLUtilities_hexCharToNumeric(*p++));
399 if (PEGASUS_SINT64_MIN - x > -newDigit)
|
400 lucier 1.7 {
401 MessageLoaderParms mload(String("CQL.CQLUtilities.OVERFLOW"),
402 String("String $0 caused an overflow."),
403 stringNum);
404 throw CQLRuntimeException(mload);
405 }
|
406 chuck 1.2
|
407 lucier 1.4 x = x - newDigit;
|
408 chuck 1.2 }
409
|
410 lucier 1.9 // If we found a non-hexidecimal digit, report an error
|
411 chuck 1.2 if (*p)
|
412 lucier 1.7 {
413 MessageLoaderParms mload(String("CQL.CQLUtilities.INVALID_HEX_CHAR"),
|
414 lucier 1.9 String("Character '$0' in string '$1' is not a hexidecimal digit."),
415 String(p, 1), stringNum);
|
416 lucier 1.7 throw CQLRuntimeException(mload);
417 }
|
418 chuck 1.2
419 // Return the integer to positive, if necessary, checking for an
420 // overflow error
421 if (!invert)
422 {
423 if (x == PEGASUS_SINT64_MIN)
|
424 lucier 1.7 {
425 MessageLoaderParms mload(String("CQL.CQLUtilities.OVERFLOW"),
426 String("String $0 caused an overflow."),
427 stringNum);
428 throw CQLRuntimeException(mload);
429 }
|
430 chuck 1.2 x = -x;
431 }
432
433 // return value from the hex string
|
434 lucier 1.7 PEG_METHOD_EXIT();
|
435 chuck 1.2 return x;
436 } // end if hexidecimal
437
438
439 // Expect a positive decimal digit:
440
441 // Add on each digit, checking for overflow errors
442 while (isdigit(*p))
443 {
444 // Make sure we won't overflow when we multiply by 10
|
445 lucier 1.4 if (x < PEGASUS_SINT64_MIN/10)
|
446 lucier 1.7 {
447 MessageLoaderParms mload(String("CQL.CQLUtilities.OVERFLOW"),
448 String("String $0 caused an overflow."),
449 stringNum);
450 throw CQLRuntimeException(mload);
451 }
|
452 chuck 1.2 x = 10 * x;
453
454 // Make sure we won't overflow when we add the next digit
455 Sint64 newDigit = (*p++ - '0');
456 if (PEGASUS_SINT64_MIN - x > -newDigit)
|
457 lucier 1.7 {
458 MessageLoaderParms mload(String("CQL.CQLUtilities.OVERFLOW"),
459 String("String $0 caused an overflow."),
460 stringNum);
461 throw CQLRuntimeException(mload);
462 }
|
463 chuck 1.2
|
464 lucier 1.4 x = x - newDigit;
|
465 chuck 1.2 }
466
467 // If we found a non-decimal digit, report an error
468 if (*p)
|
469 lucier 1.7 {
470 MessageLoaderParms mload(String("CQL.CQLUtilities.INVALID_DECIMAL_CHAR"),
|
471 lucier 1.9 String("Character '$0' in string '$1' is not a decimal digit."),
472 String(p, 1), stringNum);
|
473 lucier 1.7 throw CQLRuntimeException(mload);
474 }
|
475 chuck 1.2
476 // Return the integer to positive, if necessary, checking for an
477 // overflow error
478 if (!invert)
479 {
480 if (x == PEGASUS_SINT64_MIN)
|
481 lucier 1.7 {
482 MessageLoaderParms mload(String("CQL.CQLUtilities.OVERFLOW"),
483 String("String $0 caused an overflow."),
484 stringNum);
485 throw CQLRuntimeException(mload);
486 }
|
487 chuck 1.2 x = -x;
488 }
489
490 // return the value for the decimal string
|
491 lucier 1.7 PEG_METHOD_EXIT();
|
492 chuck 1.2 return x;
493 }
494
495 Real64 CQLUtilities::stringToReal64(const String &stringNum)
496 {
|
497 lucier 1.7 PEG_METHOD_ENTER(TRC_CQL,"CQLUtilities::stringToReal64()");
498
|
499 chuck 1.2 Real64 x = 0;
500 const Char16* p = stringNum.getChar16Data();
|
501 lucier 1.4 Boolean neg = false;
502 const Char16* pStart = p;
|
503 chuck 1.2
|
504 lucier 1.8 if (String::equal(stringNum, String::EMPTY))
505 {
506 MessageLoaderParms mload(String("CQL.CQLUtilities.EMPTY_STRING"),
507 String("String cannot be empty."));
508 throw CQLRuntimeException(mload);
509 }
510
511 if (!p)
|
512 lucier 1.7 {
513 MessageLoaderParms mload(String("CQL.CQLUtilities.NULL_INPUT"),
|
514 lucier 1.8 String("String cannot be NULL."));
|
515 lucier 1.7 throw CQLRuntimeException(mload);
516 }
|
517 chuck 1.2
|
518 lucier 1.4
|
519 chuck 1.2 // Skip optional sign:
520
|
521 lucier 1.4 if (*p == '+')
|
522 chuck 1.2 p++;
|
523 lucier 1.4
524 if (*p == '-')
525 {
526 neg = true;
527 p++;
528 };
|
529 lucier 1.5
|
530 lucier 1.4 // Check if it it is a binary or hex integer
531 Uint32 endString = stringNum.size() - 1;
532 if ((*p == '0' && (p[1] == 'x' || p[1] == 'X')) || // hex OR
533 pStart[endString] == 'b' || pStart[endString] == 'B') // binary
534 {
535 if (neg)
536 x = stringToSint64(stringNum);
537 else
|
538 lucier 1.5
539 // Check if the complier is MSVC 6, which does not support the conversion operator from Uint64 to Real64
540 #if defined(PEGASUS_PLATFORM_WIN32_IX86_MSVC) && (_MSC_VER < 1300)
541 {
542 Uint64 num = stringToUint64(stringNum);
543 Sint64 half = num / 2;
544 x = half;
|
545 lucier 1.6 x += half;
|
546 lucier 1.5 if (num % 2) // if odd, then add the lost remainder
547 x += 1;
548 }
549 #else
|
550 lucier 1.4 x = stringToUint64(stringNum);
|
551 lucier 1.5 #endif
|
552 lucier 1.7 PEG_METHOD_EXIT();
|
553 lucier 1.4 return x;
554 }
555
|
556 chuck 1.2 // Skip optional first set of digits:
557
558 while (isdigit(*p))
559 p++;
560
561 // Test if optional dot is there
562 if (*p++ == '.')
563 {
564 // One or more digits required:
565 if (!isdigit(*p++))
|
566 lucier 1.7 {
567 MessageLoaderParms mload(String("CQL.CQLUtilities.INVALID_CHAR_POST_DOT"),
|
568 lucier 1.9 String("String '$0' must have a digit character following the decimal point."),
|
569 lucier 1.7 stringNum);
570 throw CQLRuntimeException(mload);
571 }
|
572 chuck 1.2
573 while (isdigit(*p))
574 p++;
575
576 // If there is an exponent now:
577 if (*p)
578 {
579 // Test exponent:
580
581 if (*p != 'e' && *p != 'E')
|
582 lucier 1.7 {
583 MessageLoaderParms mload(String("CQL.CQLUtilities.INVALID_REAL_CHAR"),
|
584 lucier 1.9 String("Character '$0' in string '$1` is invalid for a real number."),
585 String(p-1, 1), stringNum);
|
586 lucier 1.7 throw CQLRuntimeException(mload);
587 }
|
588 chuck 1.2 p++;
589
590 // Skip optional sign:
591
592 if (*p == '+' || *p == '-')
593 p++;
594
595 // One or more digits required:
596 if (!isdigit(*p++))
|
597 lucier 1.7 {
598 MessageLoaderParms mload(String("CQL.CQLUtilities.INVALID_REAL_EXP"),
|
599 lucier 1.9 String("String '$0' has an badly formed exponent. It must be of the form [eE][+-][0-9]*.. Character '$1' is invalid."),
600 stringNum, String(p, 1));
|
601 lucier 1.7 throw CQLRuntimeException(mload);
602 }
|
603 chuck 1.2
604 while (isdigit(*p))
605 p++;
606 }
|
607 lucier 1.7 } // end-if optional decimal point
|
608 lucier 1.8 if (*p && p - pStart <= stringNum.size())
|
609 lucier 1.7 {
|
610 lucier 1.8 // printf("This is char # %d\n", p - pStart);
|
611 lucier 1.7 MessageLoaderParms mload(String("CQL.CQLUtilities.INVALID_DECIMAL_CHAR"),
|
612 lucier 1.9 String("Character '$0' in string '$1' is not a decimal digit."),
613 String(p-1, 1), stringNum);
|
614 lucier 1.7 throw CQLRuntimeException(mload);
|
615 chuck 1.2 }
616 //
617 // Do the conversion
618 //
619 char* end;
620 errno = 0;
621 CString temp = stringNum.getCString();
622 x = strtod((const char *) temp, &end);
623 if (*end || (errno == ERANGE))
624 {
|
625 humberto 1.10 MessageLoaderParms mload(String("CQL.CQLUtilities.CONVERSION_REAL_ERROR"),
|
626 lucier 1.7 String("String $0 was unable to be converted to a Real64. It could be out of range."),
627 stringNum);
628 throw CQLRuntimeException(mload);
|
629 chuck 1.2 }
|
630 lucier 1.7 PEG_METHOD_EXIT();
|
631 lucier 1.9 // printf("String %s = %.16e\n", (const char *)stringNum.getCString(), x);
|
632 chuck 1.2 return x;
633 }
634
|
635 lucier 1.11 String CQLUtilities::formatRealStringExponent(const String &realString)
636 {
637 String newString(realString);
638 Uint32 expIndex = PEG_NOT_FOUND;
639 Uint32 index = newString.size() - 1;
640
641 expIndex = newString.find('E');
642 if (expIndex == PEG_NOT_FOUND)
643 expIndex = newString.find('e');
644
645 if (expIndex == PEG_NOT_FOUND)
646 return newString; // no exponent symbol, so just return
647
648 // format the exponent
649 index = expIndex + 1; // start index at next character
650 if (newString[index] == '+')
651 newString.remove(index, 1); // remove the '+' symbol
652
653 if (newString[index] == '-')
654 index++; // skip the '-' exponent sign
655
656 lucier 1.11 while (newString[index] == '0' && index < newString.size())
657 {
658 newString.remove(index, 1);
659 }
660
661 // If only an 'e' is left (only 0's behind it) then strip the 'e'
662 if (index >= newString.size())
663 newString.remove(expIndex, 1);
664
665 return newString;
666 }
667
|
668 chuck 1.2 PEGASUS_NAMESPACE_END
|