Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

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-2005, 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/libcompiler.h"
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 
00105 
00107 
00120 template<typename T> void error_unsupported_type_in_string_conversion(T);
00121 
00122 
00124 
00130 template<typename T> PGSTD::string error_ambiguous_string_conversion(T);
00131 
00132 
00133 
00134 // TODO: Implement date conversions
00135 
00137 
00149 template<typename T> void from_string(const char Str[], T &Obj);
00150 
00151 template<> void PQXX_LIBEXPORT from_string(const char Str[], long &);   //[t45]
00152 template<>
00153   void PQXX_LIBEXPORT from_string(const char Str[], unsigned long &);   //[t45]
00154 template<> void PQXX_LIBEXPORT from_string(const char Str[], int &);    //[t45]
00155 template<>
00156   void PQXX_LIBEXPORT from_string(const char Str[], unsigned int &);    //[t45]
00157 template<> void PQXX_LIBEXPORT from_string(const char Str[], short &);  //[t45]
00158 template<>
00159   void PQXX_LIBEXPORT from_string(const char Str[], unsigned short &);  //[t45]
00160 template<> void PQXX_LIBEXPORT from_string(const char Str[], float &);  //[t46]
00161 template<> void PQXX_LIBEXPORT from_string(const char Str[], double &); //[t46]
00162 template<> void PQXX_LIBEXPORT from_string(const char Str[], bool &);   //[t76]
00163 #if defined(PQXX_HAVE_LONG_DOUBLE)
00164 template<>
00165   void PQXX_LIBEXPORT from_string(const char Str[], long double &);     //[t46]
00166 #endif
00167 
00168 
00169 template<> inline void from_string(const char Str[],PGSTD::string &Obj) //[t46]
00170         { Obj = Str; }
00171 
00172 template<>
00173   inline void from_string(const char Str[], PGSTD::stringstream &Obj)   //[t0]
00174         { Obj.clear(); Obj << Str; }
00175 
00176 template<typename T>
00177   inline void from_string(const PGSTD::string &Str, T &Obj)             //[t45]
00178         { from_string(Str.c_str(), Obj); }
00179 
00180 template<typename T>
00181   inline void from_string(const PGSTD::stringstream &Str, T &Obj)       //[t0]
00182         { from_string(Str.str(), Obj); }
00183 
00184 template<> inline void
00185 from_string(const PGSTD::string &Str, PGSTD::string &Obj)               //[t46]
00186         { Obj = Str; }
00187 
00188 template<> inline void
00189 from_string(const char [], char &Obj)
00190         { error_ambiguous_string_conversion(Obj); }
00191 template<> inline void
00192 from_string(const char [], signed char &Obj)
00193         { error_ambiguous_string_conversion(Obj); }
00194 template<> inline void
00195 from_string(const char [], unsigned char &Obj)
00196         { error_ambiguous_string_conversion(Obj); }
00197 
00198 template<> inline void
00199 from_string(const PGSTD::string &, char &Obj)
00200         { error_ambiguous_string_conversion(Obj); }
00201 template<> inline void
00202 from_string(const PGSTD::string &, signed char &Obj)
00203         { error_ambiguous_string_conversion(Obj); }
00204 template<> inline void
00205 from_string(const PGSTD::string &, unsigned char &Obj)
00206         { error_ambiguous_string_conversion(Obj); }
00207 
00208 
00209 namespace internal
00210 {
00212 inline int digit_to_number(char c) throw () { return c-'0'; }
00213 inline char number_to_digit(int i) throw () { return i+'0'; }
00214 }
00215 
00216 
00218 
00222 template<typename T> PGSTD::string to_string(const T &);
00223 
00224 template<> PGSTD::string PQXX_LIBEXPORT to_string(const short &);       //[t76]
00225 template<>
00226   PGSTD::string PQXX_LIBEXPORT to_string(const unsigned short &);       //[t76]
00227 template<> PGSTD::string PQXX_LIBEXPORT to_string(const int &);         //[t10]
00228 template<>
00229   PGSTD::string PQXX_LIBEXPORT to_string(const unsigned int &);         //[t13]
00230 template<> PGSTD::string PQXX_LIBEXPORT to_string(const long &);        //[t18]
00231 template<>
00232   PGSTD::string PQXX_LIBEXPORT to_string(const unsigned long &);        //[t20]
00233 template<> PGSTD::string PQXX_LIBEXPORT to_string(const float &);       //[t74]
00234 template<> PGSTD::string PQXX_LIBEXPORT to_string(const double &);      //[t74]
00235 template<> PGSTD::string PQXX_LIBEXPORT to_string(const bool &);        //[t76]
00236 #if defined(PQXX_HAVE_LONG_DOUBLE)
00237 template<> PGSTD::string PQXX_LIBEXPORT to_string(const long double &); //[t74]
00238 #endif
00239 
00240 inline PGSTD::string to_string(const char Obj[])                        //[t14]
00241         { return PGSTD::string(Obj); }
00242 
00243 inline PGSTD::string to_string(const PGSTD::stringstream &Obj)          //[t0]
00244         { return Obj.str(); }
00245 
00246 inline PGSTD::string to_string(const PGSTD::string &Obj) {return Obj;}  //[t21]
00247 
00248 template<> PGSTD::string PQXX_LIBEXPORT to_string(const char &);        //[t21]
00249 
00250 
00251 template<> inline PGSTD::string to_string(const signed char &Obj)
00252         { return error_ambiguous_string_conversion(Obj); }
00253 template<> inline PGSTD::string to_string(const unsigned char &Obj)
00254         { return error_ambiguous_string_conversion(Obj); }
00256 
00258 
00275 template<typename T=PGSTD::string, typename CONT=PGSTD::vector<T> >
00276 class items : public CONT
00277 {
00278 public:
00280   items() : CONT() {}                                                   //[t80]
00282   explicit items(const T &t) : CONT() { push_back(t); }                 //[t0]
00283   items(const T &t1, const T &t2) : CONT()                              //[t80]
00284         { push_back(t1); push_back(t2); }
00285   items(const T &t1, const T &t2, const T &t3) : CONT()                 //[t0]
00286         { push_back(t1); push_back(t2); push_back(t3); }
00287   items(const T &t1, const T &t2, const T &t3, const T &t4) : CONT()    //[t0]
00288         { push_back(t1); push_back(t2); push_back(t3); push_back(t4); }
00289   items(const T&t1,const T&t2,const T&t3,const T&t4,const T&t5):CONT()  //[t0]
00290         {push_back(t1);push_back(t2);push_back(t3);push_back(t4);push_back(t5);}
00292   items(const CONT &c) : CONT(c) {}                                     //[t0]
00293 
00295   items &operator()(const T &t)                                         //[t80]
00296   {
00297     push_back(t);
00298     return *this;
00299   }
00300 };
00301 
00302 
00303 namespace internal
00304 {
00305 // TODO: Does standard library provide a ready-made version of this?
00307 template<typename ITER> struct dereference
00308 {
00309   typename ITER::value_type operator()(ITER i) const { return *i; }
00310 };
00311 template<typename T> struct deref_ptr { T operator()(T *i) const {return *i;} };
00312 }
00313 
00314 
00316 template<typename ITER, typename ACCESS> inline
00317 PGSTD::string separated_list(const PGSTD::string &sep,                  //[t0]
00318     ITER begin,
00319     ITER end,
00320     ACCESS access)
00321 {
00322   PGSTD::string result;
00323   if (begin != end)
00324   {
00325     result = to_string(access(begin));
00326     for (++begin; begin != end; ++begin)
00327     {
00328       result += sep;
00329       result += to_string(access(begin));
00330     }
00331   }
00332   return result;
00333 }
00334 
00336 template<typename ITER> inline PGSTD::string
00337 separated_list(const PGSTD::string &sep, ITER begin, ITER end)          //[t8]
00338         { return separated_list(sep,begin,end,internal::dereference<ITER>()); }
00339 
00340 
00342 template<typename OBJ> inline PGSTD::string
00343 separated_list(const PGSTD::string &sep, OBJ *begin, OBJ *end)          //[t9]
00344         { return separated_list(sep,begin,end,internal::deref_ptr<OBJ>()); }
00345 
00346 
00348 template<typename CONTAINER> inline PGSTD::string
00349 separated_list(const PGSTD::string &sep, const CONTAINER &c)            //[t10]
00350         { return separated_list(sep, c.begin(), c.end()); }
00351 
00352 
00354 
00363 namespace internal
00364 {
00365 typedef unsigned long result_size_type;
00366 typedef long result_difference_type;
00367 
00369 
00377 template<typename T> inline const char *FmtString(T t)
00378 {
00379   error_unsupported_type_in_string_conversion(t);
00380   return 0;
00381 }
00382 
00383 template<> inline const char *FmtString(short)         { return "%hd"; }
00384 template<> inline const char *FmtString(unsigned short){ return "%hu"; }
00385 template<> inline const char *FmtString(int)           { return  "%i"; }
00386 template<> inline const char *FmtString(long)          { return "%li"; }
00387 template<> inline const char *FmtString(unsigned)      { return  "%u"; }
00388 template<> inline const char *FmtString(unsigned long) { return "%lu"; }
00389 template<> inline const char *FmtString(float)         { return  "%f"; }
00390 template<> inline const char *FmtString(double)        { return "%lf"; }
00391 template<> inline const char *FmtString(char)          { return  "%c"; }
00392 template<> inline const char *FmtString(unsigned char) { return  "%c"; }
00393 #if defined(PQXX_HAVE_LONG_DOUBLE)
00394 template<> inline const char *FmtString(long double)   { return "%Lf"; }
00395 #endif
00396 
00397 } // namespace internal
00398 
00400 
00408 template<typename T> inline PGSTD::string ToString(const T &Obj)
00409 {
00410   // TODO: Find a decent way to determine max string length at compile time!
00411   char Buf[500];
00412   sprintf(Buf, internal::FmtString(Obj), Obj);
00413   return PGSTD::string(Buf);
00414 }
00415 
00416 
00417 template<> inline PGSTD::string ToString(const PGSTD::string &Obj) {return Obj;}
00418 template<> inline PGSTD::string ToString(const char *const &Obj) { return Obj; }
00419 template<> inline PGSTD::string ToString(char *const &Obj) { return Obj; }
00420 
00421 template<> inline PGSTD::string ToString(const unsigned char *const &Obj)
00422 {
00423   return reinterpret_cast<const char *>(Obj);
00424 }
00425 
00426 template<> inline PGSTD::string ToString(const bool &Obj)
00427 {
00428   return ToString(unsigned(Obj));
00429 }
00430 
00431 template<> inline PGSTD::string ToString(const short &Obj)
00432 {
00433   return ToString(int(Obj));
00434 }
00435 
00436 template<> inline PGSTD::string ToString(const unsigned short &Obj)
00437 {
00438   return ToString(unsigned(Obj));
00439 }
00440 
00441 
00443 
00451 template<typename T> inline void FromString(const char Str[], T &Obj)
00452 {
00453   if (!Str) throw PGSTD::runtime_error("Attempt to convert NULL string to " +
00454                                      PGSTD::string(typeid(T).name()));
00455 
00456   if (sscanf(Str, internal::FmtString(Obj), &Obj) != 1)
00457     throw PGSTD::runtime_error("Cannot convert value '" +
00458                              PGSTD::string(Str) +
00459                              "' to " + typeid(T).name());
00460 }
00461 
00462 
00463 namespace internal
00464 {
00466 
00468 void PQXX_LIBEXPORT FromString_string(const char Str[], PGSTD::string &Obj);
00469 
00471 
00473 void PQXX_LIBEXPORT FromString_ucharptr(const char Str[],
00474         const unsigned char *&Obj);
00475 
00477 PGSTD::string PQXX_LIBEXPORT Quote_string(const PGSTD::string &Obj,
00478         bool EmptyIsNull);
00479 
00481 PGSTD::string PQXX_LIBEXPORT Quote_charptr(const char Obj[], bool EmptyIsNull);
00482 } // namespace internal
00483 
00484 
00485 template<> inline void FromString(const char Str[], PGSTD::string &Obj)
00486 {
00487   internal::FromString_string(Str, Obj);
00488 }
00489 
00490 template<> inline void FromString(const char Str[], const char *&Obj)
00491 {
00492   if (!Str) throw PGSTD::runtime_error("Attempt to read NULL string");
00493   Obj = Str;
00494 }
00495 
00496 template<> inline void FromString(const char Str[], const unsigned char *&Obj)
00497 {
00498   internal::FromString_ucharptr(Str, Obj);
00499 }
00500 
00501 template<> inline void FromString(const char Str[], bool &Obj)
00502 {
00503   from_string(Str, Obj);
00504 }
00505 
00506 
00573 
00574 
00583 PGSTD::string PQXX_LIBEXPORT sqlesc(const char str[]);                  //[t0]
00584 
00586 
00596 PGSTD::string PQXX_LIBEXPORT sqlesc(const char str[], size_t maxlen);   //[t0]
00597 
00599 
00605 PGSTD::string PQXX_LIBEXPORT sqlesc(const PGSTD::string &);             //[t0]
00606 
00607 
00609 
00613 template<typename T> PGSTD::string Quote(const T &Obj, bool EmptyIsNull);
00614 
00615 
00617 
00619 template<>
00620 inline PGSTD::string Quote(const PGSTD::string &Obj, bool EmptyIsNull)
00621 {
00622   return internal::Quote_string(Obj, EmptyIsNull);
00623 }
00624 
00626 
00628 template<> inline PGSTD::string Quote(const char *const & Obj, bool EmptyIsNull)
00629 {
00630   return internal::Quote_charptr(Obj, EmptyIsNull);
00631 }
00632 
00633 
00635 
00640 template<int LEN> inline PGSTD::string Quote(const char (&Obj)[LEN],
00641                                              bool EmptyIsNull)
00642 {
00643   return internal::Quote_charptr(Obj, EmptyIsNull);
00644 }
00645 
00646 
00647 template<typename T> inline PGSTD::string Quote(const T &Obj, bool EmptyIsNull)
00648 {
00649   return Quote(ToString(Obj), EmptyIsNull);
00650 }
00651 
00652 
00654 
00657 template<typename T> inline PGSTD::string Quote(T Obj)
00658 {
00659   return Quote(Obj, false);
00660 }
00662 
00663 
00664 namespace internal
00665 {
00666 void freepqmem(void *);
00667 
00669 
00683 template<typename T> class PQXX_LIBEXPORT PQAlloc
00684 {
00685   T *m_Obj;
00686   mutable const PQAlloc *m_l, *m_r;
00687 public:
00688   typedef T content_type;
00689 
00690   PQAlloc() throw () : m_Obj(0), m_l(this), m_r(this) {}
00691   PQAlloc(const PQAlloc &rhs) throw () :
00692     m_Obj(0), m_l(this), m_r(this) { makeref(rhs); }
00693   ~PQAlloc() throw () { loseref(); }
00694 
00695   PQAlloc &operator=(const PQAlloc &rhs) throw ()
00696         { if (&rhs != this) { loseref(); makeref(rhs); } return *this; }
00697 
00699 
00701   explicit PQAlloc(T *obj) throw () : m_Obj(obj), m_l(this), m_r(this) {}
00702 
00703   void swap(PQAlloc &rhs) throw ()
00704   {
00705     PQAlloc tmp(*this);
00706     *this = rhs;
00707     rhs = tmp;
00708   }
00709 
00710   PQAlloc &operator=(T *obj) throw () { loseref(); makeref(obj); return *this; }
00711 
00713   operator bool() const throw () { return m_Obj != 0; }
00714 
00716   bool operator!() const throw () { return !m_Obj; }
00717 
00719 
00721   T *operator->() const throw (PGSTD::logic_error)
00722   {
00723     if (!m_Obj) throw PGSTD::logic_error("Null pointer dereferenced");
00724     return m_Obj;
00725   }
00726 
00728 
00730   T &operator*() const throw (PGSTD::logic_error) { return *operator->(); }
00731 
00733 
00735   T *c_ptr() const throw () { return m_Obj; }
00736 
00737   void clear() throw () { loseref(); }
00738 
00739 private:
00740   void makeref(T *p) throw () { m_Obj = p; }
00741 
00742   void makeref(const PQAlloc &rhs) throw ()
00743   {
00744     m_l = &rhs;
00745     m_r = rhs.m_r;
00746     m_l->m_r = m_r->m_l = this;
00747     m_Obj = rhs.m_Obj;
00748   }
00749 
00751   void loseref() throw ()
00752   {
00753     if (m_l == this && m_Obj) freemem();
00754     m_Obj = 0;
00755     m_l->m_r = m_r;
00756     m_r->m_l = m_l;
00757     m_l = m_r = this;
00758   }
00759 
00760   void freemem() throw () { freepqmem(m_Obj); }
00761 };
00762 
00763 
00764 void PQXX_LIBEXPORT freemem_result(pq::PGresult *) throw ();
00765 template<> inline void PQAlloc<pq::PGresult>::freemem() throw ()
00766         { freemem_result(m_Obj); }
00767 
00768 void PQXX_LIBEXPORT freemem_notif(pq::PGnotify *) throw ();
00769 template<> inline void PQAlloc<pq::PGnotify>::freemem() throw ()
00770         { freemem_notif(m_Obj); }
00771 
00772 
00773 
00774 template<typename T> class scoped_array
00775 {
00776   T *m_ptr;
00777 public:
00778   typedef size_t size_type;
00779   typedef long difference_type;
00780 
00781   scoped_array() : m_ptr(0) {}
00782   explicit scoped_array(size_type n) : m_ptr(new T[n]) {}
00783   explicit scoped_array(T *t) : m_ptr(t) {}
00784   ~scoped_array() { delete [] m_ptr; }
00785 
00786   T *c_ptr() const throw () { return m_ptr; }
00787   T &operator*() const throw () { return *m_ptr; }
00788   T &operator[](difference_type i) const throw () { return m_ptr[i]; }
00789 
00790   scoped_array &operator=(T *t) throw ()
00791   {
00792     if (t != m_ptr)
00793     {
00794       delete [] m_ptr;
00795       m_ptr = t;
00796     }
00797     return *this;
00798   }
00799 
00800 private:
00802   scoped_array(const scoped_array &);
00803   scoped_array &operator=(const scoped_array &);
00804 };
00805 
00806 
00807 class PQXX_LIBEXPORT namedclass
00808 {
00809 public:
00810   namedclass(const PGSTD::string &Name, const PGSTD::string &Classname) :
00811     m_Name(Name),
00812     m_Classname(Classname)
00813   {
00814   }
00815 
00816   const PGSTD::string &name() const throw () { return m_Name; }         //[t1]
00817   const PGSTD::string &classname() const throw () {return m_Classname;} //[t73]
00818   PGSTD::string description() const;
00819 
00820 private:
00821   PGSTD::string m_Name, m_Classname;
00822 };
00823 
00824 
00825 void CheckUniqueRegistration(const namedclass *New, const namedclass *Old);
00826 void CheckUniqueUnregistration(const namedclass *New, const namedclass *Old);
00827 
00828 
00830 
00833 template<typename GUEST>
00834 class unique
00835 {
00836 public:
00837   unique() : m_Guest(0) {}
00838 
00839   GUEST *get() const throw () { return m_Guest; }
00840 
00841   void Register(GUEST *G)
00842   {
00843     CheckUniqueRegistration(G, m_Guest);
00844     m_Guest = G;
00845   }
00846 
00847   void Unregister(GUEST *G)
00848   {
00849     CheckUniqueUnregistration(G, m_Guest);
00850     m_Guest = 0;
00851   }
00852 
00853 private:
00854   GUEST *m_Guest;
00855 
00857   unique(const unique &);
00859   unique &operator=(const unique &);
00860 };
00861 
00863 
00866 void PQXX_LIBEXPORT sleep_seconds(int);
00867 
00869 typedef const char *cstring;
00870 
00872 
00881 cstring PQXX_LIBEXPORT strerror_wrapper(int err, char buf[], PGSTD::size_t len)
00882   throw ();
00883 
00884 } // namespace internal
00885 } // namespace pqxx
00886 

Generated on Mon Oct 3 20:28:59 2005 for libpqxx by  doxygen 1.4.2