pstrconv.cxx (3557B)
1 /* 2 * 3 * C++ Portable Types Library (PTypes) 4 * Version 2.1.1 Released 27-Jun-2007 5 * 6 * Copyright (C) 2001-2007 Hovik Melikyan 7 * 8 * http://www.melikyan.com/ptypes/ 9 * 10 */ 11 12 #include <string.h> 13 14 #include "ptypes.h" 15 16 17 namespace ptypes { 18 19 20 static const char* _itobase(large value, char* buf, int base, int& len, bool _signed) 21 { 22 // internal conversion routine: converts the value to a string 23 // at the end of the buffer and returns a pointer to the first 24 // character. this is to get rid of copying the string to the 25 // beginning of the buffer, since finally the string is supposed 26 // to be copied to a dynamic string in itostring(). the buffer 27 // must be at least 65 bytes long. 28 29 static char digits[65] = 30 "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; 31 32 char* pdigits; 33 if (base > 36) 34 pdigits = digits; // start from '.' 35 else 36 pdigits = digits + 2; // start from '0' 37 38 int i = 64; 39 buf[i] = 0; 40 41 bool neg = false; 42 ularge v = value; 43 if (_signed && base == 10 && value < 0) 44 { 45 v = -value; 46 // since we can't handle the lowest signed 64-bit value, we just 47 // return a built-in string. 48 if (large(v) < 0) // the LLONG_MIN negated results in the same value 49 { 50 len = 20; 51 return "-9223372036854775808"; 52 } 53 neg = true; 54 } 55 56 do 57 { 58 buf[--i] = pdigits[uint(v % base)]; 59 v /= base; 60 } while (v > 0); 61 62 if (neg) 63 buf[--i] = '-'; 64 65 len = 64 - i; 66 return buf + i; 67 } 68 69 70 static void _itobase2(string& result, large value, int base, int width, char padchar, bool _signed) 71 { 72 if (base < 2 || base > 64) 73 { 74 clear(result); 75 return; 76 } 77 78 char buf[65]; // the longest possible string is when base=2 79 int reslen; 80 const char* p = _itobase(value, buf, base, reslen, _signed); 81 82 if (width > reslen) 83 { 84 if (padchar == 0) 85 { 86 // default pad char 87 if (base == 10) 88 padchar = ' '; 89 else if (base > 36) 90 padchar = '.'; 91 else 92 padchar = '0'; 93 } 94 95 setlength(result, width); 96 bool neg = *p == '-'; 97 width -= reslen; 98 memset(pchar(pconst(result)) + neg, padchar, width); 99 memcpy(pchar(pconst(result)) + width + neg, p + neg, reslen - neg); 100 if (neg) 101 *pchar(pconst(result)) = '-'; 102 } 103 else 104 assign(result, p, reslen); 105 } 106 107 108 string ptdecl itostring(large value, int base, int width, char padchar) 109 { 110 string result; 111 _itobase2(result, value, base, width, padchar, true); 112 return result; 113 } 114 115 116 string ptdecl itostring(ularge value, int base, int width, char padchar) 117 { 118 string result; 119 _itobase2(result, value, base, width, padchar, false); 120 return result; 121 } 122 123 124 string ptdecl itostring(int value, int base, int width, char padchar) 125 { 126 string result; 127 _itobase2(result, large(value), base, width, padchar, true); 128 return result; 129 } 130 131 132 string ptdecl itostring(uint value, int base, int width, char padchar) 133 { 134 string result; 135 _itobase2(result, ularge(value), base, width, padchar, false); 136 return result; 137 } 138 139 140 string ptdecl itostring(large v) { return itostring(v, 10, 0, ' '); } 141 string ptdecl itostring(ularge v) { return itostring(v, 10, 0, ' '); } 142 string ptdecl itostring(int v) { return itostring(large(v), 10, 0, ' '); } 143 string ptdecl itostring(uint v) { return itostring(ularge(v), 10, 0, ' '); } 144 145 146 } 147