Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | 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-2004, 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 <stdexcept>
00023 #include <string>
00024 #include <typeinfo>
00025 
00026 extern "C"
00027 {
00028 #include "libpq-fe.h"
00029 }
00030 
00031 
00033 namespace pqxx
00034 {
00035 typedef long result_size_type;
00036 typedef int tuple_size_type;
00037 
00039 typedef Oid oid;
00040 
00042 const oid oid_none = InvalidOid;
00043 
00044 
00046 
00059 template<typename T> void error_unsupported_type_in_string_conversion(T);
00060 
00061 
00063 
00068 namespace internal
00069 {
00071 
00077 template<typename T> inline const char *FmtString(T t)
00078 {
00079   error_unsupported_type_in_string_conversion(t);
00080   return 0;
00081 }
00082 
00083 // Not implemented to prevent accidents with irregular meaning of argument:
00084 // template<> inline const char *FmtString(const char *&) { return "%s"; }
00085 
00086 template<> inline const char *FmtString(short)         { return "%hd"; }
00087 template<> inline const char *FmtString(unsigned short){ return "%hu"; }
00088 template<> inline const char *FmtString(int)           { return  "%i"; }
00089 template<> inline const char *FmtString(long)          { return "%li"; }
00090 template<> inline const char *FmtString(unsigned)      { return  "%u"; }
00091 template<> inline const char *FmtString(unsigned long) { return "%lu"; }
00092 template<> inline const char *FmtString(float)         { return  "%f"; }
00093 template<> inline const char *FmtString(double)        { return "%lf"; }
00094 template<> inline const char *FmtString(long double)   { return "%Lf"; }
00095 template<> inline const char *FmtString(char)          { return  "%c"; }
00096 template<> inline const char *FmtString(unsigned char) { return  "%c"; }
00097 
00098 } // namespace internal
00099 
00101 
00108 template<typename T> inline PGSTD::string ToString(const T &Obj)
00109 {
00110   // TODO: Find a decent way to determine max string length at compile time!
00111   char Buf[500];
00112   sprintf(Buf, internal::FmtString(Obj), Obj);
00113   return PGSTD::string(Buf);
00114 }
00115 
00116 // TODO: Implement date conversions
00117 
00118 template<> inline PGSTD::string ToString(const PGSTD::string &Obj) {return Obj;}
00119 template<> inline PGSTD::string ToString(const char *const &Obj) { return Obj; }
00120 template<> inline PGSTD::string ToString(char *const &Obj) { return Obj; }
00121 
00122 template<> inline PGSTD::string ToString(const unsigned char *const &Obj)
00123 {
00124   return reinterpret_cast<const char *>(Obj);
00125 }
00126 
00127 template<> inline PGSTD::string ToString(const bool &Obj) 
00128 { 
00129   return ToString(unsigned(Obj));
00130 }
00131 
00132 template<> inline PGSTD::string ToString(const short &Obj)
00133 {
00134   return ToString(int(Obj));
00135 }
00136 
00137 template<> inline PGSTD::string ToString(const unsigned short &Obj)
00138 {
00139   return ToString(unsigned(Obj));
00140 }
00141 
00142 
00144 
00151 template<typename T> inline void FromString(const char Str[], T &Obj)
00152 {
00153   if (!Str) throw PGSTD::runtime_error("Attempt to convert NULL string to " +
00154                                      PGSTD::string(typeid(T).name()));
00155 
00156   if (sscanf(Str, internal::FmtString(Obj), &Obj) != 1)
00157     throw PGSTD::runtime_error("Cannot convert value '" + 
00158                              PGSTD::string(Str) + 
00159                              "' to " + typeid(T).name());
00160 }
00161 
00162 
00163 namespace internal
00164 {
00166 void PQXX_LIBEXPORT FromString_string(const char Str[], PGSTD::string &Obj);
00167 
00169 void PQXX_LIBEXPORT FromString_ucharptr(const char Str[], 
00170         const unsigned char *&Obj);
00171 
00173 void PQXX_LIBEXPORT FromString_bool(const char Str[], bool &Obj);
00174 
00176 PGSTD::string PQXX_LIBEXPORT Quote_string(const PGSTD::string &Obj, 
00177         bool EmptyIsNull);
00178 
00180 PGSTD::string PQXX_LIBEXPORT Quote_charptr(const char Obj[], bool EmptyIsNull);
00181 } // namespace internal
00182 
00183 
00184 template<> inline void FromString(const char Str[], PGSTD::string &Obj)
00185 {
00186   internal::FromString_string(Str, Obj);
00187 }
00188 
00189 template<> inline void FromString(const char Str[], const char *&Obj)
00190 {
00191   if (!Str) throw PGSTD::runtime_error("Attempt to read NULL string");
00192   Obj = Str;
00193 }
00194 
00195 template<> inline void FromString(const char Str[], const unsigned char *&Obj)
00196 {
00197   internal::FromString_ucharptr(Str, Obj);
00198 }
00199 
00200 template<> inline void FromString(const char Str[], bool &Obj)
00201 {
00202   internal::FromString_bool(Str, Obj);
00203 }
00204 
00205 
00207 
00210 template<typename T> PGSTD::string Quote(const T &Obj, bool EmptyIsNull);
00211 
00212 
00214 template<> 
00215 inline PGSTD::string Quote(const PGSTD::string &Obj, bool EmptyIsNull)
00216 {
00217   return internal::Quote_string(Obj, EmptyIsNull);
00218 }
00219 
00221 template<> inline PGSTD::string Quote(const char *const & Obj, bool EmptyIsNull)
00222 {
00223   return internal::Quote_charptr(Obj, EmptyIsNull);
00224 }
00225 
00226 
00228 
00233 template<int LEN> inline PGSTD::string Quote(const char (&Obj)[LEN],
00234                                              bool EmptyIsNull)          //[t18]
00235 {
00236   return internal::Quote_charptr(Obj, EmptyIsNull);
00237 }
00238 
00239 
00243 template<typename T> inline PGSTD::string Quote(const T &Obj, bool EmptyIsNull)
00244 {
00245   return Quote(ToString(Obj), EmptyIsNull);
00246 }
00247 
00248 
00250 
00252 template<typename T> inline PGSTD::string Quote(T Obj)
00253 {
00254   return Quote(Obj, false);
00255 }
00256 
00257 
00258 namespace internal
00259 {
00261 
00267 template<typename T> class PQAlloc
00268 {
00269   T *m_Obj;
00270 public:
00271   typedef T content_type;
00272 
00273   PQAlloc() : m_Obj(0) {}
00274 
00276   explicit PQAlloc(T *obj) : m_Obj(obj) {}
00277 
00278   ~PQAlloc() throw () { close(); }
00279 
00281 
00283   PQAlloc &operator=(T *obj) throw ()
00284   { 
00285     if (obj != m_Obj)
00286     {
00287       close();
00288       m_Obj = obj;
00289     }
00290     return *this;
00291   }
00292 
00294   operator bool() const throw () { return m_Obj != 0; }
00295 
00297   bool operator!() const throw () { return !m_Obj; }
00298 
00300 
00302   T *operator->() const throw (PGSTD::logic_error)
00303   {
00304     if (!m_Obj) throw PGSTD::logic_error("Null pointer dereferenced");
00305     return m_Obj;
00306   }
00307 
00309 
00311   T &operator*() const throw (PGSTD::logic_error) { return *operator->(); }
00312 
00314 
00316   T *c_ptr() const throw () { return m_Obj; }
00317 
00319   void close() throw () { if (m_Obj) freemem(); m_Obj = 0; }
00320 
00321 private:
00322   void freemem() throw ()
00323   {
00324 #if defined(PQXX_HAVE_PQFREEMEM)
00325     PQfreemem(reinterpret_cast<unsigned char *>(m_Obj));
00326 #else
00327     free(m_Obj);
00328 #endif
00329   }
00330 
00331   PQAlloc(const PQAlloc &);             // Not allowed
00332   PQAlloc &operator=(const PQAlloc &);  // Not allowed
00333 };
00334 
00335 
00337 template<> inline void PQAlloc<PGnotify>::freemem() throw ()
00338 {
00339 #if defined(PQXX_HAVE_PQFREEMEM)
00340     PQfreemem(reinterpret_cast<unsigned char *>(m_Obj));
00341 #elif defined(PQXX_HAVE_PQFREENOTIFY)
00342     PQfreeNotify(m_Obj);
00343 #else
00344     free(m_Obj);
00345 #endif
00346 }
00347 
00348 
00349 class PQXX_LIBEXPORT namedclass
00350 {
00351 public:
00352   namedclass(const PGSTD::string &Name, const PGSTD::string &Classname) :
00353     m_Name(Name),
00354     m_Classname(Classname)
00355   {
00356   }
00357 
00358   const PGSTD::string &name() const throw () { return m_Name; }         //[t1]
00359   const PGSTD::string &classname() const throw () {return m_Classname;} //[t73]
00360   PGSTD::string description() const throw ();                           //[t73]
00361 
00362 private:
00363   PGSTD::string m_Name, m_Classname;
00364 };
00365 
00366 
00367 void CheckUniqueRegistration(const namedclass *New, const namedclass *Old);
00368 void CheckUniqueUnregistration(const namedclass *New, const namedclass *Old);
00369 
00370 
00372 
00375 template<typename GUEST>
00376 class unique
00377 {
00378 public:
00379   unique() : m_Guest(0) {}
00380 
00381   GUEST *get() const throw () { return m_Guest; }
00382 
00383   void Register(GUEST *G)
00384   {
00385     CheckUniqueRegistration(G, m_Guest);
00386     m_Guest = G;
00387   }
00388 
00389   void Unregister(GUEST *G)
00390   {
00391     CheckUniqueUnregistration(G, m_Guest);
00392     m_Guest = 0;
00393   }
00394 
00395 private:
00396   GUEST *m_Guest;
00397 
00399   unique(const unique &);
00401   unique &operator=(const unique &);
00402 };
00403 
00404 } // namespace internal
00405 } // namespace pqxx
00406 

Generated on Thu Feb 19 22:04:36 2004 for libpqxx by doxygen 1.3.5