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 
00047 
00048 namespace pqxx {}
00049 
00050 #include <pqxx/libpq-forward.hxx>
00051 
00052 
00053 namespace pqxx
00054 {
00056 const oid oid_none = 0;
00057 
00059 
00072 template<typename T> void error_unsupported_type_in_string_conversion(T);
00073 
00074 
00076 
00082 template<typename T> PGSTD::string error_ambiguous_string_conversion(T);
00083 
00084 
00085 
00086 // TODO: Implement date conversions
00087 
00089 
00099 template<typename T> void from_string(const char Str[], T &Obj);
00100 
00101 template<> void PQXX_LIBEXPORT from_string(const char Str[], long &);   //[t45]
00102 template<>
00103   void PQXX_LIBEXPORT from_string(const char Str[], unsigned long &);   //[t45]
00104 template<> void PQXX_LIBEXPORT from_string(const char Str[], int &);    //[t45]
00105 template<>
00106   void PQXX_LIBEXPORT from_string(const char Str[], unsigned int &);    //[t45]
00107 template<> void PQXX_LIBEXPORT from_string(const char Str[], short &);  //[t45]
00108 template<>
00109   void PQXX_LIBEXPORT from_string(const char Str[], unsigned short &);  //[t45]
00110 template<> void PQXX_LIBEXPORT from_string(const char Str[], float &);  //[t46]
00111 template<> void PQXX_LIBEXPORT from_string(const char Str[], double &); //[t46]
00112 template<> void PQXX_LIBEXPORT from_string(const char Str[], bool &);   //[t76]
00113 #if defined(PQXX_HAVE_LONG_DOUBLE)
00114 template<>
00115   void PQXX_LIBEXPORT from_string(const char Str[], long double &);     //[t46]
00116 #endif
00117 
00118 
00119 template<> inline void from_string(const char Str[],PGSTD::string &Obj) //[t46]
00120         { Obj = Str; }
00121 
00122 template<>
00123   inline void from_string(const char Str[], PGSTD::stringstream &Obj)   //[t0]
00124         { Obj.clear(); Obj << Str; }
00125 
00126 template<typename T>
00127   inline void from_string(const PGSTD::string &Str, T &Obj)             //[t45]
00128         { from_string(Str.c_str(), Obj); }
00129 
00130 template<typename T>
00131   inline void from_string(const PGSTD::stringstream &Str, T &Obj)       //[t0]
00132         { from_string(Str.str(), Obj); }
00133 
00134 template<> inline void
00135 from_string(const PGSTD::string &Str, PGSTD::string &Obj)               //[t46]
00136         { Obj = Str; }
00137 
00138 template<> inline void
00139 from_string(const PGSTD::string &, const char &Obj)
00140         { error_ambiguous_string_conversion(Obj); }
00141 template<> inline void
00142 from_string(const PGSTD::string &, const signed char &Obj)
00143         { error_ambiguous_string_conversion(Obj); }
00144 template<> inline void
00145 from_string(const PGSTD::string &, const unsigned char &Obj)
00146         { error_ambiguous_string_conversion(Obj); }
00147 
00148 
00150 
00154 template<typename T> PGSTD::string to_string(const T &);
00155 
00156 template<> PGSTD::string PQXX_LIBEXPORT to_string(const short &);       //[t76]
00157 template<>
00158   PGSTD::string PQXX_LIBEXPORT to_string(const unsigned short &);       //[t76]
00159 template<> PGSTD::string PQXX_LIBEXPORT to_string(const int &);         //[t10]
00160 template<>
00161   PGSTD::string PQXX_LIBEXPORT to_string(const unsigned int &);         //[t13]
00162 template<> PGSTD::string PQXX_LIBEXPORT to_string(const long &);        //[t18]
00163 template<>
00164   PGSTD::string PQXX_LIBEXPORT to_string(const unsigned long &);        //[t20]
00165 template<> PGSTD::string PQXX_LIBEXPORT to_string(const float &);       //[t74]
00166 template<> PGSTD::string PQXX_LIBEXPORT to_string(const double &);      //[t74]
00167 template<> PGSTD::string PQXX_LIBEXPORT to_string(const bool &);        //[t76]
00168 #if defined(PQXX_HAVE_LONG_DOUBLE)
00169 template<> PGSTD::string PQXX_LIBEXPORT to_string(const long double &); //[t74]
00170 #endif
00171 
00172 inline PGSTD::string to_string(const char Obj[])                        //[t14]
00173         { return PGSTD::string(Obj); }
00174 
00175 inline PGSTD::string to_string(const PGSTD::stringstream &Obj)          //[t0]
00176         { return Obj.str(); }
00177 
00178 inline PGSTD::string to_string(const PGSTD::string &Obj) {return Obj;}  //[t21]
00179 
00180 template<> PGSTD::string PQXX_LIBEXPORT to_string(const char &);        //[t21]
00181 
00182 
00183 template<> inline PGSTD::string to_string(const signed char &Obj)
00184         { return error_ambiguous_string_conversion(Obj); }
00185 template<> inline PGSTD::string to_string(const unsigned char &Obj)
00186         { return error_ambiguous_string_conversion(Obj); }
00187 
00188 
00190 
00207 template<typename T=PGSTD::string, typename CONT=PGSTD::vector<T> >
00208 class items : public CONT
00209 {
00210 public:
00212   items() : CONT() {}                                                   //[t80]
00214   explicit items(const T &t) : CONT() { push_back(t); }                 //[t0]
00215   items(const T &t1, const T &t2) : CONT()                              //[t80]
00216         { push_back(t1); push_back(t2); }
00217   items(const T &t1, const T &t2, const T &t3) : CONT()                 //[t0]
00218         { push_back(t1); push_back(t2); push_back(t3); }
00219   items(const T &t1, const T &t2, const T &t3, const T &t4) : CONT()    //[t0]
00220         { push_back(t1); push_back(t2); push_back(t3); push_back(t4); }
00221   items(const T&t1,const T&t2,const T&t3,const T&t4,const T&t5):CONT()  //[t0]
00222         {push_back(t1);push_back(t2);push_back(t3);push_back(t4);push_back(t5);}
00224   items(const CONT &c) : CONT(c) {}                                     //[t0]
00225 
00227   items &operator()(const T &t)                                         //[t80]
00228   {
00229     push_back(t);
00230     return *this;
00231   }
00232 };
00233 
00234 
00235 namespace internal
00236 {
00237 // TODO: Does standard library provide a ready-made version of this?
00239 template<typename ITER> struct dereference
00240 {
00241   typename ITER::value_type operator()(ITER i) const { return *i; }
00242 };
00243 template<typename T> struct deref_ptr { T operator()(T *i) const {return *i;} };
00244 }
00245 
00246 
00248 template<typename ITER, typename ACCESS> inline
00249 PGSTD::string separated_list(const PGSTD::string &sep,                  //[t0]
00250     ITER begin,
00251     ITER end,
00252     ACCESS access)
00253 {
00254   PGSTD::string result;
00255   if (begin != end)
00256   {
00257     result = to_string(access(begin));
00258     for (++begin; begin != end; ++begin)
00259     {
00260       result += sep;
00261       result += to_string(access(begin));
00262     }
00263   }
00264   return result;
00265 }
00266 
00268 template<typename ITER> inline PGSTD::string
00269 separated_list(const PGSTD::string &sep, ITER begin, ITER end)          //[t8]
00270         { return separated_list(sep,begin,end,internal::dereference<ITER>()); }
00271 
00272 
00274 template<typename OBJ> inline PGSTD::string
00275 separated_list(const PGSTD::string &sep, OBJ *begin, OBJ *end)          //[t9]
00276         { return separated_list(sep,begin,end,internal::deref_ptr<OBJ>()); }
00277 
00278 
00280 template<typename CONTAINER> inline PGSTD::string
00281 separated_list(const PGSTD::string &sep, const CONTAINER &c)            //[t10]
00282         { return separated_list(sep, c.begin(), c.end()); }
00283 
00284 
00286 
00295 namespace internal
00296 {
00297 typedef unsigned long result_size_type;
00298 typedef long result_difference_type;
00299 
00301 
00309 template<typename T> inline const char *FmtString(T t)
00310 {
00311   error_unsupported_type_in_string_conversion(t);
00312   return 0;
00313 }
00314 
00315 template<> inline const char *FmtString(short)         { return "%hd"; }
00316 template<> inline const char *FmtString(unsigned short){ return "%hu"; }
00317 template<> inline const char *FmtString(int)           { return  "%i"; }
00318 template<> inline const char *FmtString(long)          { return "%li"; }
00319 template<> inline const char *FmtString(unsigned)      { return  "%u"; }
00320 template<> inline const char *FmtString(unsigned long) { return "%lu"; }
00321 template<> inline const char *FmtString(float)         { return  "%f"; }
00322 template<> inline const char *FmtString(double)        { return "%lf"; }
00323 template<> inline const char *FmtString(char)          { return  "%c"; }
00324 template<> inline const char *FmtString(unsigned char) { return  "%c"; }
00325 #if defined(PQXX_HAVE_LONG_DOUBLE)
00326 template<> inline const char *FmtString(long double)   { return "%Lf"; }
00327 #endif
00328 
00329 } // namespace internal
00330 
00332 
00340 template<typename T> inline PGSTD::string ToString(const T &Obj)
00341 {
00342   // TODO: Find a decent way to determine max string length at compile time!
00343   char Buf[500];
00344   sprintf(Buf, internal::FmtString(Obj), Obj);
00345   return PGSTD::string(Buf);
00346 }
00347 
00348 
00349 template<> inline PGSTD::string ToString(const PGSTD::string &Obj) {return Obj;}
00350 template<> inline PGSTD::string ToString(const char *const &Obj) { return Obj; }
00351 template<> inline PGSTD::string ToString(char *const &Obj) { return Obj; }
00352 
00353 template<> inline PGSTD::string ToString(const unsigned char *const &Obj)
00354 {
00355   return reinterpret_cast<const char *>(Obj);
00356 }
00357 
00358 template<> inline PGSTD::string ToString(const bool &Obj)
00359 {
00360   return ToString(unsigned(Obj));
00361 }
00362 
00363 template<> inline PGSTD::string ToString(const short &Obj)
00364 {
00365   return ToString(int(Obj));
00366 }
00367 
00368 template<> inline PGSTD::string ToString(const unsigned short &Obj)
00369 {
00370   return ToString(unsigned(Obj));
00371 }
00372 
00373 
00375 
00383 template<typename T> inline void FromString(const char Str[], T &Obj)
00384 {
00385   if (!Str) throw PGSTD::runtime_error("Attempt to convert NULL string to " +
00386                                      PGSTD::string(typeid(T).name()));
00387 
00388   if (sscanf(Str, internal::FmtString(Obj), &Obj) != 1)
00389     throw PGSTD::runtime_error("Cannot convert value '" +
00390                              PGSTD::string(Str) +
00391                              "' to " + typeid(T).name());
00392 }
00393 
00394 
00395 namespace internal
00396 {
00398 
00400 void PQXX_LIBEXPORT FromString_string(const char Str[], PGSTD::string &Obj);
00401 
00403 
00405 void PQXX_LIBEXPORT FromString_ucharptr(const char Str[],
00406         const unsigned char *&Obj);
00407 
00409 PGSTD::string PQXX_LIBEXPORT Quote_string(const PGSTD::string &Obj,
00410         bool EmptyIsNull);
00411 
00413 PGSTD::string PQXX_LIBEXPORT Quote_charptr(const char Obj[], bool EmptyIsNull);
00414 } // namespace internal
00415 
00416 
00417 template<> inline void FromString(const char Str[], PGSTD::string &Obj)
00418 {
00419   internal::FromString_string(Str, Obj);
00420 }
00421 
00422 template<> inline void FromString(const char Str[], const char *&Obj)
00423 {
00424   if (!Str) throw PGSTD::runtime_error("Attempt to read NULL string");
00425   Obj = Str;
00426 }
00427 
00428 template<> inline void FromString(const char Str[], const unsigned char *&Obj)
00429 {
00430   internal::FromString_ucharptr(Str, Obj);
00431 }
00432 
00433 template<> inline void FromString(const char Str[], bool &Obj)
00434 {
00435   from_string(Str, Obj);
00436 }
00437 
00438 
00440 
00449 PGSTD::string PQXX_LIBEXPORT sqlesc(const char str[]);                  //[t0]
00450 
00452 
00462 PGSTD::string PQXX_LIBEXPORT sqlesc(const char str[], size_t maxlen);   //[t0]
00463 
00465 
00471 PGSTD::string PQXX_LIBEXPORT sqlesc(const PGSTD::string &);             //[t0]
00472 
00473 
00475 
00479 template<typename T> PGSTD::string Quote(const T &Obj, bool EmptyIsNull);
00480 
00481 
00483 
00485 template<>
00486 inline PGSTD::string Quote(const PGSTD::string &Obj, bool EmptyIsNull)
00487 {
00488   return internal::Quote_string(Obj, EmptyIsNull);
00489 }
00490 
00492 
00494 template<> inline PGSTD::string Quote(const char *const & Obj, bool EmptyIsNull)
00495 {
00496   return internal::Quote_charptr(Obj, EmptyIsNull);
00497 }
00498 
00499 
00501 
00506 template<int LEN> inline PGSTD::string Quote(const char (&Obj)[LEN],
00507                                              bool EmptyIsNull)
00508 {
00509   return internal::Quote_charptr(Obj, EmptyIsNull);
00510 }
00511 
00512 
00513 template<typename T> inline PGSTD::string Quote(const T &Obj, bool EmptyIsNull)
00514 {
00515   return Quote(ToString(Obj), EmptyIsNull);
00516 }
00517 
00518 
00520 
00523 template<typename T> inline PGSTD::string Quote(T Obj)
00524 {
00525   return Quote(Obj, false);
00526 }
00527 
00528 
00529 namespace internal
00530 {
00531 void freepqmem(void *);
00532 void freenotif(pq::PGnotify *);
00533 
00535 
00541 template<typename T> class PQXX_LIBEXPORT PQAlloc
00542 {
00543   T *m_Obj;
00544   mutable const PQAlloc *m_l, *m_r;
00545 public:
00546   typedef T content_type;
00547 
00548   PQAlloc() throw () : m_Obj(0), m_l(this), m_r(this) {}
00549   PQAlloc(const PQAlloc &rhs) throw () :
00550     m_Obj(0), m_l(this), m_r(this) { makeref(rhs); }
00551   ~PQAlloc() throw () { loseref(); }
00552 
00553   PQAlloc &operator=(const PQAlloc &rhs) throw ()
00554         { if (&rhs != this) { loseref(); makeref(rhs); } return *this; }
00555 
00557 
00559   explicit PQAlloc(T *obj) throw () : m_Obj(obj), m_l(this), m_r(this) {}
00560 
00561   void swap(PQAlloc &rhs) throw ()
00562   {
00563     PQAlloc tmp(*this);
00564     *this = rhs;
00565     rhs = tmp;
00566   }
00567 
00568   PQAlloc &operator=(T *obj) throw () { loseref(); makeref(obj); return *this; }
00569 
00571   operator bool() const throw () { return m_Obj != 0; }
00572 
00574   bool operator!() const throw () { return !m_Obj; }
00575 
00577 
00579   T *operator->() const throw (PGSTD::logic_error)
00580   {
00581     if (!m_Obj) throw PGSTD::logic_error("Null pointer dereferenced");
00582     return m_Obj;
00583   }
00584 
00586 
00588   T &operator*() const throw (PGSTD::logic_error) { return *operator->(); }
00589 
00591 
00593   T *c_ptr() const throw () { return m_Obj; }
00594 
00595   void clear() throw () { loseref(); }
00596 
00597 private:
00598   void makeref(T *p) throw () { m_Obj = p; }
00599 
00600   void makeref(const PQAlloc &rhs) throw ()
00601   {
00602     m_l = &rhs;
00603     m_r = rhs.m_r;
00604     m_l->m_r = m_r->m_l = this;
00605     m_Obj = rhs.m_Obj;
00606   }
00607 
00609   void loseref() throw ()
00610   {
00611     if (m_l == this && m_Obj) freemem();
00612     m_Obj = 0;
00613     m_l->m_r = m_r;
00614     m_r->m_l = m_l;
00615     m_l = m_r = this;
00616   }
00617 
00618   void freemem() throw () { freepqmem(m_Obj); }
00619 };
00620 
00621 
00622 class PQXX_LIBEXPORT namedclass
00623 {
00624 public:
00625   namedclass(const PGSTD::string &Name, const PGSTD::string &Classname) :
00626     m_Name(Name),
00627     m_Classname(Classname)
00628   {
00629   }
00630 
00631   const PGSTD::string &name() const throw () { return m_Name; }         //[t1]
00632   const PGSTD::string &classname() const throw () {return m_Classname;} //[t73]
00633   PGSTD::string description() const;
00634 
00635 private:
00636   PGSTD::string m_Name, m_Classname;
00637 };
00638 
00639 
00640 void CheckUniqueRegistration(const namedclass *New, const namedclass *Old);
00641 void CheckUniqueUnregistration(const namedclass *New, const namedclass *Old);
00642 
00643 
00645 
00648 template<typename GUEST>
00649 class unique
00650 {
00651 public:
00652   unique() : m_Guest(0) {}
00653 
00654   GUEST *get() const throw () { return m_Guest; }
00655 
00656   void Register(GUEST *G)
00657   {
00658     CheckUniqueRegistration(G, m_Guest);
00659     m_Guest = G;
00660   }
00661 
00662   void Unregister(GUEST *G)
00663   {
00664     CheckUniqueUnregistration(G, m_Guest);
00665     m_Guest = 0;
00666   }
00667 
00668 private:
00669   GUEST *m_Guest;
00670 
00672   unique(const unique &);
00674   unique &operator=(const unique &);
00675 };
00676 
00678 
00681 void PQXX_LIBEXPORT sleep_seconds(int);
00682 
00683 } // namespace internal
00684 } // namespace pqxx
00685 

Generated on Sat Mar 19 18:42:43 2005 for libpqxx by  doxygen 1.4.1