00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #ifndef PQXX_H_STRINGCONV
00019 #define PQXX_H_STRINGCONV
00020
00021 #include "pqxx/compiler-public.hxx"
00022
00023 #include <sstream>
00024 #include <stdexcept>
00025
00026
00027 namespace pqxx
00028 {
00029
00041
00043
00046 template<typename T> struct string_traits {};
00047
00048 namespace internal
00049 {
00051 void PQXX_LIBEXPORT throw_null_conversion(const PGSTD::string &type);
00052 }
00053
00054 #define PQXX_DECLARE_STRING_TRAITS_SPECIALIZATION(T) \
00055 template<> struct PQXX_LIBEXPORT string_traits<T> \
00056 { \
00057 typedef T subject_type; \
00058 static const char *name() { return #T; } \
00059 static bool has_null() { return false; } \
00060 static bool is_null(T) { return false; } \
00061 static T null() \
00062 { internal::throw_null_conversion(name()); return subject_type(); } \
00063 static void from_string(const char Str[], T &Obj); \
00064 static PGSTD::string to_string(T Obj); \
00065 };
00066
00067 PQXX_DECLARE_STRING_TRAITS_SPECIALIZATION(bool)
00068
00069 PQXX_DECLARE_STRING_TRAITS_SPECIALIZATION(short)
00070 PQXX_DECLARE_STRING_TRAITS_SPECIALIZATION(unsigned short)
00071 PQXX_DECLARE_STRING_TRAITS_SPECIALIZATION(int)
00072 PQXX_DECLARE_STRING_TRAITS_SPECIALIZATION(unsigned int)
00073 PQXX_DECLARE_STRING_TRAITS_SPECIALIZATION(long)
00074 PQXX_DECLARE_STRING_TRAITS_SPECIALIZATION(unsigned long)
00075 #ifdef PQXX_HAVE_LONG_LONG
00076 PQXX_DECLARE_STRING_TRAITS_SPECIALIZATION(long long)
00077 PQXX_DECLARE_STRING_TRAITS_SPECIALIZATION(unsigned long long)
00078 #endif
00079
00080 PQXX_DECLARE_STRING_TRAITS_SPECIALIZATION(float)
00081 PQXX_DECLARE_STRING_TRAITS_SPECIALIZATION(double)
00082 #ifdef PQXX_HAVE_LONG_DOUBLE
00083 PQXX_DECLARE_STRING_TRAITS_SPECIALIZATION(long double)
00084 #endif
00085
00086 #undef PQXX_DECLARE_STRING_TRAITS_SPECIALIZATION
00087
00089 template<> struct PQXX_LIBEXPORT string_traits<const char *>
00090 {
00091 static const char *name() { return "const char *"; }
00092 static bool has_null() { return true; }
00093 static bool is_null(const char *t) { return !t; }
00094 static const char *null() { return NULL; }
00095 static void from_string(const char Str[], const char *&Obj) { Obj = Str; }
00096 static PGSTD::string to_string(const char *Obj) { return Obj; }
00097 };
00098
00100 template<> struct PQXX_LIBEXPORT string_traits<char *>
00101 {
00102 static const char *name() { return "char *"; }
00103 static bool has_null() { return true; }
00104 static bool is_null(const char *t) { return !t; }
00105 static const char *null() { return NULL; }
00106
00107
00108
00109
00110 static PGSTD::string to_string(char *Obj) { return Obj; }
00111 };
00112
00114 template<size_t N> struct PQXX_LIBEXPORT string_traits<char[N]>
00115 {
00116 static const char *name() { return "char[]"; }
00117 static bool has_null() { return true; }
00118 static bool is_null(const char t[]) { return !t; }
00119 static const char *null() { return NULL; }
00120 static void from_string(const char Str[], const char *&Obj) { Obj = Str; }
00121 static PGSTD::string to_string(const char Obj[]) { return Obj; }
00122 };
00123
00124 template<> struct PQXX_LIBEXPORT string_traits<PGSTD::string>
00125 {
00126 static const char *name() { return "string"; }
00127 static bool has_null() { return false; }
00128 static bool is_null(const PGSTD::string &) { return false; }
00129 static PGSTD::string null()
00130 { internal::throw_null_conversion(name()); return PGSTD::string(); }
00131 static void from_string(const char Str[], PGSTD::string &Obj) { Obj=Str; }
00132 static PGSTD::string to_string(const PGSTD::string &Obj) { return Obj; }
00133 };
00134
00135 template<> struct PQXX_LIBEXPORT string_traits<const PGSTD::string>
00136 {
00137 static const char *name() { return "const string"; }
00138 static bool has_null() { return false; }
00139 static bool is_null(const PGSTD::string &) { return false; }
00140 static const PGSTD::string null()
00141 { internal::throw_null_conversion(name()); return PGSTD::string(); }
00142 static const PGSTD::string to_string(const PGSTD::string &Obj) { return Obj; }
00143 };
00144
00145 template<> struct PQXX_LIBEXPORT string_traits<PGSTD::stringstream>
00146 {
00147 static const char *name() { return "stringstream"; }
00148 static bool has_null() { return false; }
00149 static bool is_null(const PGSTD::stringstream &) { return false; }
00150 static PGSTD::stringstream null()
00151 {
00152 internal::throw_null_conversion(name());
00153
00154 throw 0;
00155 }
00156 static void from_string(const char Str[], PGSTD::stringstream &Obj)
00157 { Obj.clear(); Obj << Str; }
00158 static PGSTD::string to_string(const PGSTD::stringstream &Obj)
00159 { return Obj.str(); }
00160 };
00161
00162
00163
00164
00166
00178 template<typename T>
00179 inline void from_string(const char Str[], T &Obj)
00180 {
00181 if (!Str)
00182 throw PGSTD::runtime_error("Attempt to read NULL string");
00183 string_traits<T>::from_string(Str, Obj);
00184 }
00185
00186
00188
00194 template<typename T> inline void from_string(const char Str[], T &Obj, size_t)
00195 {
00196 return from_string(Str, Obj);
00197 }
00198
00199 template<>
00200 inline void from_string<PGSTD::string>(const char Str[],
00201 PGSTD::string &Obj,
00202 size_t len)
00203 {
00204 if (!Str)
00205 throw PGSTD::runtime_error("Attempt to read NULL string");
00206 Obj.assign(Str, len);
00207 }
00208
00209 template<typename T>
00210 inline void from_string(const PGSTD::string &Str, T &Obj)
00211 { from_string(Str.c_str(), Obj); }
00212
00213 template<typename T>
00214 inline void from_string(const PGSTD::stringstream &Str, T &Obj)
00215 { from_string(Str.str(), Obj); }
00216
00217 template<> inline void
00218 from_string(const PGSTD::string &Str, PGSTD::string &Obj)
00219 { Obj = Str; }
00220
00221
00222 namespace internal
00223 {
00225 inline int digit_to_number(char c) throw () { return c-'0'; }
00226 inline char number_to_digit(int i) throw () { return static_cast<char>(i+'0'); }
00227 }
00228
00229
00231
00235 template<typename T> inline PGSTD::string to_string(const T &Obj)
00236 { return string_traits<T>::to_string(Obj); }
00237
00238
00239 inline PGSTD::string to_string(const char Obj[])
00240 { return Obj; }
00241
00243
00244 }
00245
00246 #endif
00247