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

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  *-------------------------------------------------------------------------
00013  */
00014 #ifndef PQXX_LARGEOBJECT_H
00015 #define PQXX_LARGEOBJECT_H
00016 
00017 #include <streambuf>
00018 
00019 #include <pqxx/transactionitf.h>
00020 
00021 
00022 namespace pqxx
00023 {
00024 
00025 class LargeObjectAccess;
00026 
00027 
00029 
00036 class LargeObject
00037 {
00038 public:
00039   typedef long size_type;
00040 
00042   LargeObject();                                                        //[t48]
00043 
00045 
00047   explicit LargeObject(TransactionItf &T);                              //[t48]
00048 
00050 
00054   explicit LargeObject(Oid O) : m_ID(O) {}                              //[t48]
00055 
00057 
00061   LargeObject(TransactionItf &T, const PGSTD::string &File);            //[]
00062 
00064 
00068   LargeObject(const LargeObjectAccess &O);                              //[t50]
00069 
00071 
00074   Oid id() const throw () { return m_ID; }                              //[t48]
00075 
00077   bool operator==(const LargeObject &other) const                       //[t51]
00078           { return m_ID == other.m_ID; }
00080   bool operator!=(const LargeObject &other) const                       //[t51]
00081           { return m_ID != other.m_ID; }
00083   bool operator<=(const LargeObject &other) const                       //[t51]
00084           { return m_ID <= other.m_ID; }
00086   bool operator>=(const LargeObject &other) const                       //[t51]
00087           { return m_ID >= other.m_ID; }
00089   bool operator<(const LargeObject &other) const                        //[t51]
00090           { return m_ID < other.m_ID; }
00092   bool operator>(const LargeObject &other) const                        //[t51]
00093           { return m_ID > other.m_ID; }
00094 
00096 
00100   void to_file(TransactionItf &T, const char File[]) const;             //[]
00101 
00103 
00107   void to_file(TransactionItf &T, const PGSTD::string &File) const      //[]
00108   { 
00109     to_file(T, File.c_str()); 
00110   }
00111 
00113 
00117   void remove(TransactionItf &T) const;                                 //[t48]
00118 
00119 protected:
00120   static PGconn *RawConnection(const TransactionItf &T)
00121   {
00122     return T.Conn().RawConnection();
00123   }
00124 
00125   PGSTD::string Reason() const;
00126 
00127 private:
00128   Oid m_ID;
00129 };
00130 
00131 
00133 class LargeObjectAccess : private LargeObject
00134 {
00135 public:
00136   using LargeObject::size_type;
00137 
00139 
00143   explicit LargeObjectAccess(TransactionItf &T, 
00144                              PGSTD::ios_base::openmode mode = 
00145                                 PGSTD::ios_base::in | 
00146                                 PGSTD::ios_base::out);                  //[t51]
00147 
00149 
00155   explicit LargeObjectAccess(TransactionItf &T, 
00156                              Oid O,
00157                              PGSTD::ios_base::openmode mode = 
00158                                 PGSTD::ios_base::in | 
00159                                 PGSTD::ios_base::out);                  //[]
00160 
00162 
00167   LargeObjectAccess(TransactionItf &T, 
00168                     LargeObject O,
00169                     PGSTD::ios_base::openmode mode = 
00170                                 PGSTD::ios_base::in | 
00171                                 PGSTD::ios_base::out);                  //[t50]
00172 
00174 
00179   LargeObjectAccess(TransactionItf &T, 
00180                     const PGSTD::string &File,
00181                     PGSTD::ios_base::openmode mode = 
00182                         PGSTD::ios_base::in | PGSTD::ios_base::out);    //[]
00183 
00184   ~LargeObjectAccess() { close(); }
00185 
00187 
00190   using LargeObject::id;
00191 
00193 
00196   void to_file(const char File[]) const                                 //[]
00197   { 
00198     LargeObject::to_file(m_Trans, File); 
00199   }
00200 
00202 
00205   void to_file(const PGSTD::string &File) const                         //[]
00206   { 
00207     LargeObject::to_file(m_Trans, File); 
00208   }
00209 
00211 
00215   void write(const char Buf[], size_type Len);                          //[]
00216 
00218 
00221   void write(const PGSTD::string &Buf)                                  //[t50]
00222         { write(Buf.c_str(), Buf.size()); }
00223 
00225 
00231   size_type read(char Buf[], size_type Len);                            //[t50]
00232 
00234 
00237   size_type seek(size_type dest, PGSTD::ios_base::seekdir dir);         //[t51]
00238 
00240 
00248   long cseek(long dest, PGSTD::ios_base::seekdir dir) throw ();         //[t50]
00249     
00251 
00257   long cwrite(const char Buf[], size_type Len) throw ();                //[t50]
00258 
00260 
00266   long cread(char Buf[], size_type Len) throw ();                       //[t50]
00267 
00268   using LargeObject::operator==;
00269   using LargeObject::operator!=;
00270   using LargeObject::operator<;
00271   using LargeObject::operator<=;
00272   using LargeObject::operator>;
00273   using LargeObject::operator>=;
00274 
00275 private:
00276   PGSTD::string Reason() const;
00277   PGconn *RawConnection() { return LargeObject::RawConnection(m_Trans); }
00278 
00279   void open(PGSTD::ios_base::openmode mode);
00280   void close();
00281 
00282   TransactionItf &m_Trans;
00283   int m_fd;
00284 
00285   // Not allowed:
00286   LargeObjectAccess();
00287   LargeObjectAccess(const LargeObjectAccess &);
00288   LargeObjectAccess operator=(const LargeObjectAccess &);
00289 };
00290 
00291 
00293 
00298 template<typename CHAR=char, typename TRAITS=PGSTD::char_traits<CHAR> >
00299 class largeobject_streambuf : public PGSTD::basic_streambuf<CHAR, TRAITS>
00300 {
00301   typedef long size_type;
00302 public:
00303   typedef CHAR   char_type;
00304   typedef TRAITS traits_type;
00305   typedef typename traits_type::int_type int_type;
00306   typedef typename traits_type::pos_type pos_type;
00307   typedef typename traits_type::off_type off_type;
00308 
00309   largeobject_streambuf(TransactionItf &T,
00310                         LargeObject O,
00311                         PGSTD::ios_base::openmode mode = 
00312                                 PGSTD::ios::in | PGSTD::ios::out,
00313                         size_type BufSize=512) :                        //[t48]
00314     m_BufSize(BufSize),
00315     m_Obj(T, O),
00316     m_G(0),
00317     m_P(0)
00318   {
00319     initialize(mode);
00320   }
00321 
00322   largeobject_streambuf(TransactionItf &T,
00323                         Oid O,
00324                         PGSTD::ios_base::openmode mode = 
00325                                 PGSTD::ios::in | PGSTD::ios::out,
00326                         size_type BufSize=512) :                        //[t48]
00327     m_BufSize(BufSize),
00328     m_Obj(T, O),
00329     m_G(0),
00330     m_P(0)
00331   {
00332     initialize(mode);
00333   }
00334 
00335   virtual ~largeobject_streambuf()
00336   {
00337     delete [] m_P;
00338     delete [] m_G;
00339   }
00340 
00341 
00342 protected:
00343   virtual int sync()
00344   {
00345     // setg() sets eback, gptr, egptr
00346     setg(eback(), eback(), egptr());
00347     return overflow(EoF());
00348   }
00349 
00350   virtual pos_type seekoff(off_type offset, 
00351                            PGSTD::ios_base::seekdir dir,
00352                            PGSTD::ios_base::openmode mode =
00353                                 PGSTD::ios_base::in|PGSTD::ios_base::out)
00354   {
00355     if (!mode) {}       // Quench "unused parameter" warning
00356     return AdjustEOF(m_Obj.cseek(offset, dir));
00357   }
00358 
00359   virtual pos_type seekpos(pos_type pos, 
00360                            PGSTD::ios_base::openmode mode =
00361                                 PGSTD::ios_base::in|PGSTD::ios_base::out)
00362   {
00363     if (!mode) {}       // Quench "unused parameter" warning
00364     return AdjustEOF(m_Obj.cseek(pos, PGSTD::ios_base::beg));
00365   }
00366 
00367   virtual int_type overflow(int_type ch = EoF())
00368   {
00369     char *const pp = pptr();
00370     if (!pp) return EoF();
00371     char *const pb = pbase();
00372     int_type result = 0;
00373 
00374     if (pp > pb) result = AdjustEOF(m_Obj.cwrite(pb, pp-pb));
00375     setp(m_P, m_P + m_BufSize);
00376 
00377     // Write that one more character, if it's there.
00378     if (ch != EoF())
00379     {
00380       *pptr() = char(ch);
00381       pbump(1);
00382     }
00383     return result;
00384   }
00385 
00386   virtual int_type underflow()
00387   {
00388     if (!gptr()) return EoF();
00389     char *const eb = eback();
00390     const int result = AdjustEOF(m_Obj.cread(eback(), m_BufSize));
00391     setg(eb, eb, eb + ((result==EoF()) ? 0 : result));
00392     return (!result || (result == EoF())) ? EoF() : *eb;
00393   }
00394 
00395 private:
00397   static int_type EoF() { return traits_type::eof(); }
00398 
00400   static PGSTD::streampos AdjustEOF(int pos)
00401   {
00402     return (pos == -1) ? EoF() : pos;
00403   }
00404 
00405   void initialize(PGSTD::ios_base::openmode mode)
00406   {
00407     if (mode & PGSTD::ios_base::in) 
00408     {
00409       m_G = new char_type[m_BufSize];
00410       setg(m_G, m_G, m_G);
00411     }
00412     if (mode & PGSTD::ios_base::out)
00413     {
00414       m_P = new char_type[m_BufSize];
00415       setp(m_P, m_P + m_BufSize);
00416     }
00417   }
00418 
00419   const size_type m_BufSize;
00420   LargeObjectAccess m_Obj;
00421 
00422   // Get & put buffers
00423   char_type *m_G, *m_P;
00424 };
00425 
00426 
00428 
00435 template<typename CHAR=char, typename TRAITS=PGSTD::char_traits<CHAR> > 
00436 class basic_ilostream : public PGSTD::basic_istream<CHAR, TRAITS>
00437 {
00438 public:
00439   typedef CHAR char_type;
00440   typedef TRAITS traits_type;
00441   typedef typename traits_type::int_type int_type;
00442   typedef typename traits_type::pos_type pos_type;
00443   typedef typename traits_type::off_type off_type;
00444 
00446 
00450   basic_ilostream(TransactionItf &T, 
00451                   LargeObject O, 
00452                   LargeObject::size_type BufSize=512) :                 //[]
00453     PGSTD::basic_istream<CHAR,TRAITS>(&m_Buf),
00454     m_Buf(T, O, in, BufSize) 
00455   { 
00456   }
00457 
00459 
00463   basic_ilostream(TransactionItf &T, 
00464                   Oid O, 
00465                   LargeObject::size_type BufSize=512) :                 //[t48]
00466     PGSTD::basic_istream<CHAR,TRAITS>(&m_Buf),
00467     m_Buf(T, O, in, BufSize) 
00468   { 
00469   }
00470 
00471 private:
00472   largeobject_streambuf<CHAR,TRAITS> m_Buf;
00473 };
00474 
00475 typedef basic_ilostream<char> ilostream;
00476 
00477 
00479 
00486 template<typename CHAR=char, typename TRAITS=PGSTD::char_traits<CHAR> > 
00487 class basic_olostream : public PGSTD::basic_ostream<CHAR, TRAITS>
00488 {
00489 public:
00490   typedef CHAR char_type;
00491   typedef TRAITS traits_type;
00492   typedef typename traits_type::int_type int_type;
00493   typedef typename traits_type::pos_type pos_type;
00494   typedef typename traits_type::off_type off_type;
00495 
00497 
00501   basic_olostream(TransactionItf &T, 
00502                   LargeObject O,
00503                   LargeObject::size_type BufSize=512) :                 //[t48]
00504     PGSTD::basic_ostream<CHAR,TRAITS>(&m_Buf),
00505     m_Buf(T, O, out, BufSize) 
00506   { 
00507   }
00508 
00510 
00514   basic_olostream(TransactionItf &T, 
00515                   Oid O,
00516                   LargeObject::size_type BufSize=512) :                 //[]
00517     PGSTD::basic_ostream<CHAR,TRAITS>(&m_Buf),
00518     m_Buf(T, O, out, BufSize) 
00519   { 
00520   }
00521 
00522   ~basic_olostream() { m_Buf.pubsync(); m_Buf.pubsync(); }
00523 
00524 private:
00525   largeobject_streambuf<CHAR,TRAITS> m_Buf;
00526 };
00527 
00528 typedef basic_olostream<char> olostream;
00529 
00530 
00532 
00539 template<typename CHAR=char, typename TRAITS=PGSTD::char_traits<CHAR> > 
00540 class basic_lostream : public PGSTD::basic_iostream<CHAR, TRAITS>
00541 {
00542 public:
00543   typedef CHAR char_type;
00544   typedef TRAITS traits_type;
00545   typedef typename traits_type::int_type int_type;
00546   typedef typename traits_type::pos_type pos_type;
00547   typedef typename traits_type::off_type off_type;
00548 
00550 
00554   basic_lostream(TransactionItf &T, 
00555                  LargeObject O,
00556                  LargeObject::size_type BufSize=512) :                  //[]
00557     PGSTD::basic_iostream<CHAR,TRAITS>(&m_Buf),
00558     m_Buf(T, O, in | out, BufSize) 
00559   { 
00560   }
00561 
00563 
00567   basic_lostream(TransactionItf &T, 
00568                  Oid O,
00569                  LargeObject::size_type BufSize=512) :                  //[]
00570     PGSTD::basic_iostream<CHAR,TRAITS>(&m_Buf),
00571     m_Buf(T, O, in | out, BufSize) 
00572   { 
00573   }
00574 
00575   ~basic_lostream() { m_Buf.pubsync(); m_Buf.pubsync(); }
00576 
00577 private:
00578   largeobject_streambuf<CHAR,TRAITS> m_Buf;
00579 };
00580 
00581 typedef basic_lostream<char> lostream;
00582 
00583 }
00584 
00585 #endif
00586 

Generated on Sat Mar 29 21:51:03 2003 for libpqxx by doxygen1.3-rc3