Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages  

largeobject.h

Go to the documentation of this file.
00001 /*-------------------------------------------------------------------------
00002  *
00003  *   FILE
00004  *      pqxx/largeobject.h
00005  *
00006  *   DESCRIPTION
00007  *      libpqxx's Large Objects interface
00008  *   Allows access to large objects directly, or through I/O streams
00009  *
00010  * Copyright (c) 2003, 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 #ifndef PQXX_LARGEOBJECT_H
00019 #define PQXX_LARGEOBJECT_H
00020 
00021 #include "pqxx/config.h"
00022 
00023 #ifdef HAVE_STREAMBUF
00024 #include <streambuf>
00025 #else
00026 #include <streambuf.h>
00027 #endif
00028 
00029 #include "pqxx/dbtransaction.h"
00030 
00031 
00032 namespace pqxx
00033 {
00034 
00035 class largeobjectaccess;
00036 
00038 
00045 class PQXX_LIBEXPORT largeobject
00046 {
00047 public:
00048   typedef long size_type;
00049 
00051   largeobject();                                                        //[t48]
00052 
00054 
00056   explicit largeobject(dbtransaction &T);                               //[t48]
00057 
00059 
00063   explicit largeobject(oid O) : m_ID(O) {}                              //[t48]
00064 
00066 
00070   largeobject(dbtransaction &T, const PGSTD::string &File);             //[t53]
00071 
00073 
00077   largeobject(const largeobjectaccess &O);                              //[t50]
00078 
00080 
00084   oid id() const throw () { return m_ID; }                              //[t48]
00085 
00087   bool operator==(const largeobject &other) const                       //[t51]
00088           { return m_ID == other.m_ID; }
00090   bool operator!=(const largeobject &other) const                       //[t51]
00091           { return m_ID != other.m_ID; }
00093   bool operator<=(const largeobject &other) const                       //[t51]
00094           { return m_ID <= other.m_ID; }
00096   bool operator>=(const largeobject &other) const                       //[t51]
00097           { return m_ID >= other.m_ID; }
00099   bool operator<(const largeobject &other) const                        //[t51]
00100           { return m_ID < other.m_ID; }
00102   bool operator>(const largeobject &other) const                        //[t51]
00103           { return m_ID > other.m_ID; }
00104 
00106 
00110   void to_file(dbtransaction &T, const PGSTD::string &File) const;      //[t52]
00111 
00113 
00117   void remove(dbtransaction &T) const;                                  //[t48]
00118 
00119 protected:
00120   static PGconn *RawConnection(const dbtransaction &T)
00121   {
00122     return T.Conn().RawConnection();
00123   }
00124 
00125   PGSTD::string Reason() const;
00126 
00127 private:
00128   oid m_ID;
00129 };
00130 
00132 typedef largeobject LargeObject;
00133 
00134 
00136 class PQXX_LIBEXPORT largeobjectaccess : private largeobject
00137 {
00138 public:
00139   using largeobject::size_type;
00140   typedef long off_type;
00141   typedef size_type pos_type;
00142 
00144 
00148   typedef PGSTD::ios::openmode openmode;
00149 
00151 
00155   typedef PGSTD::ios::seekdir seekdir;
00156 
00158 
00162   explicit largeobjectaccess(dbtransaction &T, 
00163                              openmode mode = 
00164                                 PGSTD::ios::in | 
00165                                 PGSTD::ios::out);                       //[t51]
00166 
00168 
00174   largeobjectaccess(dbtransaction &T, 
00175                     oid O,
00176                     openmode mode = 
00177                         PGSTD::ios::in | 
00178                         PGSTD::ios::out);                               //[t52]
00179 
00181 
00186   largeobjectaccess(dbtransaction &T, 
00187                     largeobject O,
00188                     openmode mode = PGSTD::ios::in | PGSTD::ios::out);  //[t50]
00189 
00191 
00196   largeobjectaccess(dbtransaction &T, 
00197                     const PGSTD::string &File,
00198                     openmode mode = 
00199                         PGSTD::ios::in | PGSTD::ios::out);              //[t55]
00200 
00201   ~largeobjectaccess() { close(); }
00202 
00204 
00207   using largeobject::id;
00208 
00210 
00213   void to_file(const PGSTD::string &File) const                         //[t54]
00214   { 
00215     largeobject::to_file(m_Trans, File); 
00216   }
00217 
00219 
00223   void write(const char Buf[], size_type Len);                          //[t51]
00224 
00226 
00229   void write(const PGSTD::string &Buf)                                  //[t50]
00230         { write(Buf.c_str(), Buf.size()); }
00231 
00233 
00239   size_type read(char Buf[], size_type Len);                            //[t50]
00240 
00242 
00245   size_type seek(size_type dest, seekdir dir);                          //[t51]
00246 
00248 
00256   pos_type cseek(off_type dest, seekdir dir) throw ();                  //[t50]
00257     
00259 
00265   off_type cwrite(const char Buf[], size_type Len) throw ();            //[t50]
00266 
00268 
00274   off_type cread(char Buf[], size_type Len) throw ();                   //[t50]
00275 
00276   using largeobject::operator==;
00277   using largeobject::operator!=;
00278   using largeobject::operator<;
00279   using largeobject::operator<=;
00280   using largeobject::operator>;
00281   using largeobject::operator>=;
00282 
00283 private:
00284   PGSTD::string Reason() const;
00285   PGconn *RawConnection() { return largeobject::RawConnection(m_Trans); }
00286 
00287   void open(openmode mode);
00288   void close();
00289 
00290   dbtransaction &m_Trans;
00291   int m_fd;
00292 
00293   // Not allowed:
00294   largeobjectaccess();
00295   largeobjectaccess(const largeobjectaccess &);
00296   largeobjectaccess operator=(const largeobjectaccess &);
00297 };
00298 
00300 typedef largeobjectaccess LargeObjectAccess;
00301 
00302 
00304 
00312 template<typename CHAR=char, typename TRAITS=PGSTD::char_traits<CHAR> >
00313   class PQXX_LIBEXPORT largeobject_streambuf :
00314 #ifdef HAVE_STREAMBUF
00315     public PGSTD::basic_streambuf<CHAR, TRAITS>
00316 #else
00317     public PGSTD::streambuf
00318 #endif
00319 {
00320   typedef long size_type;
00321 public:
00322   typedef CHAR   char_type;
00323   typedef TRAITS traits_type;
00324   typedef typename traits_type::int_type int_type;
00325 #ifdef HAVE_STREAMBUF
00326   typedef typename traits_type::pos_type pos_type;
00327   typedef typename traits_type::off_type off_type;
00328 #else
00329   typedef streamoff off_type;
00330   typedef streampos pos_type;
00331 #endif
00332   typedef largeobjectaccess::openmode openmode;
00333   typedef largeobjectaccess::seekdir seekdir;
00334 
00335   largeobject_streambuf(dbtransaction &T,
00336                         largeobject O,
00337                         openmode mode = in | out,
00338                         size_type BufSize=512) :                        //[t48]
00339     m_BufSize(BufSize),
00340     m_Obj(T, O),
00341     m_G(0),
00342     m_P(0)
00343   {
00344     initialize(mode);
00345   }
00346 
00347   largeobject_streambuf(dbtransaction &T,
00348                         oid O,
00349                         openmode mode = in | out,
00350                         size_type BufSize=512) :                        //[t48]
00351     m_BufSize(BufSize),
00352     m_Obj(T, O),
00353     m_G(0),
00354     m_P(0)
00355   {
00356     initialize(mode);
00357   }
00358 
00359   virtual ~largeobject_streambuf()
00360   {
00361     delete [] m_P;
00362     delete [] m_G;
00363   }
00364 
00365 
00366 #ifdef HAVE_STREAMBUF
00367 protected:
00368 #endif
00369   virtual int sync()
00370   {
00371     // setg() sets eback, gptr, egptr
00372     setg(eback(), eback(), egptr());
00373     return overflow(EoF());
00374   }
00375 
00376 protected:
00377   virtual pos_type seekoff(off_type offset, 
00378                            seekdir dir,
00379                            openmode mode = in|out)
00380   {
00381     if (!mode) {}       // Quench "unused parameter" warning
00382     return AdjustEOF(m_Obj.cseek(offset, dir));
00383   }
00384 
00385   virtual pos_type seekpos(pos_type pos, 
00386                            openmode mode = in|out)
00387   {
00388     if (!mode) {}       // Quench "unused parameter" warning
00389     return AdjustEOF(m_Obj.cseek(pos, PGSTD::ios::beg));
00390   }
00391 
00392   virtual int_type overflow(int_type ch = EoF())
00393   {
00394     char *const pp = pptr();
00395     if (!pp) return EoF();
00396     char *const pb = pbase();
00397     int_type result = 0;
00398 
00399     if (pp > pb) result = AdjustEOF(m_Obj.cwrite(pb, pp-pb));
00400     setp(m_P, m_P + m_BufSize);
00401 
00402     // Write that one more character, if it's there.
00403     if (ch != EoF())
00404     {
00405       *pptr() = char(ch);
00406       pbump(1);
00407     }
00408     return result;
00409   }
00410 
00411   virtual int_type underflow()
00412   {
00413     if (!gptr()) return EoF();
00414     char *const eb = eback();
00415     const int result = AdjustEOF(m_Obj.cread(eback(), m_BufSize));
00416     setg(eb, eb, eb + ((result==EoF()) ? 0 : result));
00417     return (!result || (result == EoF())) ? EoF() : *eb;
00418   }
00419 
00420 private:
00422   static int_type EoF() { return traits_type::eof(); }
00423 
00425   static PGSTD::streampos AdjustEOF(int pos)
00426   {
00427     return (pos == -1) ? EoF() : pos;
00428   }
00429 
00430   void initialize(openmode mode)
00431   {
00432     if (mode & PGSTD::ios::in) 
00433     {
00434       m_G = new char_type[m_BufSize];
00435       setg(m_G, m_G, m_G);
00436     }
00437     if (mode & PGSTD::ios::out)
00438     {
00439       m_P = new char_type[m_BufSize];
00440       setp(m_P, m_P + m_BufSize);
00441     }
00442   }
00443 
00444   const size_type m_BufSize;
00445   largeobjectaccess m_Obj;
00446 
00447   // Get & put buffers
00448   char_type *m_G, *m_P;
00449 };
00450 
00451 
00453 
00461 template<typename CHAR=char, typename TRAITS=PGSTD::char_traits<CHAR> > 
00462   class PQXX_LIBEXPORT basic_ilostream :
00463 #ifdef HAVE_STREAMBUF
00464     public PGSTD::basic_istream<CHAR, TRAITS>
00465 #else
00466     public PGSTD::istream
00467 #endif
00468 {
00469 #ifdef HAVE_STREAMBUF
00470   typedef PGSTD::basic_istream<CHAR, TRAITS> super;
00471 #else
00472   typedef PGSTD::istream super;
00473 #endif
00474 
00475 public:
00476   typedef CHAR char_type;
00477   typedef TRAITS traits_type;
00478   typedef typename traits_type::int_type int_type;
00479   typedef typename traits_type::pos_type pos_type;
00480   typedef typename traits_type::off_type off_type;
00481 
00483 
00487   basic_ilostream(dbtransaction &T, 
00488                   largeobject O, 
00489                   largeobject::size_type BufSize=512) :                 //[]
00490     super(m_Buf),
00491     m_Buf(T, O, in, BufSize) 
00492   { 
00493   }
00494 
00496 
00500   basic_ilostream(dbtransaction &T, 
00501                   oid O, 
00502                   largeobject::size_type BufSize=512) :                 //[t48]
00503     super(&m_Buf),
00504     m_Buf(T, O, in, BufSize) 
00505   { 
00506   }
00507 
00508 private:
00509   largeobject_streambuf<CHAR,TRAITS> m_Buf;
00510 };
00511 
00512 typedef basic_ilostream<char> ilostream;
00513 
00514 
00516 
00524 template<typename CHAR=char, typename TRAITS=PGSTD::char_traits<CHAR> > 
00525   class PQXX_LIBEXPORT basic_olostream : 
00526 #ifdef HAVE_STREAMBUF
00527     public PGSTD::basic_ostream<CHAR, TRAITS>
00528 #else
00529     public PGSTD::ostream
00530 #endif
00531 {
00532 #ifdef HAVE_STREAMBUF
00533   typedef PGSTD::basic_ostream<CHAR, TRAITS> super;
00534 #else
00535   typedef PGSTD::ostream super;
00536 #endif
00537 public:
00538   typedef CHAR char_type;
00539   typedef TRAITS traits_type;
00540   typedef typename traits_type::int_type int_type;
00541   typedef typename traits_type::pos_type pos_type;
00542   typedef typename traits_type::off_type off_type;
00543 
00545 
00549   basic_olostream(dbtransaction &T, 
00550                   largeobject O,
00551                   largeobject::size_type BufSize=512) :                 //[t48]
00552     super(&m_Buf),
00553     m_Buf(T, O, out, BufSize) 
00554   { 
00555   }
00556 
00558 
00562   basic_olostream(dbtransaction &T, 
00563                   oid O,
00564                   largeobject::size_type BufSize=512) :                 //[]
00565     super(&m_Buf),
00566     m_Buf(T, O, out, BufSize) 
00567   { 
00568   }
00569 
00570   ~basic_olostream() 
00571   { 
00572 #ifdef HAVE_STREAMBUF
00573     m_Buf.pubsync(); m_Buf.pubsync(); 
00574 #else
00575     m_Buf.sync(); m_Buf.sync();
00576 #endif
00577   }
00578 
00579 private:
00580   largeobject_streambuf<CHAR,TRAITS> m_Buf;
00581 };
00582 
00583 typedef basic_olostream<char> olostream;
00584 
00585 
00587 
00595 template<typename CHAR=char, typename TRAITS=PGSTD::char_traits<CHAR> > 
00596   class PQXX_LIBEXPORT basic_lostream :
00597 #ifdef HAVE_STREAMBUF
00598     public PGSTD::basic_iostream<CHAR, TRAITS>
00599 #else
00600     public PGSTD::iostream
00601 #endif
00602 {
00603 #ifdef HAVE_STREAMBUF
00604   typedef PGSTD::basic_iostream<CHAR, TRAITS> super;
00605 #else
00606   typedef PGSTD::iostream super;
00607 #endif
00608 
00609 public:
00610   typedef CHAR char_type;
00611   typedef TRAITS traits_type;
00612   typedef typename traits_type::int_type int_type;
00613   typedef typename traits_type::pos_type pos_type;
00614   typedef typename traits_type::off_type off_type;
00615 
00617 
00621   basic_lostream(dbtransaction &T, 
00622                  largeobject O,
00623                  largeobject::size_type BufSize=512) :                  //[]
00624     super(&m_Buf),
00625     m_Buf(T, O, in | out, BufSize) 
00626   { 
00627   }
00628 
00630 
00634   basic_lostream(dbtransaction &T, 
00635                  oid O,
00636                  largeobject::size_type BufSize=512) :                  //[]
00637     super(&m_Buf),
00638     m_Buf(T, O, in | out, BufSize) 
00639   { 
00640   }
00641 
00642   ~basic_lostream() 
00643   { 
00644 #ifdef HAVE_STREAMBUF
00645     m_Buf.pubsync(); m_Buf.pubsync(); 
00646 #else
00647     m_Buf.sync(); m_Buf.sync();
00648 #endif
00649   }
00650 
00651 private:
00652   largeobject_streambuf<CHAR,TRAITS> m_Buf;
00653 };
00654 
00655 typedef basic_lostream<char> lostream;
00656 
00657 }
00658 
00659 #endif
00660 

Generated on Sat Jun 7 00:49:34 2003 for libpqxx by doxygen1.3-rc3