// --------------------------------------------------------------------------- // - ccnv.cxx - // - standard system library - c conversion function implementation - // --------------------------------------------------------------------------- // - This program is free software; you can redistribute it and/or modify - // - it provided that this copyright notice is kept intact. - // - - // - This program is distributed in the hope that it will be useful, but - // - without any warranty; without even the implied warranty of - // - merchantability or fitness for a particular purpose. In no event shall - // - the copyright holder be liable for any direct, indirect, incidental or - // - special damages arising in any way out of the use of this software. - // --------------------------------------------------------------------------- // - copyright (c) 1999-2007 amaury darsch - // --------------------------------------------------------------------------- #include "cstr.hpp" #include "ccnv.hpp" #include "ccnv.hxx" namespace afnix { // this function convert a character according to a base static inline long ctol (const char c, const int base, bool& status) { status = true; switch (base) { case 2: if (c == '0') return 0; if (c == '1') return 1; break; case 10: if ((c >= '0') && (c <= '9')) return (long) (c - '0'); break; case 16: if ((c >= '0') && (c <= '9')) return (long) (c - '0'); if ((c >= 'a') && (c <= 'f')) return ((long) (c - 'a')) + 10; if ((c >= 'A') && (c <= 'F')) return ((long) (c - 'A')) + 10; break; } status = false; return 0; } t_long c_atoll (const char* s, bool& status) { // initialize result int base = 10; long long basval = 1; long long result = 0; status = true; // check for size first long len = 0; if ((s == 0) || ((len = c_strlen (s)) == 0)) return 0; // process one character if (len == 1) return ctol (s[0],10,status); // here we have at least two characters - it can be the sign, the format // or a normal number bool negative = false; const char* ptr = s; // check for the sign if (ptr[0] == '-') { ptr++; len--; negative = true; goto format; } if (ptr[0] == '+') { ptr++; len--; goto format; } // check for the format format: if (ptr[0] != '0') goto number; ptr++; len--; if (len == 0) return 0; if ((ptr[0] == 'x') || (ptr[0] == 'X')) { ptr++; len--; if (len == 0) { status = false; return 0; } base = 16; goto number; } if ((ptr[0] == 'b') || (ptr[0] == 'B')) { ptr++; len--; if (len == 0) { status = false; return 0; } base = 2; goto number; } // compute the number value number: if (len == 0) return 0; for (long i = len-1; i >= 0; i--) { result += basval * ctol (ptr[i], base, status); basval *= base; if (status == false) return 0; }; return (negative) ? -result : result; } // this procedure convert a long value to a character static inline char ltoc (const long value, bool& status) { if ((value >= 0) && (value <= 9)) return (char) ('0' + value); status = false; return nilc; } // convert a long long integer to a string char* c_lltoa (const t_long value) { char buffer[512]; bool status = true; long index = 0; bool sign = (value < 0) ? true : false; t_octa baseval = 10; t_octa dataval = sign ? (t_octa) -value : (t_octa) value; // let start in good shape buffer[0] = nilc; index = 0; // loop until we reach 0 while (dataval != 0) { long val = (long) (dataval % baseval); buffer[index++] = ltoc (val, status); if (status == false) return nilp; // readjust index dataval /= baseval; } if (status == false) return nilp; // readjust for sign and null value if (sign == true) buffer[index++] = '-'; if (buffer[0] == nilc) buffer[index++] = '0'; // prepare the result string char* result = sign ? new char[index+2] : new char[index+1]; for (long i = 0; i < index; i++) result[i] = buffer[index-i-1]; result[index] = nilc; return result; } // convert a long integer to a string char* c_ltoa (const long value) { return c_lltoa (value); } // this procedure convert a long value to a hexa character static inline char ltoh (const long value, bool& status) { if ((value >= 0) && (value <= 9)) return (char) ('0' + value); if (value == 10) return 'A'; if (value == 11) return 'B'; if (value == 12) return 'C'; if (value == 13) return 'D'; if (value == 14) return 'E'; if (value == 15) return 'F'; status = false; return nilc; } // convert a long long integer to an hexa string char* c_lltoh (const t_long value, const bool pflag) { char buffer[512]; bool status = true; long index = 0; t_octa baseval = 16; t_octa dataval = (t_octa) value; // let start in good shape buffer[0] = nilc; index = 0; // loop until we reach 0 while (dataval != 0) { long val = dataval % baseval; buffer[index++] = ltoh (val, status); if (status == false) return nilp; // readjust index dataval /= baseval; } if (status == false) return nilp; // readjust extension if (buffer[0] == nilc) buffer[index++] = '0'; if (pflag == true) { buffer[index++] = 'x'; buffer[index++] = '0'; } // prepare the result string char* result = new char[index+1]; for (long i = 0; i < index; i++) result[i] = buffer[index-i-1]; result[index] = nilc; return result; } // convert a long integer to a hexadecimal string char* c_ltoh (const long value, const bool pflag) { return c_lltoh (value, pflag); } // convert a double to a c-string representation char* c_dtoa (const double value) { char buffer[512]; sprintf (buffer,"%f",value); return c_strdup (buffer); } // convert a double to a c-string with a precision char* c_dtoap (const double value, const long precision) { char format[512]; char buffer[512]; sprintf (format,"%%.%ldf",precision); if (precision == 0) sprintf (buffer,"%f",value); else sprintf (buffer,format,value); return c_strdup (buffer); } // convert a char string to a double float double c_atod (const char* buffer, bool& status) { char* check; errno = 0; if (c_strlen (buffer) == 0) return 0.0; double result = strtod (buffer,&check); if ((*check != nilc) || (errno != 0)) { status = false; return 0.0; } status = true; return result; } // return true if the platform is in big endian sex bool c_isbe (void) { union { char bval[2]; unsigned short ival; } data; data.ival = 0x1234; if ((data.bval[0] == 0x12) && (data.bval[1] == 0x34)) return true; return false; } // convert a word to an array on bytes void c_whton (const t_word value, t_byte* array) { union { t_word wval; t_byte bval[2]; } data; data.wval = value; if (c_isbe () == true) { array[1] = data.bval[1]; array[0] = data.bval[0]; } else { array[1] = data.bval[0]; array[0] = data.bval[1]; } } // convert an array of bytes to a word t_word c_wntoh (const t_byte* array) { union { t_word wval; t_byte bval[2]; } data; if (c_isbe () == true) { data.bval[1] = array[1]; data.bval[0] = array[0]; } else { data.bval[1] = array[0]; data.bval[0] = array[1]; } return data.wval; } // swap a word between network order and host order t_word c_wswap (const t_word value) { // do nothing in big endian mode if (c_isbe () == true) return value; // swap in little endian mode union { t_word wval; t_byte bval[2]; } data; data.wval = value; t_byte tmp = data.bval[0]; data.bval[0] = data.bval[1]; data.bval[1] = tmp; return data.wval; } // convert a quad to an array on bytes void c_qhton (const t_quad value, t_byte* array) { union { t_quad qval; t_byte bval[4]; } data; data.qval = value; if (c_isbe () == true) { array[3] = data.bval[3]; array[2] = data.bval[2]; array[1] = data.bval[1]; array[0] = data.bval[0]; } else { array[3] = data.bval[0]; array[2] = data.bval[1]; array[1] = data.bval[2]; array[0] = data.bval[3]; } } // convert an array of bytes to a quad t_quad c_qntoh (const t_byte* array) { union { t_quad qval; t_byte bval[4]; } data; if (c_isbe () == true) { data.bval[3] = array[3]; data.bval[2] = array[2]; data.bval[1] = array[1]; data.bval[0] = array[0]; } else { data.bval[3] = array[0]; data.bval[2] = array[1]; data.bval[1] = array[2]; data.bval[0] = array[3]; } return data.qval; } // swap a quad between network order and host order t_quad c_qswap (const t_quad value) { // do nothing in big endian mode if (c_isbe () == true) return value; // swap in little endian mode union { t_quad qval; t_byte bval[4]; } data; data.qval = value; t_byte tmp = data.bval[3]; data.bval[3] = data.bval[0]; data.bval[0] = tmp; tmp = data.bval[2]; data.bval[2] = data.bval[1]; data.bval[1] = tmp; return data.qval; } // convert an octa to an array on bytes void c_ohton (const t_octa value, t_byte* array) { union { t_octa oval; t_byte bval[8]; } data; data.oval = value; if (c_isbe () == true) { array[7] = data.bval[7]; array[6] = data.bval[6]; array[5] = data.bval[5]; array[4] = data.bval[4]; array[3] = data.bval[3]; array[2] = data.bval[2]; array[1] = data.bval[1]; array[0] = data.bval[0]; } else { array[7] = data.bval[0]; array[6] = data.bval[1]; array[5] = data.bval[2]; array[4] = data.bval[3]; array[3] = data.bval[4]; array[2] = data.bval[5]; array[1] = data.bval[6]; array[0] = data.bval[7]; } } // convert an array of bytes to an octa t_octa c_ontoh (const t_byte* array) { union { t_octa oval; t_byte bval[8]; } data; if (c_isbe () == true) { data.bval[7] = array[7]; data.bval[6] = array[6]; data.bval[5] = array[5]; data.bval[4] = array[4]; data.bval[3] = array[3]; data.bval[2] = array[2]; data.bval[1] = array[1]; data.bval[0] = array[0]; } else { data.bval[7] = array[0]; data.bval[6] = array[1]; data.bval[5] = array[2]; data.bval[4] = array[3]; data.bval[3] = array[4]; data.bval[2] = array[5]; data.bval[1] = array[6]; data.bval[0] = array[7]; } return data.oval; } // swap an octa between network order and host order t_octa c_oswap (const t_octa value) { // do noting in big endian mode if (c_isbe () == true) return value; // swap in little endian mode union { t_octa oval; t_byte bval[8]; } data; data.oval = value; t_byte tmp = data.bval[7]; data.bval[7] = data.bval[0]; data.bval[0] = tmp; tmp = data.bval[6]; data.bval[6] = data.bval[1]; data.bval[1] = tmp; tmp = data.bval[5]; data.bval[5] = data.bval[2]; data.bval[2] = tmp; tmp = data.bval[4]; data.bval[4] = data.bval[3]; data.bval[3] = tmp; return data.oval; } }