From: Gonzalo A. <ga...@us...> - 2006-09-08 14:24:20
|
Update of /cvsroot/mod-c/ehtml/src In directory sc8-pr-cvs7.sourceforge.net:/tmp/cvs-serv12608/src Modified Files: Common.cpp Log Message: * Wrote hex_aton. * Recoded GetByteFromHex into 2 calls of hex_aton. * Wrote xatoul. * Wrote is_directory. * Wrote xmemdup. Index: Common.cpp =================================================================== RCS file: /cvsroot/mod-c/ehtml/src/Common.cpp,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** Common.cpp 13 Mar 2006 15:52:04 -0000 1.6 --- Common.cpp 8 Sep 2006 14:24:05 -0000 1.7 *************** *** 19,25 **** ***************************************************************************/ ! #include <Common.h> #include <stdlib.h> #include <sstream> using namespace std; --- 19,26 ---- ***************************************************************************/ ! #include "Common.h" #include <stdlib.h> #include <sstream> + #include <ctype.h> using namespace std; *************** *** 192,214 **** } ! static inline unsigned char GetByteFromHex( char a, char b ) { ! register unsigned char retVal = 0; if ( a >= '0' && a <= '9' ) ! retVal |= (a - '0') << 4; else if ( a >= 'a' && a <= 'f' ) ! retVal |= (a - 'a' + 10) << 4; else if ( a >= 'A' && a <= 'F' ) ! retVal |= (a - 'A' + 10) << 4; ! if ( b >= '0' && b <= '9' ) ! retVal |= b - '0'; ! else if ( b >= 'a' && b <= 'f' ) ! retVal |= b - 'a' + 10; ! else if ( b >= 'A' && b <= 'F' ) ! retVal |= b - 'A' + 10; ! return retVal; } --- 193,213 ---- } ! static inline unsigned char hex_aton(char a) { ! unsigned char c = 0xff; if ( a >= '0' && a <= '9' ) ! c = (a - '0'); else if ( a >= 'a' && a <= 'f' ) ! c = (a - 'a' + 10); else if ( a >= 'A' && a <= 'F' ) ! c = (a - 'A' + 10); ! return c; ! } ! static inline unsigned char GetByteFromHex( char a, char b ) ! { ! return (hex_aton(a) << 4) | hex_aton(b); } *************** *** 254,255 **** --- 253,465 ---- return -1; } + + const char* ehtml_strerror(int errno) { + if (errno >= 0) + return strerror(errno); + switch (errno) { + case EHTML_ERR: return "Unspecified error"; + case EHTML_TIMEOUT: return "Timeout"; + case EHTML_INVALID_CALL: return "Invalid call"; + } + return "Unknown error"; + } + + static const char h2c[17] = "0123456789ABCDEF"; + + static inline bool must_escape(char c) { + return !isalnum(c) && c != '-' && c != '_'; + } + + string urlencode(const string& s) { + //@todo better way to fix this const issue? + return urlencode(MemBuf::Dup((void*)s.c_str(), s.length())); + } + + string urlencode(const MemBuf& mb) { + size_t n_escape = 0; + const char* s = mb.Char(); + for (int i = mb.Size(); i--;) + if (must_escape(s[i])) + ++n_escape; + + string dev; + dev.reserve(mb.Size() + 2 * n_escape + 1); + + size_t i_escape = 0; + size_t size = mb.Size(); + for (int i = 0; i < size; ++i) { + if (!must_escape(s[i])) { + dev += s[i]; + continue; + } + char escape[4] = { + '%', + h2c[(dev[i] >> 4) & 0x0f], + h2c[dev[i] & 0x0f], + '\0' + }; + dev += escape; + } + + return dev; + } + + MemBuf urldecode(const string& s) throw (const char*) { //@todo test + MemBuf dev(strdup(s.c_str()), s.length()+1); + char* obuf = dev.Char(); + int ii = 0; + int i = 0; + for (; ii < dev.Size(); ++i, ++ii) { + if (obuf[ii] != '%') + continue; + if (ii >= dev.Size() - 2) + throw "Invalid string to decode"; + dev[i] = GetByteFromHex(obuf[++ii], obuf[++ii]); + } + dev.resize(i); + return dev; + } + + string hexencode(const MemBuf& mb) { + string dev; + dev.reserve(mb.Size()*2+1); + + for (int i = 0; i < mb.Size(); ++i) { + char c = mb.Char()[i]; + dev += h2c[(c >> 4) & 0x0f]; + dev += h2c[c & 0x0f]; + } + + return dev; + } + + MemBuf hexdecode(const string& s) throw (const char*) { + MemBuf dev; + dev.resize(s.length()/2); + char* obuf = dev.Char(); + if (s.length() & 1) + throw "Invalid format"; + for (int i = 0; i < s.length(); ++i) + dev[i>>1] = GetByteFromHex(s[i], s[++i]); + return dev; + } + + char _b64[65] = + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz" + "0123456879" + "+/"; + + std::string base64encode(const MemBuf& mb) { //@todo test + string dev; + dev.reserve(mb.Size() * 4 / 3 + 2); + int i = 0; + while (mb.Size() - i >= 3) { + const char* in = mb.Char()+i; + char out[5] = { + // XX00 0000 | XX00 1111 | XX11 1122 | XX22 2222 + _b64[(in[0] >> 2) & 0x03f], + _b64[((in[0] << 4) & 0x030) | ((in[1] >> 4) & 0x00f)], + _b64[((in[1] << 2) & 0x03C) | ((in[2] >> 6) & 0x003)], + _b64[(in[2] & 0x03f)], + '\0' + }; + dev += out; + i += 3; + } + switch (mb.Size() - i) { + case 0: + break; + case 1: { // 1 byte missing + const char* in = mb.Char()+i; + char out[5] = { + // XX00 0000 | XX00 1111 | XX11 1122 | XX22 2222 + _b64[(in[0] >> 2) & 0x03f], + _b64[((in[0] << 4) & 0x030)], + '=', '=', '\0' + }; + dev += out; + } + break; + case 2: { // 2 bytes missing + const char* in = mb.Char()+i; + char out[5] = { + // XX00 0000 | XX00 1111 | XX11 1122 | XX22 2222 + _b64[(in[0] >> 2) & 0x03f], + _b64[((in[0] << 4) & 0x030) | ((in[1] >> 4) & 0x00f)], + _b64[((in[1] << 2) & 0x03C)], + '=', + '\0' + }; + dev += out; + } + break; + } + return dev; + } + + unsigned char _b64_aton(char c) { + if (c >= 'A' && c <= 'Z') return int(c-'A'); + if (c >= 'a' && c <= 'z') return int(c-'a') + ('Z'-'A'); + if (c >= '0' && c <= '9') return int(c-'0') + ('z'-'a') + ('Z'-'A'); + if (c == '+') return 62; + if (c == '/') return 63; + if (c == '=') return 0; + return 255; + } + + MemBuf base64decode(const std::string& s) throw (const char*) { //@todo test + // 0000 0011 | 1111 2222 | 2233 3333 + MemBuf dev; + dev.resize(s.length() * 3 / 4); + if (s.length() & 0x03) + throw "Invalid base64 string."; + int ii = 0; + int i = 0; + for (; i < s.length();) { + const char* in = s.c_str()+i; + unsigned char iv[4] = { + _b64_aton(in[0]), + _b64_aton(in[1]), + _b64_aton(in[2]), + _b64_aton(in[3]) + }; + dev.Char()[ii++] = (iv[0] << 2) | (iv[1] >> 4); + dev.Char()[ii++] = (iv[1] << 4) | (iv[2] >> 2); + dev.Char()[ii++] = (iv[2] << 6) | (iv[3]); + i += 4; + } + return dev; + } + + unsigned long xatoul(const char* s) throw (const char*) { //@todo test + char* end; + if (!s || !s[0]) + throw "Invalid string for unsigned long"; + unsigned long dev = strtol(s, &end, 10); + if (*end) + throw "Invalid string for unsigned long"; + return dev; + } + + double xatod(const char* s) throw (const char*) { //@todo test + char* end; + if (!s || !s[0]) + throw "Invalid string for unsigned long"; + double dev = strtod(s, &end); + if (*end) + throw "Invalid string for unsigned long"; + return dev; + } + + bool is_directory(const char* name) { + struct stat st; + return stat(name, &st) == 0 && S_ISDIR(st.st_mode); + } + + void* xmemdup(const void* p, size_t n) { + void* dev = malloc(n); + assert(dev != NULL); + return memcpy(dev, p, n); + } + |