util.hxx

Go to the documentation of this file.
00001 /*-------------------------------------------------------------------------
00002  *
00003  *   FILE
00004  *      pqxx/util.hxx
00005  *
00006  *   DESCRIPTION
00007  *      Various utility definitions for libpqxx
00008  *      DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/util instead.
00009  *
00010  * Copyright (c) 2001-2006, Jeroen T. Vermeulen <jtv@xs4all.nl>
00011  *
00012  * See COPYING for copyright license.  If you did not receive a file called
00013  * COPYING with this source code, please notify the distributor of this mistake,
00014  * or contact the author.
00015  *
00016  *-------------------------------------------------------------------------
00017  */
00018 #include "pqxx/compiler-public.hxx"
00019 
00020 #include <cstdio>
00021 #include <cctype>
00022 #include <sstream>
00023 #include <stdexcept>
00024 #include <string>
00025 #include <typeinfo>
00026 #include <vector>
00027 
00065 
00066 namespace pqxx {}
00067 
00069 
00074 namespace PGSTD {}
00075 
00076 #include <pqxx/libpq-forward.hxx>
00077 
00078 
00079 namespace pqxx
00080 {
00082 const oid oid_none = 0;
00083 
00106 
00108 
00121 template<typename T> void error_unsupported_type_in_string_conversion(T);
00122 
00123 
00125 
00131 template<typename T> PGSTD::string error_ambiguous_string_conversion(T);
00132 
00133 
00134 
00135 // TODO: Implement date conversions
00136 
00138 
00150 template<typename T> void from_string(const char Str[], T &Obj);
00151 
00153 
00159 template<typename T> void from_string(const char Str[], T &Obj, size_t)
00160 {
00161   return from_string(Str, Obj);
00162 }
00163 
00164 template<> void PQXX_LIBEXPORT from_string(const char Str[],
00165         PGSTD::string &,
00166         size_t);                                                        //[t0]
00167 
00168 template<> void PQXX_LIBEXPORT from_string(const char Str[], long &);   //[t45]
00169 template<>
00170   void PQXX_LIBEXPORT from_string(const char Str[], unsigned long &);   //[t45]
00171 template<> void PQXX_LIBEXPORT from_string(const char Str[], int &);    //[t45]
00172 template<>
00173   void PQXX_LIBEXPORT from_string(const char Str[], unsigned int &);    //[t45]
00174 template<> void PQXX_LIBEXPORT from_string(const char Str[], short &);  //[t45]
00175 template<>
00176   void PQXX_LIBEXPORT from_string(const char Str[], unsigned short &);  //[t45]
00177 template<> void PQXX_LIBEXPORT from_string(const char Str[], float &);  //[t46]
00178 template<> void PQXX_LIBEXPORT from_string(const char Str[], double &); //[t46]
00179 template<> void PQXX_LIBEXPORT from_string(const char Str[], bool &);   //[t76]
00180 #if defined(PQXX_HAVE_LONG_DOUBLE)
00181 template<>
00182   void PQXX_LIBEXPORT from_string(const char Str[], long double &);     //[t46]
00183 #endif
00184 
00185 
00186 template<> inline void from_string(const char Str[],PGSTD::string &Obj) //[t46]
00187         { Obj = Str; }
00188 
00189 template<>
00190   inline void from_string(const char Str[], PGSTD::stringstream &Obj)   //[t0]
00191         { Obj.clear(); Obj << Str; }
00192 
00193 template<typename T>
00194   inline void from_string(const PGSTD::string &Str, T &Obj)             //[t45]
00195         { from_string(Str.c_str(), Obj); }
00196 
00197 template<typename T>
00198   inline void from_string(const PGSTD::stringstream &Str, T &Obj)       //[t0]
00199         { from_string(Str.str(), Obj); }
00200 
00201 template<> inline void
00202 from_string(const PGSTD::string &Str, PGSTD::string &Obj)               //[t46]
00203         { Obj = Str; }
00204 
00205 template<> inline void
00206 from_string(const char [], char &Obj)
00207         { error_ambiguous_string_conversion(Obj); }
00208 template<> inline void
00209 from_string(const char [], signed char &Obj)
00210         { error_ambiguous_string_conversion(Obj); }
00211 template<> inline void
00212 from_string(const char [], unsigned char &Obj)
00213         { error_ambiguous_string_conversion(Obj); }
00214 
00215 template<> inline void
00216 from_string(const PGSTD::string &, char &Obj)
00217         { error_ambiguous_string_conversion(Obj); }
00218 template<> inline void
00219 from_string(const PGSTD::string &, signed char &Obj)
00220         { error_ambiguous_string_conversion(Obj); }
00221 template<> inline void
00222 from_string(const PGSTD::string &, unsigned char &Obj)
00223         { error_ambiguous_string_conversion(Obj); }
00224 
00225 
00226 namespace internal
00227 {
00229 inline int digit_to_number(char c) throw () { return c-'0'; }
00230 inline char number_to_digit(int i) throw () { return static_cast<char>(i)+'0'; }
00231 }
00232 
00233 
00235 
00239 template<typename T> PGSTD::string to_string(const T &);
00240 
00241 template<> PGSTD::string PQXX_LIBEXPORT to_string(const short &);       //[t76]
00242 template<>
00243   PGSTD::string PQXX_LIBEXPORT to_string(const unsigned short &);       //[t76]
00244 template<> PGSTD::string PQXX_LIBEXPORT to_string(const int &);         //[t10]
00245 template<>
00246   PGSTD::string PQXX_LIBEXPORT to_string(const unsigned int &);         //[t13]
00247 template<> PGSTD::string PQXX_LIBEXPORT to_string(const long &);        //[t18]
00248 template<>
00249   PGSTD::string PQXX_LIBEXPORT to_string(const unsigned long &);        //[t20]
00250 template<> PGSTD::string PQXX_LIBEXPORT to_string(const float &);       //[t74]
00251 template<> PGSTD::string PQXX_LIBEXPORT to_string(const double &);      //[t74]
00252 template<> PGSTD::string PQXX_LIBEXPORT to_string(const bool &);        //[t76]
00253 #if defined(PQXX_HAVE_LONG_DOUBLE)
00254 template<> PGSTD::string PQXX_LIBEXPORT to_string(const long double &); //[t74]
00255 #endif
00256 
00257 inline PGSTD::string to_string(const char Obj[])                        //[t14]
00258         { return PGSTD::string(Obj); }
00259 
00260 inline PGSTD::string to_string(const PGSTD::stringstream &Obj)          //[t0]
00261         { return Obj.str(); }
00262 
00263 inline PGSTD::string to_string(const PGSTD::string &Obj) {return Obj;}  //[t21]
00264 
00265 template<> PGSTD::string PQXX_LIBEXPORT to_string(const char &);        //[t21]
00266 
00267 
00268 template<> inline PGSTD::string to_string(const signed char &Obj)
00269         { return error_ambiguous_string_conversion(Obj); }
00270 template<> inline PGSTD::string to_string(const unsigned char &Obj)
00271         { return error_ambiguous_string_conversion(Obj); }
00273 
00275 
00297 template<typename T=PGSTD::string, typename CONT=PGSTD::vector<T> >
00298 class items : public CONT
00299 {
00300 public:
00302   items() : CONT() {}                                                   //[t80]
00304   explicit items(const T &t) : CONT() { push_back(t); }                 //[t0]
00305   items(const T &t1, const T &t2) : CONT()                              //[t80]
00306         { push_back(t1); push_back(t2); }
00307   items(const T &t1, const T &t2, const T &t3) : CONT()                 //[t0]
00308         { push_back(t1); push_back(t2); push_back(t3); }
00309   items(const T &t1, const T &t2, const T &t3, const T &t4) : CONT()    //[t0]
00310         { push_back(t1); push_back(t2); push_back(t3); push_back(t4); }
00311   items(const T&t1,const T&t2,const T&t3,const T&t4,const T&t5):CONT()  //[t0]
00312         {push_back(t1);push_back(t2);push_back(t3);push_back(t4);push_back(t5);}
00314   items(const CONT &c) : CONT(c) {}                                     //[t0]
00315 
00317   items &operator()(const T &t)                                         //[t80]
00318   {
00319     push_back(t);
00320     return *this;
00321   }
00322 };
00323 
00324 
00325 namespace internal
00326 {
00327 // TODO: Does standard library provide a ready-made version of this?
00329 template<typename ITER> struct dereference
00330 {
00331   typename ITER::value_type operator()(ITER i) const { return *i; }
00332 };
00333 template<typename T> struct deref_ptr { T operator()(T *i) const {return *i;} };
00334 }
00335 
00336 
00338 
00344 template<typename ITER, typename ACCESS> inline
00345 PGSTD::string separated_list(const PGSTD::string &sep,                  //[t0]
00346     ITER begin,
00347     ITER end,
00348     ACCESS access)
00349 {
00350   PGSTD::string result;
00351   if (begin != end)
00352   {
00353     result = to_string(access(begin));
00354     for (++begin; begin != end; ++begin)
00355     {
00356       result += sep;
00357       result += to_string(access(begin));
00358     }
00359   }
00360   return result;
00361 }
00362 
00367 
00369 template<typename ITER> inline PGSTD::string
00370 separated_list(const PGSTD::string &sep, ITER begin, ITER end)          //[t8]
00371         { return separated_list(sep,begin,end,internal::dereference<ITER>()); }
00372 
00373 
00375 template<typename OBJ> inline PGSTD::string
00376 separated_list(const PGSTD::string &sep, OBJ *begin, OBJ *end)          //[t9]
00377         { return separated_list(sep,begin,end,internal::deref_ptr<OBJ>()); }
00378 
00379 
00381 template<typename CONTAINER> inline PGSTD::string
00382 separated_list(const PGSTD::string &sep, const CONTAINER &c)            //[t10]
00383         { return separated_list(sep, c.begin(), c.end()); }
00385 
00387 
00396 namespace internal
00397 {
00398 typedef unsigned long result_size_type;
00399 typedef long result_difference_type;
00400 
00402 
00410 template<typename T> inline const char *FmtString(T t) PQXX_DEPRECATED
00411 {
00412   error_unsupported_type_in_string_conversion(t);
00413   return 0;
00414 }
00415 
00416 template<> inline const char *FmtString(short)         { return "%hd"; }
00417 template<> inline const char *FmtString(unsigned short){ return "%hu"; }
00418 template<> inline const char *FmtString(int)           { return  "%i"; }
00419 template<> inline const char *FmtString(long)          { return "%li"; }
00420 template<> inline const char *FmtString(unsigned)      { return  "%u"; }
00421 template<> inline const char *FmtString(unsigned long) { return "%lu"; }
00422 template<> inline const char *FmtString(float)         { return  "%f"; }
00423 template<> inline const char *FmtString(double)        { return "%lf"; }
00424 template<> inline const char *FmtString(char)          { return  "%c"; }
00425 template<> inline const char *FmtString(unsigned char) { return  "%c"; }
00426 #if defined(PQXX_HAVE_LONG_DOUBLE)
00427 template<> inline const char *FmtString(long double)   { return "%Lf"; }
00428 #endif
00429 
00430 } // namespace internal
00431 
00433 
00441 template<typename T> inline PGSTD::string ToString(const T &Obj) PQXX_DEPRECATED
00442 {
00443   // TODO: Find a decent way to determine max string length at compile time!
00444   char Buf[500];
00445   sprintf(Buf, internal::FmtString(Obj), Obj);
00446   return PGSTD::string(Buf);
00447 }
00448 
00449 
00450 template<> inline PGSTD::string ToString(const PGSTD::string &Obj) {return Obj;}
00451 template<> inline PGSTD::string ToString(const char *const &Obj) { return Obj; }
00452 template<> inline PGSTD::string ToString(char *const &Obj) { return Obj; }
00453 
00454 template<> inline PGSTD::string ToString(const unsigned char *const &Obj)
00455 {
00456   return reinterpret_cast<const char *>(Obj);
00457 }
00458 
00459 template<> inline PGSTD::string ToString(const bool &Obj)
00460 {
00461   return ToString(unsigned(Obj));
00462 }
00463 
00464 template<> inline PGSTD::string ToString(const short &Obj)
00465 {
00466   return ToString(int(Obj));
00467 }
00468 
00469 template<> inline PGSTD::string ToString(const unsigned short &Obj)
00470 {
00471   return ToString(unsigned(Obj));
00472 }
00473 
00474 
00476 
00484 template<typename T> inline void FromString(const char Str[], T &Obj)
00485   PQXX_DEPRECATED
00486 {
00487   if (!Str) throw PGSTD::runtime_error("Attempt to convert NULL string to " +
00488                                      PGSTD::string(typeid(T).name()));
00489 
00490   if (sscanf(Str, internal::FmtString(Obj), &Obj) != 1)
00491     throw PGSTD::runtime_error("Cannot convert value '" +
00492                              PGSTD::string(Str) +
00493                              "' to " + typeid(T).name());
00494 }
00495 
00496 
00497 namespace internal
00498 {
00500 
00502 PGSTD::string escape_string(const char str[], size_t maxlen);
00503 
00505 
00507 void PQXX_LIBEXPORT FromString_string(const char Str[], PGSTD::string &Obj)
00508   PQXX_DEPRECATED;
00509 
00511 
00513 void PQXX_LIBEXPORT FromString_ucharptr(const char Str[],
00514         const unsigned char *&Obj)
00515   PQXX_DEPRECATED;
00516 
00518 PGSTD::string PQXX_LIBEXPORT Quote_string(const PGSTD::string &Obj,
00519         bool EmptyIsNull);
00520 
00522 PGSTD::string PQXX_LIBEXPORT Quote_charptr(const char Obj[], bool EmptyIsNull);
00523 } // namespace internal
00524 
00525 
00526 template<> inline void FromString(const char Str[], PGSTD::string &Obj)
00527 {
00528   internal::FromString_string(Str, Obj);
00529 }
00530 
00531 template<> inline void FromString(const char Str[], const char *&Obj)
00532 {
00533   if (!Str) throw PGSTD::runtime_error("Attempt to read NULL string");
00534   Obj = Str;
00535 }
00536 
00537 template<> inline void FromString(const char Str[], const unsigned char *&Obj)
00538 {
00539   internal::FromString_ucharptr(Str, Obj);
00540 }
00541 
00542 template<> inline void FromString(const char Str[], bool &Obj)
00543 {
00544   from_string(Str, Obj);
00545 }
00546 
00547 
00614 
00615 
00627 PGSTD::string PQXX_LIBEXPORT sqlesc(const char str[]);
00628 
00630 
00643 PGSTD::string PQXX_LIBEXPORT sqlesc(const char str[], size_t maxlen);
00644 
00646 
00652 PGSTD::string PQXX_LIBEXPORT sqlesc(const PGSTD::string &);
00653 
00654 
00656 
00661 template<typename T> PGSTD::string Quote(const T &Obj, bool EmptyIsNull)
00662   PQXX_DEPRECATED;
00663 
00664 
00666 
00668 template<>
00669 inline PGSTD::string Quote(const PGSTD::string &Obj, bool EmptyIsNull)
00670   PQXX_DEPRECATED
00671 {
00672   return internal::Quote_string(Obj, EmptyIsNull);
00673 }
00674 
00676 
00678 template<> inline PGSTD::string Quote(const char *const & Obj, bool EmptyIsNull)
00679   PQXX_DEPRECATED
00680 {
00681   return internal::Quote_charptr(Obj, EmptyIsNull);
00682 }
00683 
00684 
00686 
00693 template<int LEN> inline PGSTD::string Quote(const char (&Obj)[LEN],
00694                                              bool EmptyIsNull)
00695   PQXX_DEPRECATED
00696 {
00697   return internal::Quote_charptr(Obj, EmptyIsNull);
00698 }
00699 
00700 
00701 template<typename T> inline PGSTD::string Quote(const T &Obj, bool EmptyIsNull)
00702   PQXX_DEPRECATED
00703 {
00704   return Quote(ToString(Obj), EmptyIsNull);
00705 }
00706 
00707 
00709 
00713 template<typename T> inline PGSTD::string Quote(T Obj) PQXX_DEPRECATED
00714 {
00715   return Quote(Obj, false);
00716 }
00718 
00719 
00720 namespace internal
00721 {
00722 void PQXX_LIBEXPORT freepqmem(void *);
00723 
00724 
00726 class PQXX_LIBEXPORT refcount
00727 {
00728   refcount *volatile m_l, *volatile m_r;
00729 
00730 public:
00731   refcount();
00732   ~refcount();
00733 
00735   void makeref(refcount &) throw ();
00736 
00738   bool loseref() throw ();
00739 
00740 private:
00742   refcount(const refcount &);
00744   refcount &operator=(const refcount &);
00745 };
00746 
00747 
00749 
00763 template<typename T> class PQAlloc
00764 {
00765   T *m_Obj;
00766   mutable refcount m_rc;
00767 public:
00768   typedef T content_type;
00769 
00770   PQAlloc() throw () : m_Obj(0), m_rc() {}
00771   PQAlloc(const PQAlloc &rhs) throw () : m_Obj(0), m_rc() { makeref(rhs); }
00772   ~PQAlloc() throw () { loseref(); }
00773 
00774   PQAlloc &operator=(const PQAlloc &rhs) throw () {redoref(rhs); return *this;}
00775 
00777 
00779   explicit PQAlloc(T *obj) throw () : m_Obj(obj), m_rc() {}
00780 
00781   void swap(PQAlloc &rhs) throw ()
00782   {
00783     PQAlloc tmp(*this);
00784     *this = rhs;
00785     rhs = tmp;
00786   }
00787 
00788   PQAlloc &operator=(T *obj) throw () { redoref(obj); return *this; }
00789 
00791   operator bool() const throw () { return m_Obj != 0; }
00792 
00794   bool operator!() const throw () { return !m_Obj; }
00795 
00797 
00799   T *operator->() const throw (PGSTD::logic_error)
00800   {
00801     if (!m_Obj) throw PGSTD::logic_error("Null pointer dereferenced");
00802     return m_Obj;
00803   }
00804 
00806 
00808   T &operator*() const throw (PGSTD::logic_error) { return *operator->(); }
00809 
00811 
00813   T *c_ptr() const throw () { return m_Obj; }
00814 
00815   void clear() throw () { loseref(); }
00816 
00817 private:
00818   void makeref(T *p) throw () { m_Obj = p; }
00819 
00820   void makeref(const PQAlloc &rhs) throw ()
00821   {
00822     m_Obj = rhs.m_Obj;
00823     m_rc.makeref(rhs.m_rc);
00824   }
00825 
00827   void loseref() throw ()
00828   {
00829     if (m_rc.loseref() && m_Obj) freemem();
00830     m_Obj = 0;
00831   }
00832 
00833   void redoref(const PQAlloc &rhs) throw ()
00834         { if (rhs.m_Obj != m_Obj) { loseref(); makeref(rhs); } }
00835   void redoref(T *obj) throw ()
00836         { if (obj != m_Obj) { loseref(); makeref(obj); } }
00837 
00838   void freemem() throw () { freepqmem(m_Obj); }
00839 };
00840 
00841 
00842 void PQXX_LIBEXPORT freemem_result(pq::PGresult *) throw ();
00843 template<> inline void PQAlloc<pq::PGresult>::freemem() throw ()
00844         { freemem_result(m_Obj); }
00845 
00846 void PQXX_LIBEXPORT freemem_notif(pq::PGnotify *) throw ();
00847 template<> inline void PQAlloc<pq::PGnotify>::freemem() throw ()
00848         { freemem_notif(m_Obj); }
00849 
00850 
00851 
00852 template<typename T> class scoped_array
00853 {
00854   T *m_ptr;
00855 public:
00856   typedef size_t size_type;
00857   typedef long difference_type;
00858 
00859   scoped_array() : m_ptr(0) {}
00860   explicit scoped_array(size_type n) : m_ptr(new T[n]) {}
00861   explicit scoped_array(T *t) : m_ptr(t) {}
00862   ~scoped_array() { delete [] m_ptr; }
00863 
00864   T *c_ptr() const throw () { return m_ptr; }
00865   T &operator*() const throw () { return *m_ptr; }
00866   T &operator[](difference_type i) const throw () { return m_ptr[i]; }
00867 
00868   scoped_array &operator=(T *t) throw ()
00869   {
00870     if (t != m_ptr)
00871     {
00872       delete [] m_ptr;
00873       m_ptr = t;
00874     }
00875     return *this;
00876   }
00877 
00878 private:
00880   scoped_array(const scoped_array &);
00881   scoped_array &operator=(const scoped_array &);
00882 };
00883 
00884 
00885 class PQXX_LIBEXPORT namedclass
00886 {
00887 public:
00888   namedclass(const PGSTD::string &Classname, const PGSTD::string &Name="") :
00889     m_Classname(Classname),
00890     m_Name(Name)
00891   {
00892   }
00893 
00894   const PGSTD::string &name() const throw () { return m_Name; }         //[t1]
00895   const PGSTD::string &classname() const throw () {return m_Classname;} //[t73]
00896   PGSTD::string description() const;
00897 
00898 private:
00899   PGSTD::string m_Classname, m_Name;
00900 };
00901 
00902 
00903 void CheckUniqueRegistration(const namedclass *New, const namedclass *Old);
00904 void CheckUniqueUnregistration(const namedclass *New, const namedclass *Old);
00905 
00906 
00908 
00911 template<typename GUEST>
00912 class unique
00913 {
00914 public:
00915   unique() : m_Guest(0) {}
00916 
00917   GUEST *get() const throw () { return m_Guest; }
00918 
00919   void Register(GUEST *G)
00920   {
00921     CheckUniqueRegistration(G, m_Guest);
00922     m_Guest = G;
00923   }
00924 
00925   void Unregister(GUEST *G)
00926   {
00927     CheckUniqueUnregistration(G, m_Guest);
00928     m_Guest = 0;
00929   }
00930 
00931 private:
00932   GUEST *m_Guest;
00933 
00935   unique(const unique &);
00937   unique &operator=(const unique &);
00938 };
00939 
00941 
00944 void PQXX_LIBEXPORT sleep_seconds(int);
00945 
00947 typedef const char *cstring;
00948 
00950 
00959 cstring PQXX_LIBEXPORT strerror_wrapper(int err, char buf[], PGSTD::size_t len)
00960   throw ();
00961 
00962 
00964 extern const char sql_begin_work[], sql_commit_work[], sql_rollback_work[];
00965 
00966 } // namespace internal
00967 } // namespace pqxx
00968 

Generated on Wed Sep 6 16:54:12 2006 for libpqxx by  doxygen 1.4.7