[Assorted-commits] SF.net SVN: assorted:[1511] cpp-commons/trunk/src/commons
Brought to you by:
yangzhang
From: <yan...@us...> - 2009-11-09 04:18:55
|
Revision: 1511 http://assorted.svn.sourceforge.net/assorted/?rev=1511&view=rev Author: yangzhang Date: 2009-11-09 04:18:43 +0000 (Mon, 09 Nov 2009) Log Message: ----------- - added resolver.h, functions.h, cxx0x.h - added socket-related data structure converters - added hexfmt - added to_string, to_wstring for windows code page/wide char conversions - added to_utf8, to_utf16 converters - fixed stream formatter for vectors - conditional (non-WIN32) compilation of unique_ptr, array, files.h - more overloads in files.h - removed executable properties on files Modified Paths: -------------- cpp-commons/trunk/src/commons/array.h cpp-commons/trunk/src/commons/files.h cpp-commons/trunk/src/commons/sockets.h cpp-commons/trunk/src/commons/streams.h cpp-commons/trunk/src/commons/strings.h cpp-commons/trunk/src/commons/unique_ptr.h Added Paths: ----------- cpp-commons/trunk/src/commons/cxx0x.h cpp-commons/trunk/src/commons/functions.h cpp-commons/trunk/src/commons/resolver.h Property Changed: ---------------- cpp-commons/trunk/src/commons/win.h Modified: cpp-commons/trunk/src/commons/array.h =================================================================== --- cpp-commons/trunk/src/commons/array.h 2009-11-08 18:27:35 UTC (rev 1510) +++ cpp-commons/trunk/src/commons/array.h 2009-11-09 04:18:43 UTC (rev 1511) @@ -40,6 +40,20 @@ size_t n_; }; + // TODO: try just specifying a single templated function + /** + * Swap two arrays. + */ + template<typename T> + void + inline swap(sized_array<T> &a, sized_array<T> &b) + { + std::swap(a.p_, b.p_); + swap(a.n_, b.n_); + } + +#ifdef COMMONS_CXX0X + // TODO: rename /** * A thin wrapper around arrays. Like a fixed-size vector. Unlike array @@ -92,19 +106,7 @@ swap(a.n_, b.n_); } - // TODO: try just specifying a single templated function /** - * Swap two arrays. - */ - template<typename T> - void - inline swap(sized_array<T> &a, sized_array<T> &b) - { - std::swap(a.p_, b.p_); - swap(a.n_, b.n_); - } - - /** * Conditionally-scoped, move-able, release-able, un-sized array. */ template<typename T> @@ -128,6 +130,8 @@ bool scoped_; }; +#endif + /** * Checks if a pointer is in an array. */ Added: cpp-commons/trunk/src/commons/cxx0x.h =================================================================== --- cpp-commons/trunk/src/commons/cxx0x.h (rev 0) +++ cpp-commons/trunk/src/commons/cxx0x.h 2009-11-09 04:18:43 UTC (rev 1511) @@ -0,0 +1,8 @@ +#ifndef COMMONS_CXX0X_H +#define COMMONS_CXX0X_H + +#ifdef __GXX_EXPERIMENTAL_CXX0X__ +#define COMMONS_CXX0X +#endif + +#endif Modified: cpp-commons/trunk/src/commons/files.h =================================================================== --- cpp-commons/trunk/src/commons/files.h 2009-11-08 18:27:35 UTC (rev 1510) +++ cpp-commons/trunk/src/commons/files.h 2009-11-09 04:18:43 UTC (rev 1511) @@ -1,6 +1,7 @@ #ifndef COMMONS_FILES_H #define COMMONS_FILES_H +#include <cstdio> #include <exception> #include <fstream> #include <iostream> @@ -9,7 +10,9 @@ #include <sys/types.h> #include <sys/stat.h> +#ifndef WIN32 #include <unistd.h> +#endif #include <fcntl.h> #include <commons/array.h> @@ -21,10 +24,10 @@ using namespace std; - class file_not_found_exception : std::exception { + class file_open_exception : std::exception { public: - file_not_found_exception(const string & name) : name(name) {} - virtual ~file_not_found_exception() throw() {} + file_open_exception(const string & name) : name(name) {} + virtual ~file_open_exception() throw() {} private: const string name; }; @@ -52,25 +55,37 @@ /** * Read in a whole file as a string. */ - UNUSED static void read_file_as_string ( const string & name, string & out ) { - ifstream in ( name.c_str() ); - if (in.fail()) throw file_not_found_exception( name ); - out = string ( istreambuf_iterator<char> ( in ), istreambuf_iterator<char>() ); + inline void read_file_as_string(const char * name, string & out ) { + ifstream in ( name ); + if (in.fail()) throw file_open_exception( name ); + out.assign(istreambuf_iterator<char>(in), istreambuf_iterator<char>()); } /** + * Read in a whole file as a string. + */ + inline string read_file_as_string ( const char * name ) + { + string s; + read_file_as_string(name, s); + return s; + } + + /** * Read in a whole file as a vector of chars. */ - UNUSED static void read_file_as_vector ( const string & name, vector<char> & out ) { - ifstream in ( name.c_str() ); - if ( in.fail() ) throw file_not_found_exception( name ); - out = vector<char> ( istreambuf_iterator<char> ( in ), istreambuf_iterator<char>() ); + inline void read_file_as_vector(const char * name, vector<char> & out) { + ifstream in ( name ); + if ( in.fail() ) throw file_open_exception( name ); + out.assign(istreambuf_iterator<char>(in), istreambuf_iterator<char>()); } +#ifndef WIN32 + /** * Read in a whole file as an array. */ - UNUSED static array<char> read_file_as_array(const char *path) + inline array<char> read_file_as_array(const char *path) { closingfd fd(checknnegerr(open(path, O_RDONLY))); array<char> buf(file_size(fd)); @@ -78,7 +93,7 @@ return buf; } - UNUSED static void write_file(int fd, const void *buf, size_t len) + inline void write_file(int fd, const void *buf, size_t len) { checkeqnneg(write(fd, buf, len), ssize_t(len)); } @@ -86,7 +101,7 @@ /** * Write a whole array to disk. */ - UNUSED static void write_file(const char *path, const void *buf, size_t len) + inline void write_file(const char *path, const void *buf, size_t len) { closingfd fd(checknnegerr(creat(path, 0644))); write_file(fd, buf, len); @@ -95,7 +110,7 @@ /** * Write a whole array to disk. */ - UNUSED static void write_file(const char *path, const array<char> &buf) + inline void write_file(const char *path, const array<char> &buf) { write_file(path, buf, buf.size()); } @@ -106,7 +121,7 @@ * TODO this probably isn't very safe, since we're demoting an off_t to a * size_t. Is there a healthier approach? */ - UNUSED static char * + inline char * load_file(const char *path, size_t & len, unsigned int ncpus) { struct stat sb; @@ -148,6 +163,8 @@ errno = 0; } +#endif + } #endif Added: cpp-commons/trunk/src/commons/functions.h =================================================================== --- cpp-commons/trunk/src/commons/functions.h (rev 0) +++ cpp-commons/trunk/src/commons/functions.h 2009-11-09 04:18:43 UTC (rev 1511) @@ -0,0 +1,23 @@ +#ifndef COMMONS_FUNCTIONS_H +#define COMMONS_FUNCTIONS_H + +#include <boost/bind.hpp> +#include <boost/function.hpp> + +namespace commons +{ + + using boost::bind; + using boost::function; + + template<typename C, typename A, typename B> + function<C(A)> compose(function<C(A)> f, function<A(B)> g) + { return bind(f, bind(g, _1)); } + + template<typename B, typename A> + function<B> operator*(function<B> f, function<A> g) + { return compose(f, g); } + +} + +#endif Added: cpp-commons/trunk/src/commons/resolver.h =================================================================== --- cpp-commons/trunk/src/commons/resolver.h (rev 0) +++ cpp-commons/trunk/src/commons/resolver.h 2009-11-09 04:18:43 UTC (rev 1511) @@ -0,0 +1,39 @@ +#ifndef RESOLVER_H +#define RESOLVER_H + +#include <commons/sockets.h> +#include <commons/strings.h> +#include <Poco/Net/DNS.h> + +/** + * Convenience functions for resolving hostnames. + */ + +namespace commons +{ + + using namespace Poco::Net; + + /** Get the hostname's IPv4 address as an int in network byte order. */ + inline uint32_t name2nl(DNS &dns, const string &name) { + return ipaddr2nl(*reinterpret_cast<const in_addr*>(dns.resolveOne(name).addr())); + } + + /** Get the hostname's IPv4 address as an int in network byte order. */ + inline uint32_t name2nl(DNS &dns, const wstring &name) { + return name2nl(dns, to_string(name)); + } + + /** Get the hostname's IPv4 address as an int in host byte order. */ + inline uint32_t name2hl(DNS &dns, const string &name) { + return ipaddr2hl(*reinterpret_cast<const in_addr*>(dns.resolveOne(name).addr())); + } + + /** Get the hostname's IPv4 address as an int in host byte order. */ + inline uint32_t name2hl(DNS &dns, const wstring &name) { + return name2hl(dns, to_string(name)); + } + +} + +#endif Modified: cpp-commons/trunk/src/commons/sockets.h =================================================================== --- cpp-commons/trunk/src/commons/sockets.h 2009-11-08 18:27:35 UTC (rev 1510) +++ cpp-commons/trunk/src/commons/sockets.h 2009-11-09 04:18:43 UTC (rev 1511) @@ -3,6 +3,7 @@ #ifdef WIN32 #include <winsock2.h> +#include <ws2tcpip.h> #else #include <arpa/inet.h> #include <netdb.h> @@ -24,7 +25,7 @@ #ifdef WIN32 typedef SOCKET socket_t; - int inet_aton(const char *cp, struct in_addr *inp) { + inline int inet_aton(const char *cp, struct in_addr *inp) { uint32_t a = inet_addr(cp); if (a == INADDR_NONE) return 0; inp->S_un.S_addr = a; @@ -148,7 +149,7 @@ return a; } - void close_socket(socket_t s) { + inline void close_socket(socket_t s) { #ifdef WIN32 closesocket(s); #else @@ -219,35 +220,55 @@ return c.release(); } +#if 0 #if defined(WIN32) && defined(UNICODE) #define getnameinfo GetNameInfoW #define getaddrinfo GetAddrInfoW #define addrinfo ADDRINFOW #define freeaddrinfo FreeAddrInfoW #endif +#endif +#if 0 /** - * T is a string or wstring. + * Resolve a sockaddr's IP address to its hostname. */ - template<typename T> - sockaddr_in - addr2name(const sockaddr_in sa) + inline string + sockaddr2hostname(const sockaddr_in &sa) { - enum { sz = 1024 }; - wchar_t buf[sz]; + char hostbuf[NI_MAXHOST]; check0x(getnameinfo(reinterpret_cast<const sockaddr*>(&sa), sizeof sa, - buf, sz, // output hostname + hostbuf, NI_MAXHOST, // output hostname nullptr, 0, // service 0)); // flags - return sa; + return string(buf); } /** + * Resolve an IP address to its hostname. + */ + inline string + ipaddr2hostname(const in_addr &ip) + { + sockaddr_in sa = { AF_INET, 0, ip }; + return sockaddr2hostname(sa); + } + + /** + * Convert an IP addr to a string. + */ + inline string + ipaddr2str(const in_addr &ip) + { + inet_ntop(); + } + + /** * Get IPv4 address for hostname. T is a string or wstring. */ template<typename T> in_addr - name2addr(const T *name) + name2ipaddr(const T *name) { addrinfo *ai, hints = {0}; in_addr addr; @@ -263,7 +284,16 @@ freeaddrinfo(ai); return addr; } +#endif + /** Get the IPv4 address as an int in network byte order. */ + inline uint32_t ipaddr2nl(const in_addr &a) + { return IFWIN32(a.S_un.S_addr, a.s_addr); } + + /** Get the IPv4 address as an int in host byte order. */ + inline uint32_t ipaddr2hl(const in_addr &a) + { return ntohl(ipaddr2nl(a)); } + } #endif Modified: cpp-commons/trunk/src/commons/streams.h =================================================================== --- cpp-commons/trunk/src/commons/streams.h 2009-11-08 18:27:35 UTC (rev 1510) +++ cpp-commons/trunk/src/commons/streams.h 2009-11-09 04:18:43 UTC (rev 1511) @@ -1,24 +1,76 @@ #ifndef COMMONS_STREAMS_H #define COMMONS_STREAMS_H +#include <iomanip> +#include <limits> #include <ostream> +#include <string> #include <vector> -namespace commons { +#include <boost/foreach.hpp> +#include <boost/io/ios_state.hpp> +#include <commons/strings.h> + +namespace commons { namespace formatters { + using namespace std; + using boost::io::ios_flags_saver; - // Pretty-prints a vector of ostreamables. - template <typename T> - ostream& operator<<(ostream& out, const vector<T> &v) { - out << "["; - if (!v.empty()) { - for (typename vector<T>::size_type i = 0; i < v.size() - 1; i++) - out << v[i] << ", "; - out << v.back(); + /** + * Pretty-prints a vector of ostreamables. + */ + template<typename T> + ostream &operator<<(ostream &o, const vector<T> &v) + { + bool first = true; + o << "["; + BOOST_FOREACH (const T &x, v) { + o << (first ? "" : ", ") << x; + first = false; + } + return o << "]"; + } + + /** + * Allow wstrings to be printed to ostreams. + */ + inline ostream &operator<<(ostream &o, const wstring &s) + { return o << to_string(s); } + + /** + * Allow strings to be printed to wostreams. + */ + inline wostream &operator<<(wostream &o, const string &s) + { return o << to_wstring(s); } + + /** + * Wrapper around integral types that enables pretty printing as hex numbers. + */ + template<typename T> + class hexfmt_t + { + public: + hexfmt_t(T x) : x_(x) {} + friend wostream &operator<<(wostream &o, hexfmt_t x) { + ios_flags_saver s(o); + return o << setfill('0') << setw(2 * sizeof(T)) << hex << x.x_; } - return out << "]"; + friend ostream &operator<<(ostream &o, hexfmt_t x) { + ios_flags_saver s(o); + return o << setfill('0') << setw(2 * sizeof(T)) << hex << x.x_; + } + private: + T x_; + }; + + /** + * Convenience constructor wrapper for hexfmt_t. + */ + template<typename T> hexfmt_t<T> hexfmt(T x) { + return hexfmt_t<T>(x); } -} +} } + #endif Modified: cpp-commons/trunk/src/commons/strings.h =================================================================== --- cpp-commons/trunk/src/commons/strings.h 2009-11-08 18:27:35 UTC (rev 1510) +++ cpp-commons/trunk/src/commons/strings.h 2009-11-09 04:18:43 UTC (rev 1511) @@ -3,9 +3,16 @@ #ifndef COMMONS_STRINGS_H #define COMMONS_STRINGS_H +#include <Poco/UnicodeConverter.h> + +#ifndef __cplusplus #include <strings.h> +#else +#include <cstring> +#endif #include <commons/check.h> +#include <commons/nullptr.h> namespace commons { @@ -42,44 +49,10 @@ struct eqstr { bool operator()(const char* s1, const char* s2) const - { - return strcmp(s1, s2) == 0; - } + { return strcmp(s1, s2) == 0; } }; /** - * Look for a substring, but without null-termination conventions. - * - * TODO: remove or fix - */ - inline char * - unsafe_strstr(char *p, const char *, const char *lim) - { - if (lim == 0) { - while (true) { - for (; !(*p == '\0' && *(p+1) == '\0'); p++) {} - return p; - } - } else { - check(p < lim); - while (true) { - for (; !(*p == '\0' && *(p+1) == '\0') && p < lim; p++) {} - if (p == lim) return NULL; - return p; - } - } - } - - /** - * Look for a substring, but without null-termination conventions. - */ - inline const char* - unsafe_strstr(const char *p, const char *q, const char *lim) - { - return unsafe_strstr(const_cast<char*>(p), q, lim); - } - - /** * "Touch" the entire memory region. Useful for ensuring that some piece of * memory is "warmed up." Visits each character. Note that this might be * optimized out if the caller doesn't meaningfully use the (mostly @@ -133,6 +106,115 @@ // return NULL; // } + /** + * Convert UTF-16 to UTF-8. + */ + inline string to_utf8(const wstring &w) { + string s; + Poco::UnicodeConverter::toUTF8(w, s); + return s; + } + + /** + * Convert UTF-8 to UTF-16. + */ + inline wstring to_utf16(const string &s) { + wstring w; + Poco::UnicodeConverter::toUTF16(s, w); + return w; + } + + /** + * Throw-away stream for easily building strings. + * + * \code + * throw msg_exception(tmpstream() << "error " << errcode() << endl); + * \endcode + */ + class tmpstream : public ostringstream { + public: + operator string() const { return str(); } + operator const char *() const { return str().c_str(); } + + template<typename T> + tmpstream &operator <<(const T &x) { + *static_cast<ostringstream*>(this) << x; + return *this; + } + }; + } +#ifdef WIN32 + +#include <windows.h> +#include <string> + +namespace commons { namespace win { + + using std::string; + using std::wstring; + + // TODO return unique_ptr + + /** + * Transcode to system default ANSI code page using WideCharToMultiByte. + */ + inline char* + to_chars(const wchar_t *w) + { + char *s; + int wlen = ::wcslen(w); + int slen = ::WideCharToMultiByte(CP_ACP, 0, w, wlen, 0, 0, nullptr, nullptr); + if (slen > 0) { + s = new char[slen + 1]; + ::WideCharToMultiByte(CP_ACP, 0, w, wlen, s, slen, nullptr, nullptr); + s[slen] = 0; + } + + return s; + } + + /** + * Transcode to system default ANSI code page using WideCharToMultiByte. + */ + inline string + to_string(const wstring &w) + { + char *p = to_chars(w.c_str()); + string s(p); + delete[] p; + return s; + } + + + /** + * Transcode from system default ANSI code page using MultiByteToWideChar. + */ + inline wchar_t * + to_wchars(const char *s) + { + int len = ::strlen(s); + wchar_t *w = new wchar_t[len + 1]; + ::MultiByteToWideChar(CP_ACP, 0, s, len, w, len + 1); + return w; + } + + + /** + * Transcode from system default ANSI code page using MultiByteToWideChar. + */ + inline wstring + to_wstring(const string &s) + { + wchar_t *p = to_wchars(s.c_str()); + wstring w(p); + delete[] p; + return w; + } + +} } + #endif + +#endif Modified: cpp-commons/trunk/src/commons/unique_ptr.h =================================================================== --- cpp-commons/trunk/src/commons/unique_ptr.h 2009-11-08 18:27:35 UTC (rev 1510) +++ cpp-commons/trunk/src/commons/unique_ptr.h 2009-11-09 04:18:43 UTC (rev 1511) @@ -35,6 +35,10 @@ #ifndef _UNIQUE_PTR_H #define _UNIQUE_PTR_H 1 +#include <commons/cxx0x.h> + +#ifdef COMMONS_CXX0X + #ifndef __GXX_EXPERIMENTAL_CXX0X__ # include <c++0x_warning.h> #endif @@ -456,4 +460,6 @@ _GLIBCXX_END_NAMESPACE +#endif // COMMONS_CXX0X + #endif /* _UNIQUE_PTR_H */ Property changes on: cpp-commons/trunk/src/commons/win.h ___________________________________________________________________ Deleted: svn:executable - * This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |