Main Page | 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 
00048 
00049 namespace pqxx {}
00050 
00051 #include <pqxx/libpq-forward.hxx>
00052 
00053 
00054 namespace pqxx
00055 {
00057 const oid oid_none = 0;
00058 
00060 
00073 template<typename T> void error_unsupported_type_in_string_conversion(T);
00074 
00075 
00077 
00083 template<typename T> PGSTD::string error_ambiguous_string_conversion(T);
00084 
00085 
00086 
00087 // TODO: Implement date conversions
00088 
00090 
00102 template<typename T> void from_string(const char Str[], T &Obj);
00103 
00104 template<> void PQXX_LIBEXPORT from_string(const char Str[], long &);   //[t45]
00105 template<>
00106   void PQXX_LIBEXPORT from_string(const char Str[], unsigned long &);   //[t45]
00107 template<> void PQXX_LIBEXPORT from_string(const char Str[], int &);    //[t45]
00108 template<>
00109   void PQXX_LIBEXPORT from_string(const char Str[], unsigned int &);    //[t45]
00110 template<> void PQXX_LIBEXPORT from_string(const char Str[], short &);  //[t45]
00111 template<>
00112   void PQXX_LIBEXPORT from_string(const char Str[], unsigned short &);  //[t45]
00113 template<> void PQXX_LIBEXPORT from_string(const char Str[], float &);  //[t46]
00114 template<> void PQXX_LIBEXPORT from_string(const char Str[], double &); //[t46]
00115 template<> void PQXX_LIBEXPORT from_string(const char Str[], bool &);   //[t76]
00116 #if defined(PQXX_HAVE_LONG_DOUBLE)
00117 template<>
00118   void PQXX_LIBEXPORT from_string(const char Str[], long double &);     //[t46]
00119 #endif
00120 
00121 
00122 template<> inline void from_string(const char Str[],PGSTD::string &Obj) //[t46]
00123         { Obj = Str; }
00124 
00125 template<>
00126   inline void from_string(const char Str[], PGSTD::stringstream &Obj)   //[t0]
00127         { Obj.clear(); Obj << Str; }
00128 
00129 template<typename T>
00130   inline void from_string(const PGSTD::string &Str, T &Obj)             //[t45]
00131         { from_string(Str.c_str(), Obj); }
00132 
00133 template<typename T>
00134   inline void from_string(const PGSTD::stringstream &Str, T &Obj)       //[t0]
00135         { from_string(Str.str(), Obj); }
00136 
00137 template<> inline void
00138 from_string(const PGSTD::string &Str, PGSTD::string &Obj)               //[t46]
00139         { Obj = Str; }
00140 
00141 template<> inline void
00142 from_string(const char [], const char &Obj)
00143         { error_ambiguous_string_conversion(Obj); }
00144 template<> inline void
00145 from_string(const char [], const signed char &Obj)
00146         { error_ambiguous_string_conversion(Obj); }
00147 template<> inline void
00148 from_string(const char [], const unsigned char &Obj)
00149         { error_ambiguous_string_conversion(Obj); }
00150 
00151 template<> inline void
00152 from_string(const PGSTD::string &, const char &Obj)
00153         { error_ambiguous_string_conversion(Obj); }
00154 template<> inline void
00155 from_string(const PGSTD::string &, const signed char &Obj)
00156         { error_ambiguous_string_conversion(Obj); }
00157 template<> inline void
00158 from_string(const PGSTD::string &, const unsigned char &Obj)
00159         { error_ambiguous_string_conversion(Obj); }
00160 
00161 
00162 namespace internal
00163 {
00165 inline int digit_to_number(char c) throw () { return c-'0'; }
00166 inline char number_to_digit(int i) throw () { return i+'0'; }
00167 }
00168 
00169 
00171 
00175 template<typename T> PGSTD::string to_string(const T &);
00176 
00177 template<> PGSTD::string PQXX_LIBEXPORT to_string(const short &);       //[t76]
00178 template<>
00179   PGSTD::string PQXX_LIBEXPORT to_string(const unsigned short &);       //[t76]
00180 template<> PGSTD::string PQXX_LIBEXPORT to_string(const int &);         //[t10]
00181 template<>
00182   PGSTD::string PQXX_LIBEXPORT to_string(const unsigned int &);         //[t13]
00183 template<> PGSTD::string PQXX_LIBEXPORT to_string(const long &);        //[t18]
00184 template<>
00185   PGSTD::string PQXX_LIBEXPORT to_string(const unsigned long &);        //[t20]
00186 template<> PGSTD::string PQXX_LIBEXPORT to_string(const float &);       //[t74]
00187 template<> PGSTD::string PQXX_LIBEXPORT to_string(const double &);      //[t74]
00188 template<> PGSTD::string PQXX_LIBEXPORT to_string(const bool &);        //[t76]
00189 #if defined(PQXX_HAVE_LONG_DOUBLE)
00190 template<> PGSTD::string PQXX_LIBEXPORT to_string(const long double &); //[t74]
00191 #endif
00192 
00193 inline PGSTD::string to_string(const char Obj[])                        //[t14]
00194         { return PGSTD::string(Obj); }
00195 
00196 inline PGSTD::string to_string(const PGSTD::stringstream &Obj)          //[t0]
00197         { return Obj.str(); }
00198 
00199 inline PGSTD::string to_string(const PGSTD::string &Obj) {return Obj;}  //[t21]
00200 
00201 template<> PGSTD::string PQXX_LIBEXPORT to_string(const char &);        //[t21]
00202 
00203 
00204 template<> inline PGSTD::string to_string(const signed char &Obj)
00205         { return error_ambiguous_string_conversion(Obj); }
00206 template<> inline PGSTD::string to_string(const unsigned char &Obj)
00207         { return error_ambiguous_string_conversion(Obj); }
00208 
00209 
00211 
00228 template<typename T=PGSTD::string, typename CONT=PGSTD::vector<T> >
00229 class items : public CONT
00230 {
00231 public:
00233   items() : CONT() {}                                                   //[t80]
00235   explicit items(const T &t) : CONT() { push_back(t); }                 //[t0]
00236   items(const T &t1, const T &t2) : CONT()                              //[t80]
00237         { push_back(t1); push_back(t2); }
00238   items(const T &t1, const T &t2, const T &t3) : CONT()                 //[t0]
00239         { push_back(t1); push_back(t2); push_back(t3); }
00240   items(const T &t1, const T &t2, const T &t3, const T &t4) : CONT()    //[t0]
00241         { push_back(t1); push_back(t2); push_back(t3); push_back(t4); }
00242   items(const T&t1,const T&t2,const T&t3,const T&t4,const T&t5):CONT()  //[t0]
00243         {push_back(t1);push_back(t2);push_back(t3);push_back(t4);push_back(t5);}
00245   items(const CONT &c) : CONT(c) {}                                     //[t0]
00246 
00248   items &operator()(const T &t)                                         //[t80]
00249   {
00250     push_back(t);
00251     return *this;
00252   }
00253 };
00254 
00255 
00256 namespace internal
00257 {
00258 // TODO: Does standard library provide a ready-made version of this?
00260 template<typename ITER> struct dereference
00261 {
00262   typename ITER::value_type operator()(ITER i) const { return *i; }
00263 };
00264 template<typename T> struct deref_ptr { T operator()(T *i) const {return *i;} };
00265 }
00266 
00267 
00269 template<typename ITER, typename ACCESS> inline
00270 PGSTD::string separated_list(const PGSTD::string &sep,                  //[t0]
00271     ITER begin,
00272     ITER end,
00273     ACCESS access)
00274 {
00275   PGSTD::string result;
00276   if (begin != end)
00277   {
00278     result = to_string(access(begin));
00279     for (++begin; begin != end; ++begin)
00280     {
00281       result += sep;
00282       result += to_string(access(begin));
00283     }
00284   }
00285   return result;
00286 }
00287 
00289 template<typename ITER> inline PGSTD::string
00290 separated_list(const PGSTD::string &sep, ITER begin, ITER end)          //[t8]
00291         { return separated_list(sep,begin,end,internal::dereference<ITER>()); }
00292 
00293 
00295 template<typename OBJ> inline PGSTD::string
00296 separated_list(const PGSTD::string &sep, OBJ *begin, OBJ *end)          //[t9]
00297         { return separated_list(sep,begin,end,internal::deref_ptr<OBJ>()); }
00298 
00299 
00301 template<typename CONTAINER> inline PGSTD::string
00302 separated_list(const PGSTD::string &sep, const CONTAINER &c)            //[t10]
00303         { return separated_list(sep, c.begin(), c.end()); }
00304 
00305 
00307 
00316 namespace internal
00317 {
00318 typedef unsigned long result_size_type;
00319 typedef long result_difference_type;
00320 
00322 
00330 template<typename T> inline const char *FmtString(T t)
00331 {
00332   error_unsupported_type_in_string_conversion(t);
00333   return 0;
00334 }
00335 
00336 template<> inline const char *FmtString(short)         { return "%hd"; }
00337 template<> inline const char *FmtString(unsigned short){ return "%hu"; }
00338 template<> inline const char *FmtString(int)           { return  "%i"; }
00339 template<> inline const char *FmtString(long)          { return "%li"; }
00340 template<> inline const char *FmtString(unsigned)      { return  "%u"; }
00341 template<> inline const char *FmtString(unsigned long) { return "%lu"; }
00342 template<> inline const char *FmtString(float)         { return  "%f"; }
00343 template<> inline const char *FmtString(double)        { return "%lf"; }
00344 template<> inline const char *FmtString(char)          { return  "%c"; }
00345 template<> inline const char *FmtString(unsigned char) { return  "%c"; }
00346 #if defined(PQXX_HAVE_LONG_DOUBLE)
00347 template<> inline const char *FmtString(long double)   { return "%Lf"; }
00348 #endif
00349 
00350 } // namespace internal
00351 
00353 
00361 template<typename T> inline PGSTD::string ToString(const T &Obj)
00362 {
00363   // TODO: Find a decent way to determine max string length at compile time!
00364   char Buf[500];
00365   sprintf(Buf, internal::FmtString(Obj), Obj);
00366   return PGSTD::string(Buf);
00367 }
00368 
00369 
00370 template<> inline PGSTD::string ToString(const PGSTD::string &Obj) {return Obj;}
00371 template<> inline PGSTD::string ToString(const char *const &Obj) { return Obj; }
00372 template<> inline PGSTD::string ToString(char *const &Obj) { return Obj; }
00373 
00374 template<> inline PGSTD::string ToString(const unsigned char *const &Obj)
00375 {
00376   return reinterpret_cast<const char *>(Obj);
00377 }
00378 
00379 template<> inline PGSTD::string ToString(const bool &Obj)
00380 {
00381   return ToString(unsigned(Obj));
00382 }
00383 
00384 template<> inline PGSTD::string ToString(const short &Obj)
00385 {
00386   return ToString(int(Obj));
00387 }
00388 
00389 template<> inline PGSTD::string ToString(const unsigned short &Obj)
00390 {
00391   return ToString(unsigned(Obj));
00392 }
00393 
00394 
00396 
00404 template<typename T> inline void FromString(const char Str[], T &Obj)
00405 {
00406   if (!Str) throw PGSTD::runtime_error("Attempt to convert NULL string to " +
00407                                      PGSTD::string(typeid(T).name()));
00408 
00409   if (sscanf(Str, internal::FmtString(Obj), &Obj) != 1)
00410     throw PGSTD::runtime_error("Cannot convert value '" +
00411                              PGSTD::string(Str) +
00412                              "' to " + typeid(T).name());
00413 }
00414 
00415 
00416 namespace internal
00417 {
00419 
00421 void PQXX_LIBEXPORT FromString_string(const char Str[], PGSTD::string &Obj);
00422 
00424 
00426 void PQXX_LIBEXPORT FromString_ucharptr(const char Str[],
00427         const unsigned char *&Obj);
00428 
00430 PGSTD::string PQXX_LIBEXPORT Quote_string(const PGSTD::string &Obj,
00431         bool EmptyIsNull);
00432 
00434 PGSTD::string PQXX_LIBEXPORT Quote_charptr(const char Obj[], bool EmptyIsNull);
00435 } // namespace internal
00436 
00437 
00438 template<> inline void FromString(const char Str[], PGSTD::string &Obj)
00439 {
00440   internal::FromString_string(Str, Obj);
00441 }
00442 
00443 template<> inline void FromString(const char Str[], const char *&Obj)
00444 {
00445   if (!Str) throw PGSTD::runtime_error("Attempt to read NULL string");
00446   Obj = Str;
00447 }
00448 
00449 template<> inline void FromString(const char Str[], const unsigned char *&Obj)
00450 {
00451   internal::FromString_ucharptr(Str, Obj);
00452 }
00453 
00454 template<> inline void FromString(const char Str[], bool &Obj)
00455 {
00456   from_string(Str, Obj);
00457 }
00458 
00459 
00461 
00470 PGSTD::string PQXX_LIBEXPORT sqlesc(const char str[]);                  //[t0]
00471 
00473 
00483 PGSTD::string PQXX_LIBEXPORT sqlesc(const char str[], size_t maxlen);   //[t0]
00484 
00486 
00492 PGSTD::string PQXX_LIBEXPORT sqlesc(const PGSTD::string &);             //[t0]
00493 
00494 
00496 
00500 template<typename T> PGSTD::string Quote(const T &Obj, bool EmptyIsNull);
00501 
00502 
00504 
00506 template<>
00507 inline PGSTD::string Quote(const PGSTD::string &Obj, bool EmptyIsNull)
00508 {
00509   return internal::Quote_string(Obj, EmptyIsNull);
00510 }
00511 
00513 
00515 template<> inline PGSTD::string Quote(const char *const & Obj, bool EmptyIsNull)
00516 {
00517   return internal::Quote_charptr(Obj, EmptyIsNull);
00518 }
00519 
00520 
00522 
00527 template<int LEN> inline PGSTD::string Quote(const char (&Obj)[LEN],
00528                                              bool EmptyIsNull)
00529 {
00530   return internal::Quote_charptr(Obj, EmptyIsNull);
00531 }
00532 
00533 
00534 template<typename T> inline PGSTD::string Quote(const T &Obj, bool EmptyIsNull)
00535 {
00536   return Quote(ToString(Obj), EmptyIsNull);
00537 }
00538 
00539 
00541 
00544 template<typename T> inline PGSTD::string Quote(T Obj)
00545 {
00546   return Quote(Obj, false);
00547 }
00548 
00549 
00550 namespace internal
00551 {
00552 void freepqmem(void *);
00553 
00555 
00567 template<typename T> class PQXX_LIBEXPORT PQAlloc
00568 {
00569   T *m_Obj;
00570   mutable const PQAlloc *m_l, *m_r;
00571 public:
00572   typedef T content_type;
00573 
00574   PQAlloc() throw () : m_Obj(0), m_l(this), m_r(this) {}
00575   PQAlloc(const PQAlloc &rhs) throw () :
00576     m_Obj(0), m_l(this), m_r(this) { makeref(rhs); }
00577   ~PQAlloc() throw () { loseref(); }
00578 
00579   PQAlloc &operator=(const PQAlloc &rhs) throw ()
00580         { if (&rhs != this) { loseref(); makeref(rhs); } return *this; }
00581 
00583 
00585   explicit PQAlloc(T *obj) throw () : m_Obj(obj), m_l(this), m_r(this) {}
00586 
00587   void swap(PQAlloc &rhs) throw ()
00588   {
00589     PQAlloc tmp(*this);
00590     *this = rhs;
00591     rhs = tmp;
00592   }
00593 
00594   PQAlloc &operator=(T *obj) throw () { loseref(); makeref(obj); return *this; }
00595 
00597   operator bool() const throw () { return m_Obj != 0; }
00598 
00600   bool operator!() const throw () { return !m_Obj; }
00601 
00603 
00605   T *operator->() const throw (PGSTD::logic_error)
00606   {
00607     if (!m_Obj) throw PGSTD::logic_error("Null pointer dereferenced");
00608     return m_Obj;
00609   }
00610 
00612 
00614   T &operator*() const throw (PGSTD::logic_error) { return *operator->(); }
00615 
00617 
00619   T *c_ptr() const throw () { return m_Obj; }
00620 
00621   void clear() throw () { loseref(); }
00622 
00623 private:
00624   void makeref(T *p) throw () { m_Obj = p; }
00625 
00626   void makeref(const PQAlloc &rhs) throw ()
00627   {
00628     m_l = &rhs;
00629     m_r = rhs.m_r;
00630     m_l->m_r = m_r->m_l = this;
00631     m_Obj = rhs.m_Obj;
00632   }
00633 
00635   void loseref() throw ()
00636   {
00637     if (m_l == this && m_Obj) freemem();
00638     m_Obj = 0;
00639     m_l->m_r = m_r;
00640     m_r->m_l = m_l;
00641     m_l = m_r = this;
00642   }
00643 
00644   void freemem() throw () { freepqmem(m_Obj); }
00645 };
00646 
00647 
00648 void PQXX_LIBEXPORT freemem_result(pq::PGresult *) throw ();
00649 template<> inline void PQXX_LIBEXPORT PQAlloc<pq::PGresult>::freemem() throw ()
00650         { freemem_result(m_Obj); }
00651 
00652 void PQXX_LIBEXPORT freemem_notif(pq::PGnotify *) throw ();
00653 template<> inline void PQXX_LIBEXPORT PQAlloc<pq::PGnotify>::freemem() throw ()
00654         { freemem_notif(m_Obj); }
00655 
00656 
00657 
00658 template<typename T> class scoped_array
00659 {
00660   T *m_ptr;
00661 public:
00662   typedef size_t size_type;
00663   typedef long difference_type;
00664 
00665   scoped_array() : m_ptr(0) {}
00666   explicit scoped_array(size_type n) : m_ptr(new T[n]) {}
00667   explicit scoped_array(T *t) : m_ptr(t) {}
00668   ~scoped_array() { delete [] m_ptr; }
00669 
00670   T *c_ptr() const throw () { return m_ptr; }
00671   T &operator*() const throw () { return *m_ptr; }
00672   T &operator[](difference_type i) const throw () { return m_ptr[i]; }
00673 
00674   scoped_array &operator=(T *t) throw ()
00675   {
00676     if (t != m_ptr)
00677     {
00678       delete [] m_ptr;
00679       m_ptr = t;
00680     }
00681     return *this;
00682   }
00683 
00684 private:
00686   scoped_array(const scoped_array &);
00687   scoped_array &operator=(const scoped_array &);
00688 };
00689 
00690 
00691 class PQXX_LIBEXPORT namedclass
00692 {
00693 public:
00694   namedclass(const PGSTD::string &Name, const PGSTD::string &Classname) :
00695     m_Name(Name),
00696     m_Classname(Classname)
00697   {
00698   }
00699 
00700   const PGSTD::string &name() const throw () { return m_Name; }         //[t1]
00701   const PGSTD::string &classname() const throw () {return m_Classname;} //[t73]
00702   PGSTD::string description() const;
00703 
00704 private:
00705   PGSTD::string m_Name, m_Classname;
00706 };
00707 
00708 
00709 void CheckUniqueRegistration(const namedclass *New, const namedclass *Old);
00710 void CheckUniqueUnregistration(const namedclass *New, const namedclass *Old);
00711 
00712 
00714 
00717 template<typename GUEST>
00718 class unique
00719 {
00720 public:
00721   unique() : m_Guest(0) {}
00722 
00723   GUEST *get() const throw () { return m_Guest; }
00724 
00725   void Register(GUEST *G)
00726   {
00727     CheckUniqueRegistration(G, m_Guest);
00728     m_Guest = G;
00729   }
00730 
00731   void Unregister(GUEST *G)
00732   {
00733     CheckUniqueUnregistration(G, m_Guest);
00734     m_Guest = 0;
00735   }
00736 
00737 private:
00738   GUEST *m_Guest;
00739 
00741   unique(const unique &);
00743   unique &operator=(const unique &);
00744 };
00745 
00747 
00750 void PQXX_LIBEXPORT sleep_seconds(int);
00751 
00752 } // namespace internal
00753 } // namespace pqxx
00754 

Generated on Fri Jul 1 14:36:19 2005 for libpqxx by  doxygen 1.4.2