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

  1 mike  1.1 //%2006////////////////////////////////////////////////////////////////////////
  2           //
  3           // Copyright (c, 2 2000, 2001, 2002 BMC Software; Hewlett-Packard Development
  4           // Company, L.P.; IBM Corp.; The Open Group; Tivoli Systems.
  5           // Copyright (c, 2 2003 BMC Software; Hewlett-Packard Development Company, L.P.;
  6           // IBM Corp.; EMC Corporation, The Open Group.
  7           // Copyright (c, 2 2004 BMC Software; Hewlett-Packard Development Company, L.P.;
  8           // IBM Corp.; EMC Corporation; VERITAS Software Corporation; The Open Group.
  9           // Copyright (c, 2 2005 Hewlett-Packard Development Company, L.P.; IBM Corp.;
 10           // EMC Corporation; VERITAS Software Corporation; The Open Group.
 11           // Copyright (c, 2 2006 Hewlett-Packard Development Company, L.P.; IBM Corp.;
 12           // EMC Corporation; Symantec Corporation; The Open Group.
 13           //
 14           // Permission is hereby granted, free of charge, to any person obtaining a copy
 15           // of this software and associated documentation files (the "Software", 2, to
 16           // deal in the Software without restriction, including without limitation the
 17           // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
 18           // sell copies of the Software, and to permit persons to whom the Software is
 19           // furnished to do so, subject to the following conditions:
 20           // 
 21           // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
 22 mike  1.1 // ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED
 23           // "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
 24           // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
 25           // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 26           // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 27           // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 28           // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 29           //
 30           //%/////////////////////////////////////////////////////////////////////////////
 31           
 32           #include "StringConversion.h"
 33           
 34 kumpf 1.3 #include <errno.h>
 35           
 36 mike  1.1 PEGASUS_NAMESPACE_BEGIN
 37           
 38           struct Uint32ToStringElement
 39           {
 40               const char* str;
 41               size_t size;
 42           };
 43           
 44           static Uint32ToStringElement _Uint32Strings[] =
 45           {
 46               { "0", 1 },
 47               { "1", 1 },
 48               { "2", 1 },
 49               { "3", 1 },
 50               { "4", 1 },
 51               { "5", 1 },
 52               { "6", 1 },
 53               { "7", 1 },
 54               { "8", 1 },
 55               { "9", 1 },
 56               { "10", 2 },
 57 mike  1.1     { "11", 2 },
 58               { "12", 2 },
 59               { "13", 2 },
 60               { "14", 2 },
 61               { "15", 2 },
 62               { "16", 2 },
 63               { "17", 2 },
 64               { "18", 2 },
 65               { "19", 2 },
 66               { "20", 2 },
 67               { "21", 2 },
 68               { "22", 2 },
 69               { "23", 2 },
 70               { "24", 2 },
 71               { "25", 2 },
 72               { "26", 2 },
 73               { "27", 2 },
 74               { "28", 2 },
 75               { "29", 2 },
 76               { "30", 2 },
 77               { "31", 2 },
 78 mike  1.1     { "32", 2 },
 79               { "33", 2 },
 80               { "34", 2 },
 81               { "35", 2 },
 82               { "36", 2 },
 83               { "37", 2 },
 84               { "38", 2 },
 85               { "39", 2 },
 86               { "40", 2 },
 87               { "41", 2 },
 88               { "42", 2 },
 89               { "43", 2 },
 90               { "44", 2 },
 91               { "45", 2 },
 92               { "46", 2 },
 93               { "47", 2 },
 94               { "48", 2 },
 95               { "49", 2 },
 96               { "50", 2 },
 97               { "51", 2 },
 98               { "52", 2 },
 99 mike  1.1     { "53", 2 },
100               { "54", 2 },
101               { "55", 2 },
102               { "56", 2 },
103               { "57", 2 },
104               { "58", 2 },
105               { "59", 2 },
106               { "60", 2 },
107               { "61", 2 },
108               { "62", 2 },
109               { "63", 2 },
110               { "64", 2 },
111               { "65", 2 },
112               { "66", 2 },
113               { "67", 2 },
114               { "68", 2 },
115               { "69", 2 },
116               { "70", 2 },
117               { "71", 2 },
118               { "72", 2 },
119               { "73", 2 },
120 mike  1.1     { "74", 2 },
121               { "75", 2 },
122               { "76", 2 },
123               { "77", 2 },
124               { "78", 2 },
125               { "79", 2 },
126               { "80", 2 },
127               { "81", 2 },
128               { "82", 2 },
129               { "83", 2 },
130               { "84", 2 },
131               { "85", 2 },
132               { "86", 2 },
133               { "87", 2 },
134               { "88", 2 },
135               { "89", 2 },
136               { "90", 2 },
137               { "91", 2 },
138               { "92", 2 },
139               { "93", 2 },
140               { "94", 2 },
141 mike  1.1     { "95", 2 },
142               { "96", 2 },
143               { "97", 2 },
144               { "98", 2 },
145               { "99", 2 },
146               { "100", 3 },
147               { "101", 3 },
148               { "102", 3 },
149               { "103", 3 },
150               { "104", 3 },
151               { "105", 3 },
152               { "106", 3 },
153               { "107", 3 },
154               { "108", 3 },
155               { "109", 3 },
156               { "110", 3 },
157               { "111", 3 },
158               { "112", 3 },
159               { "113", 3 },
160               { "114", 3 },
161               { "115", 3 },
162 mike  1.1     { "116", 3 },
163               { "117", 3 },
164               { "118", 3 },
165               { "119", 3 },
166               { "120", 3 },
167               { "121", 3 },
168               { "122", 3 },
169               { "123", 3 },
170               { "124", 3 },
171               { "125", 3 },
172               { "126", 3 },
173               { "127", 3 },
174           };
175           
176           template<class S, class U>
177           struct Converter
178           {
179               static inline const char* uintToString(char buffer[22], U x, Uint32& size)
180               {
181                   if (x < 128)
182                   {
183 mike  1.1             size = _Uint32Strings[x].size;
184                       return _Uint32Strings[x].str;
185                   }
186           
187                   char* p = &buffer[21];
188                   *p = '\0';
189           
190                   do
191                   {
192                       *--p = '0' + (x % 10);
193                       x = x / 10;
194                   }
195                   while (x);
196           
197                   size = &buffer[21] - p;
198                   return p;
199               }
200           
201               static inline const char* sintToString(char buffer[22], S x, Uint32& size)
202               {
203                   if (x < 0)
204 mike  1.1         {
205                       char* p = &buffer[21];
206                       *p = '\0';
207           
208                       U t = U(-x);
209           
210                       do
211                       {
212                           *--p = '0' + (t % 10);
213                           t = t / 10;
214                       }
215                       while (t);
216           
217                       *--p = '-';
218           
219                       size = &buffer[21] - p;
220                       return p;
221                   }
222                   else
223                       return Converter<S, U>::uintToString(buffer, U(x), size);
224               }
225 mike  1.1 };
226           
227           const char* Uint8ToString(char buffer[22], Uint8 x, Uint32& size)
228           {
229               return Converter<Sint8, Uint8>::uintToString(buffer, x, size);
230           }
231           
232           const char* Uint16ToString(char buffer[22], Uint16 x, Uint32& size)
233           {
234               return Converter<Sint16, Uint16>::uintToString(buffer, x, size);
235           }
236           
237           const char* Uint32ToString(char buffer[22], Uint32 x, Uint32& size)
238           {
239               return Converter<Sint32, Uint32>::uintToString(buffer, x, size);
240           }
241           
242           const char* Uint64ToString(char buffer[22], Uint64 x, Uint32& size)
243           {
244               return Converter<Sint64, Uint64>::uintToString(buffer, x, size);
245           }
246 mike  1.1 
247           const char* Sint8ToString(char buffer[22], Sint8 x, Uint32& size)
248           {
249               return Converter<Sint8, Uint8>::sintToString(buffer, x, size);
250           }
251           
252           const char* Sint16ToString(char buffer[22], Sint16 x, Uint32& size)
253           {
254               return Converter<Sint16, Uint16>::sintToString(buffer, x, size);
255           }
256           
257           const char* Sint32ToString(char buffer[22], Sint32 x, Uint32& size)
258           {
259               return Converter<Sint32, Uint32>::sintToString(buffer, x, size);
260           }
261           
262           const char* Sint64ToString(char buffer[22], Sint64 x, Uint32& size)
263           {
264               return Converter<Sint64, Uint64>::sintToString(buffer, x, size);
265           }
266           
267 kumpf 1.2 //------------------------------------------------------------------------------
268           //
269           // decimalStringToUint64
270           //
271           //      ( positiveDecimalDigit *decimalDigit | "0" )
272           //
273           //------------------------------------------------------------------------------
274           
275           Boolean StringConversion::decimalStringToUint64(
276               const char* stringValue,
277               Uint64& x)
278           {
279               x = 0;
280               const char* p = stringValue;
281           
282               if (!p || !*p)
283               {
284                   return false;
285               }
286           
287               if (*p == '0')
288 kumpf 1.2     {
289                   // A decimal string that starts with '0' must be exactly "0".
290                   return p[1] == '\0';
291               }
292           
293               // Add on each digit, checking for overflow errors
294               while (isdigit(*p))
295               {
296                   // Make sure we won't overflow when we multiply by 10
297                   if (x > PEGASUS_UINT64_LITERAL(0xFFFFFFFFFFFFFFFF)/10)
298                   {
299                       return false;
300                   }
301                   x = 10 * x;
302           
303                   // Make sure we won't overflow when we add the next digit
304                   Uint64 newDigit = (*p++ - '0');
305                   if (PEGASUS_UINT64_LITERAL(0xFFFFFFFFFFFFFFFF) - x < newDigit)
306                   {
307                       return false;
308                   }
309 kumpf 1.2         x = x + newDigit;
310               }
311           
312               // If we found a non-decimal digit, report an error
313               return (!*p);
314           }
315           
316           //------------------------------------------------------------------------------
317           //
318           // hexStringToUint64
319           //
320           //      ( "0x" | "0X" ) 1*hexDigit
321           //
322           //------------------------------------------------------------------------------
323           
324           Boolean StringConversion::hexStringToUint64(
325               const char* stringValue,
326               Uint64& x)
327           {
328               x = 0;
329               const char* p = stringValue;
330 kumpf 1.2 
331               if (!p || !*p)
332               {
333                   return false;
334               }
335           
336               if ((p[0] != '0') || ((p[1] != 'x') && (p[1] != 'X')))
337               {
338                   return false;
339               }
340           
341               // Skip over the "0x"
342               p+=2;
343           
344               // At least one hexadecimal digit is required
345               if (!*p)
346               {
347                   return false;
348               }
349           
350               // Add on each digit, checking for overflow errors
351 kumpf 1.2     while (isxdigit(*p))
352               {
353                   // Make sure we won't overflow when we multiply by 16
354 kumpf 1.3         if (x & PEGASUS_UINT64_LITERAL(0xF000000000000000))
355 kumpf 1.2         {
356                       return false;
357                   }
358           
359                   x = (x << 4) + Uint64(hexCharToNumeric(*p++));
360               }
361           
362               // If we found a non-hexadecimal digit, report an error
363               return (!*p);
364           }
365           
366           //------------------------------------------------------------------------------
367           //
368           // octalStringToUint64
369           //
370           //      "0" 1*octalDigit
371           //
372           //------------------------------------------------------------------------------
373           
374           Boolean StringConversion::octalStringToUint64(
375               const char* stringValue,
376 kumpf 1.2     Uint64& x)
377           {
378               x = 0;
379               const char* p = stringValue;
380           
381               if (!p || !*p)
382               {
383                   return false;
384               }
385           
386               if (*p++ != '0')
387               {
388                   return false;
389               }
390           
391               // At least one octal digit is required
392               if (!*p)
393               {
394                   return false;
395               }
396           
397 kumpf 1.2     // Add on each digit, checking for overflow errors
398               while ((*p >= '0') && (*p <= '7'))
399               {
400                   // Make sure we won't overflow when we multiply by 8
401 kumpf 1.3         if (x & PEGASUS_UINT64_LITERAL(0xE000000000000000))
402 kumpf 1.2         {
403                       return false;
404                   }
405           
406                   x = (x << 3) + Uint64(*p++ - '0');
407               }
408           
409               // If we found a non-octal digit, report an error
410               return (!*p);
411           }
412           
413           //------------------------------------------------------------------------------
414           //
415           // binaryStringToUint64
416           //
417           //      1*binaryDigit ( "b" | "B" )
418           //
419           //------------------------------------------------------------------------------
420           
421           Boolean StringConversion::binaryStringToUint64(
422               const char* stringValue,
423 kumpf 1.2     Uint64& x)
424           {
425               x = 0;
426               const char* p = stringValue;
427           
428               if (!p || !*p)
429               {
430                   return false;
431               }
432           
433               // At least two characters are required
434               if (!*(p+1))
435               {
436                   return false;
437               }
438           
439               // Add on each digit, checking for overflow errors
440               while ((*p == '0') || (*p == '1'))
441               {
442                   // Make sure we won't overflow when we multiply by 2
443 kumpf 1.3         if (x & PEGASUS_UINT64_LITERAL(0x8000000000000000))
444 kumpf 1.2         {
445                       return false;
446                   }
447           
448                   // We can't overflow when we add the next digit
449                   x = (x << 1) + Uint64(*p++ - '0');
450               }
451           
452               if ((*p != 'b') && (*p != 'B'))
453               {
454                   return false;
455               }
456           
457               // No additional characters are permitted
458               return (!*++p);
459           }
460           
461           Boolean StringConversion::checkUintBounds(
462               Uint64 x,
463               CIMType type)
464           {
465 kumpf 1.2     switch (type)
466               {
467                   case CIMTYPE_UINT8:
468                       return !(x & PEGASUS_UINT64_LITERAL(0xFFFFFFFFFFFFFF00));
469                   case CIMTYPE_UINT16:
470                       return !(x & PEGASUS_UINT64_LITERAL(0xFFFFFFFFFFFF0000));
471                   case CIMTYPE_UINT32:
472                       return !(x & PEGASUS_UINT64_LITERAL(0xFFFFFFFF00000000));
473                   case CIMTYPE_UINT64:
474                       return true;
475 kumpf 1.3         default:
476                       break;
477 kumpf 1.2     }
478           
479               return false;
480           }
481           
482           //------------------------------------------------------------------------------
483           //
484           // stringToSint64
485           //
486           //      [ "+" | "-" ] (unsigned integer format)
487           //
488           //------------------------------------------------------------------------------
489           
490           Boolean StringConversion::stringToSint64(
491               const char* stringValue,
492               Boolean (*uint64Converter)(const char*, Uint64&),
493               Sint64& x)
494           {
495               x = 0;
496           
497               if (!stringValue)
498 kumpf 1.2     {
499                   return false;
500               }
501           
502               // Skip optional sign
503           
504               Boolean negative = *stringValue == '-';
505           
506               if (negative || *stringValue == '+')
507               {
508                   stringValue++;
509               }
510           
511               // Convert the remaining unsigned integer
512           
513               Uint64 uint64Value = 0;
514               if (!(uint64Converter(stringValue, uint64Value)))
515               {
516                   return false;
517               }
518           
519 kumpf 1.2     // Convert the unsigned integer to a signed integer
520           
521               if (negative)
522               {
523                   if (uint64Value > PEGASUS_UINT64_LITERAL(0x8000000000000000))
524                   {
525                       return false;
526                   }
527                   x = -Sint64(uint64Value);
528               }
529               else
530               {
531                   if (uint64Value > PEGASUS_UINT64_LITERAL(0x7FFFFFFFFFFFFFFF))
532                   {
533                       return false;
534                   }
535                   x = Sint64(uint64Value);
536               }
537           
538               return true;
539           }
540 kumpf 1.2 
541           Boolean StringConversion::checkSintBounds(
542               Sint64 x,
543               CIMType type)
544           {
545               switch (type)
546               {
547                   case CIMTYPE_SINT8:
548                       return (((x & PEGASUS_SINT64_LITERAL(0xFFFFFFFFFFFFFF80)) == 0) ||
549                               ((x & PEGASUS_SINT64_LITERAL(0xFFFFFFFFFFFFFF80)) ==
550                                     PEGASUS_SINT64_LITERAL(0xFFFFFFFFFFFFFF80)));
551                   case CIMTYPE_SINT16:
552                       return (((x & PEGASUS_SINT64_LITERAL(0xFFFFFFFFFFFF8000)) == 0) ||
553                               ((x & PEGASUS_SINT64_LITERAL(0xFFFFFFFFFFFF8000)) ==
554                                     PEGASUS_SINT64_LITERAL(0xFFFFFFFFFFFF8000)));
555                   case CIMTYPE_SINT32:
556                       return (((x & PEGASUS_SINT64_LITERAL(0xFFFFFFFF80000000)) == 0) ||
557                               ((x & PEGASUS_SINT64_LITERAL(0xFFFFFFFF80000000)) ==
558                                     PEGASUS_SINT64_LITERAL(0xFFFFFFFF80000000)));
559                   case CIMTYPE_SINT64:
560                       return true;
561 kumpf 1.3         default:
562                       break;
563 kumpf 1.2     }
564           
565               return false;
566           }
567           
568           //------------------------------------------------------------------------------
569           //
570           // stringToReal64
571           //
572           //      [ "+" | "-" ] *decimalDigit "." 1*decimalDigit
573           //          [ ( "e" | "E" ) [ "+" | "-" ] 1*decimalDigit ]
574           //
575           //------------------------------------------------------------------------------
576           
577           Boolean StringConversion::stringToReal64(
578               const char* stringValue,
579               Real64& x)
580           {
581               //
582               // Check the string against the DMTF-defined grammar
583               //
584 kumpf 1.2     const char* p = stringValue;
585           
586               if (!p || !*p)
587                   return false;
588           
589               // Skip optional sign:
590           
591               if (*p == '+' || *p  == '-')
592                   p++;
593           
594               // Skip optional first set of digits:
595           
596               while (isdigit(*p))
597                   p++;
598           
599               // Test required dot:
600           
601               if (*p++ != '.')
602                   return false;
603           
604               // One or more digits required:
605 kumpf 1.2 
606               if (!isdigit(*p++))
607                   return false;
608           
609               while (isdigit(*p))
610                   p++;
611           
612               // If there is an exponent now:
613           
614               if (*p)
615               {
616                   // Test exponent:
617           
618                   if (*p != 'e' && *p != 'E')
619                       return false;
620           
621                   p++;
622           
623                   // Skip optional sign:
624           
625                   if (*p == '+' || *p  == '-')
626 kumpf 1.2             p++;
627           
628                   // One or more digits required:
629           
630                   if (!isdigit(*p++))
631                       return false;
632           
633                   while (isdigit(*p))
634                       p++;
635               }
636           
637               if (*p)
638                   return false;
639           
640               //
641               // Do the conversion
642               //
643               char* end;
644           
645               errno = 0;
646               x = strtod(stringValue, &end);
647 kumpf 1.2 
648               return (!*end && (errno != ERANGE));
649           }
650           
651 mike  1.1 PEGASUS_NAMESPACE_END

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2