Main Page   Class Hierarchy   Compound List   File List   Compound Members  

integer_t.cpp

00001 /*
00002  *  This program is free software; you can redistribute it and/or modify
00003  *  it under the terms of the GNU General Public License as published by
00004  *  the Free Software Foundation; either version 2 of the License, or
00005  *  (at your option) any later version.
00006  *
00007  *  This program is distributed in the hope that it will be useful,
00008  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00009  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00010  *  GNU General Public License for more details.
00011  *
00012  *  You should have received a copy of the GNU General Public License
00013  *  along with this program; if not, write to the Free Software
00014  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00015  *
00016  * (c)Copyright 2006 Hewlett-Packard Development Company, LP.
00017  *
00018  */
00019 
00020 #include <ctype.h>
00021 #include "integer_t.hpp"
00022 
00023 #if defined(__hpux)
00024 
00025 // Define the strtoll and strtoull function 
00026 
00027 // The table below is used to convert from ASCII digits to a
00028 // numerical equivalent.  It maps from '0' through 'z' to integers
00029 // (100 for non-digit characters).
00030 static char cvtIn[] = {
00031     0, 1, 2, 3, 4, 5, 6, 7, 8, 9,               /* '0' - '9' */
00032     100, 100, 100, 100, 100, 100, 100,          /* punctuation */
00033     10, 11, 12, 13, 14, 15, 16, 17, 18, 19,     /* 'A' - 'Z' */
00034     20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
00035     30, 31, 32, 33, 34, 35,
00036     100, 100, 100, 100, 100, 100,               /* punctuation */
00037     10, 11, 12, 13, 14, 15, 16, 17, 18, 19,     /* 'a' - 'z' */
00038     20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
00039     30, 31, 32, 33, 34, 35};
00040 
00041 unsigned long long int strtoull(const char *P_nPtr, char **P_endPtr, int P_base)
00042 {
00043   register const char *           L_pt        = NULL;
00044   register unsigned long long int L_result    = 0LL;
00045   register unsigned               L_digit;
00046   register unsigned long long int L_shifted;
00047   int                             L_anyDigits = 0;
00048   int                             L_negative  = 0;
00049 
00050   // Skip leading blanks
00051   L_pt = P_nPtr;
00052   while (isspace((unsigned char)(*L_pt))) {
00053     L_pt += 1;
00054   }
00055 
00056   // Check for a sign
00057   if (*L_pt == '-') {
00058     L_pt += 1;
00059     L_negative = 1;
00060   } else {
00061     if (*L_pt == '+') {
00062       L_pt += 1;
00063     }
00064   }
00065 
00066   // If no base was provided, pick one from the leading characters
00067   // of the string.
00068   if (P_base == 0) {
00069     if (*L_pt == '0') {
00070       L_pt += 1;
00071       if (*L_pt == 'x' || *L_pt == 'X') {
00072         L_pt += 1;
00073         P_base = 16;
00074       } else {
00075         // Must set L_anyDigits here, otherwise "0" produces a
00076         // "no digits" error.
00077         L_anyDigits = 1;
00078         P_base = 8;
00079       }
00080     } else {
00081       P_base = 10;
00082     }
00083   } else if (P_base == 16) {
00084     // Skip a leading "0x" from hex numbers.
00085     if ((L_pt[0] == '0') && (L_pt[1] == 'x' || *L_pt == 'X')) {
00086       L_pt += 2;
00087     }
00088   }
00089 
00090   // Sorry this code is so messy, but speed seems important.  Do
00091   // different things for base 8, 10, 16, and other.
00092   if (P_base == 8) {
00093     for ( ; ; L_pt += 1) {
00094       L_digit = *L_pt - '0';
00095       if (L_digit > 7) {
00096         break;
00097       }
00098       L_shifted = L_result << 3;
00099       if ((L_shifted >> 3) != L_result) {
00100         goto overflow;
00101       }
00102       L_result = L_shifted + L_digit;
00103       if ( L_result < L_shifted ) {
00104         goto overflow;
00105       }
00106       L_anyDigits = 1;
00107     }
00108   } else if (P_base == 10) {
00109     for ( ; ; L_pt += 1) {
00110       L_digit = *L_pt - '0';
00111       if (L_digit > 9) {
00112         break;
00113       }
00114       L_shifted = 10 * L_result;
00115       if ((L_shifted / 10) != L_result) {
00116         goto overflow;
00117       }
00118       L_result = L_shifted + L_digit;
00119       if ( L_result < L_shifted ) {
00120         goto overflow;
00121       }
00122       L_anyDigits = 1;
00123     }
00124   } else if (P_base == 16) {
00125     for ( ; ; L_pt += 1) {
00126       L_digit = *L_pt - '0';
00127       if (L_digit > ('z' - '0')) {
00128         break;
00129       }
00130       L_digit = cvtIn[L_digit];
00131       if (L_digit > 15) {
00132         break;
00133       }
00134       L_shifted = L_result << 4;
00135       if ((L_shifted >> 4) != L_result) {
00136         goto overflow;
00137       }
00138       L_result = L_shifted + L_digit;
00139       if ( L_result < L_shifted ) {
00140         goto overflow;
00141       }
00142       L_anyDigits = 1;
00143     }
00144   } else if ( P_base >= 2 && P_base <= 36 ) {
00145     for ( ; ; L_pt += 1) {
00146       L_digit = *L_pt - '0';
00147       if (L_digit > ('z' - '0')) {
00148         break;
00149       }
00150       L_digit = cvtIn[L_digit];
00151       if (L_digit >= (unsigned) P_base) {
00152         break;
00153       }
00154       L_shifted = L_result * P_base;
00155       if ((L_shifted/P_base) != L_result) {
00156         goto overflow;
00157       }
00158       L_result = L_shifted + L_digit;
00159       if ( L_result < L_shifted ) {
00160         goto overflow;
00161       }
00162       L_anyDigits = 1;
00163     }
00164   }
00165 
00166   // Negate if we found a '-' earlier.
00167   if (L_negative) {
00168     L_result = (unsigned long long int)(-((long long int)L_result));
00169   }
00170 
00171   // See if there were any digits at all.
00172   if (!L_anyDigits) {
00173     L_pt = P_nPtr;
00174   }
00175 
00176   if (P_endPtr != 0) {
00177     *P_endPtr = (char *) L_pt;
00178   }
00179 
00180   return L_result;
00181 
00182   // On overflow generate the right output
00183 overflow:
00184   errno = ERANGE;
00185   if (P_endPtr != 0) {
00186     for ( ; ; L_pt += 1) {
00187       L_digit = *L_pt - '0';
00188       if (L_digit > ('z' - '0')) {
00189         break;
00190       }
00191       L_digit = cvtIn[L_digit];
00192       if (L_digit >= (unsigned) P_base) {
00193         break;
00194       }
00195     }
00196     *P_endPtr = (char *) L_pt;
00197   }
00198   return ((unsigned long long)(-1LL));
00199 }
00200 
00201 // to add << for unsigned long long
00202 iostream_output& operator<<(iostream_output&    P_ostream,
00203                             unsigned long long& P_value) {
00204 
00205   char L_buffer[25];
00206 
00207   sprintf(L_buffer,"%llu", P_value);
00208   P_ostream << L_buffer;
00209 
00210   return (P_ostream);
00211 }
00212 
00213 long long int strtoll(const char *P_nPtr, char **P_endPtr, int P_base)
00214 {
00215   register const char *  L_pt              = NULL;
00216   long long int          L_result          = 0LL;
00217   unsigned long long int L_unsigned_result = 0LL;
00218 
00219   // Skip leading blanks
00220   L_pt = P_nPtr;
00221   while (isspace((unsigned char)(*L_pt))) {
00222     L_pt += 1;
00223   }
00224 
00225   // Check for a sign.
00226   errno = 0;
00227   if ((*L_pt) == '-') {
00228     L_pt += 1;
00229     L_unsigned_result = strtoull(L_pt, P_endPtr, P_base);
00230     if (errno != ERANGE) {
00231       if (L_unsigned_result > LONG_LONG_MAX+1) {
00232         errno = ERANGE;
00233         return ((long long int)(-1LL));
00234       } else if (L_unsigned_result > LONG_LONG_MAX) {
00235         return ~((long long int)LONG_LONG_MAX);
00236       } else {
00237         L_result = -((long long int)L_unsigned_result);
00238       }
00239     }
00240   } else {
00241     if (*L_pt == '+') {
00242       L_pt += 1;
00243     }
00244     L_unsigned_result = strtoull(L_pt, P_endPtr, P_base);
00245     if (errno != ERANGE) {
00246       if (L_unsigned_result > LONG_LONG_MAX) {
00247         errno = ERANGE;
00248         return ((long long int)(-1LL));
00249       } else {
00250         L_result = L_unsigned_result;
00251       }
00252     }
00253   }
00254 
00255   if ((L_result == 0) && (P_endPtr != 0) && ((*P_endPtr) == L_pt)) {
00256     (*P_endPtr) = (char *) P_nPtr;
00257   }
00258   return L_result;
00259 }
00260 
00261 // to add << for long long
00262 iostream_output& operator<<(iostream_output&   P_ostream,
00263                             long long&         P_value) {
00264 
00265   char L_buffer[25];
00266 
00267   sprintf(L_buffer,"%lld", P_value);
00268   P_ostream << L_buffer;
00269 
00270   return (P_ostream);
00271 }
00272 
00273 #endif
00274 
00275 // Define new ntohll and htonll function
00276 T_UnsignedInteger64 ntohll(T_UnsignedInteger64 P_val) {
00277 
00278 #if BYTE_ORDER == BIG_ENDIAN
00279   return P_val;
00280 #else
00281   return (((T_UnsignedInteger64)ntohl(P_val)) << 32) + ntohl(P_val >> 32);
00282 #endif
00283 }
00284 
00285 T_UnsignedInteger64 htonll(T_UnsignedInteger64 P_val) {
00286 
00287 #if BYTE_ORDER == BIG_ENDIAN
00288   return P_val;
00289 #else
00290   return (((T_UnsignedInteger64)htonl(P_val)) << 32) + htonl(P_val >> 32);
00291 #endif
00292 }
00293 
00294 // End of file

Generated on Wed Mar 7 14:44:59 2007 for Seagull by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002