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  *-------------------------------------------------------------------------
00013  */
00014 #ifndef PQXX_LARGEOBJECT_H
00015 #define PQXX_LARGEOBJECT_H
00016 
00017 #include <pqxx/config.h>
00018 
00019 #ifdef HAVE_STREAMBUF
00020 #include <streambuf>
00021 #else
00022 #include <streambuf.h>
00023 #endif
00024 
00025 #include <pqxx/transaction_base.h>
00026 
00027 
00028 namespace pqxx
00029 {
00030 
00031 class LargeObjectAccess;
00032 
00033 
00035 
00042 class LargeObject
00043 {
00044 public:
00045   typedef long size_type;
00046 
00048   LargeObject();                                                        //[t48]
00049 
00051 
00053   explicit LargeObject(Transaction_base &T);                            //[t48]
00054 
00056 
00060   explicit LargeObject(Oid O) : m_ID(O) {}                              //[t48]
00061 
00063 
00067   LargeObject(Transaction_base &T, const PGSTD::string &File);          //[t53]
00068 
00070 
00074   LargeObject(const LargeObjectAccess &O);                              //[t50]
00075 
00077 
00080   Oid id() const throw () { return m_ID; }                              //[t48]
00081 
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; }
00095   bool operator<(const LargeObject &other) const                        //[t51]
00096           { return m_ID < other.m_ID; }
00098   bool operator>(const LargeObject &other) const                        //[t51]
00099           { return m_ID > other.m_ID; }
00100 
00102 
00106   void to_file(Transaction_base &T, const PGSTD::string &File) const;   //[t52]
00107 
00109 
00113   void remove(Transaction_base &T) const;                               //[t48]
00114 
00115 protected:
00116   static PGconn *RawConnection(const Transaction_base &T)
00117   {
00118     return T.Conn().RawConnection();
00119   }
00120 
00121   PGSTD::string Reason() const;
00122 
00123 private:
00124   Oid m_ID;
00125 };
00126 
00127 
00129 class LargeObjectAccess : private LargeObject
00130 {
00131 public:
00132   using LargeObject::size_type;
00133 
00135 
00139   typedef PGSTD::ios::openmode openmode;
00140 
00142 
00146   typedef PGSTD::ios::seekdir seekdir;
00147 
00149 
00153   explicit LargeObjectAccess(Transaction_base &T, 
00154                              openmode mode = 
00155                                 PGSTD::ios::in | 
00156                                 PGSTD::ios::out);                       //[t51]
00157 
00159 
00165   LargeObjectAccess(Transaction_base &T, 
00166                     Oid O,
00167                     openmode mode = 
00168                         PGSTD::ios::in | 
00169                         PGSTD::ios::out);                               //[t52]
00170 
00172 
00177   LargeObjectAccess(Transaction_base &T, 
00178                     LargeObject O,
00179                     openmode mode = PGSTD::ios::in | PGSTD::ios::out);  //[t50]
00180 
00182 
00187   LargeObjectAccess(Transaction_base &T, 
00188                     const PGSTD::string &File,
00189                     openmode mode = 
00190                         PGSTD::ios::in | PGSTD::ios::out);              //[t55]
00191 
00192   ~LargeObjectAccess() { close(); }
00193 
00195 
00198   using LargeObject::id;
00199 
00201 
00204   void to_file(const PGSTD::string &File) const                         //[t54]
00205   { 
00206     LargeObject::to_file(m_Trans, File); 
00207   }
00208 
00210 
00214   void write(const char Buf[], size_type Len);                          //[t51]
00215 
00217 
00220   void write(const PGSTD::string &Buf)                                  //[t50]
00221         { write(Buf.c_str(), Buf.size()); }
00222 
00224 
00230   size_type read(char Buf[], size_type Len);                            //[t50]
00231 
00233 
00236   size_type seek(size_type dest, seekdir dir);                          //[t51]
00237 
00239 
00247   long cseek(long dest, seekdir dir) throw ();                          //[t50]
00248     
00250 
00256   long cwrite(const char Buf[], size_type Len) throw ();                //[t50]
00257 
00259 
00265   long cread(char Buf[], size_type Len) throw ();                       //[t50]
00266 
00267   using LargeObject::operator==;
00268   using LargeObject::operator!=;
00269   using LargeObject::operator<;
00270   using LargeObject::operator<=;
00271   using LargeObject::operator>;
00272   using LargeObject::operator>=;
00273 
00274 private:
00275   PGSTD::string Reason() const;
00276   PGconn *RawConnection() { return LargeObject::RawConnection(m_Trans); }
00277 
00278   void open(openmode mode);
00279   void close();
00280 
00281   Transaction_base &m_Trans;
00282   int m_fd;
00283 
00284   // Not allowed:
00285   LargeObjectAccess();
00286   LargeObjectAccess(const LargeObjectAccess &);
00287   LargeObjectAccess operator=(const LargeObjectAccess &);
00288 };
00289 
00290 
00292 
00297 template<typename CHAR=char, typename TRAITS=PGSTD::char_traits<CHAR> >
00298   class largeobject_streambuf :
00299 #ifdef HAVE_STREAMBUF
00300     public PGSTD::basic_streambuf<CHAR, TRAITS>
00301 #else
00302     public PGSTD::streambuf
00303 #endif
00304 {
00305   typedef long size_type;
00306 public:
00307   typedef CHAR   char_type;
00308   typedef TRAITS traits_type;
00309   typedef typename traits_type::int_type int_type;
00310   typedef typename traits_type::pos_type pos_type;
00311   typedef typename traits_type::off_type off_type;
00312   typedef LargeObjectAccess::openmode openmode;
00313   typedef LargeObjectAccess::seekdir seekdir;
00314 
00315   largeobject_streambuf(Transaction_base &T,
00316                         LargeObject O,
00317                         openmode mode = in | out,
00318                         size_type BufSize=512) :                        //[t48]
00319     m_BufSize(BufSize),
00320     m_Obj(T, O),
00321     m_G(0),
00322     m_P(0)
00323   {
00324     initialize(mode);
00325   }
00326 
00327   largeobject_streambuf(Transaction_base &T,
00328                         Oid O,
00329                         openmode mode = in | out,
00330                         size_type BufSize=512) :                        //[t48]
00331     m_BufSize(BufSize),
00332     m_Obj(T, O),
00333     m_G(0),
00334     m_P(0)
00335   {
00336     initialize(mode);
00337   }
00338 
00339   virtual ~largeobject_streambuf()
00340   {
00341     delete [] m_P;
00342     delete [] m_G;
00343   }
00344 
00345 
00346 #ifdef HAVE_STREAMBUF
00347 protected:
00348 #endif
00349   virtual int sync()
00350   {
00351     // setg() sets eback, gptr, egptr
00352     setg(eback(), eback(), egptr());
00353     return overflow(EoF());
00354   }
00355 
00356 protected:
00357   virtual pos_type seekoff(off_type offset, 
00358                            seekdir dir,
00359                            openmode mode = in|out)
00360   {
00361     if (!mode) {}       // Quench "unused parameter" warning
00362     return AdjustEOF(m_Obj.cseek(offset, dir));
00363   }
00364 
00365   virtual pos_type seekpos(pos_type pos, 
00366                            openmode mode = in|out)
00367   {
00368     if (!mode) {}       // Quench "unused parameter" warning
00369     return AdjustEOF(m_Obj.cseek(pos, PGSTD::ios::beg));
00370   }
00371 
00372   virtual int_type overflow(int_type ch = EoF())
00373   {
00374     char *const pp = pptr();
00375     if (!pp) return EoF();
00376     char *const pb = pbase();
00377     int_type result = 0;
00378 
00379     if (pp > pb) result = AdjustEOF(m_Obj.cwrite(pb, pp-pb));
00380     setp(m_P, m_P + m_BufSize);
00381 
00382     // Write that one more character, if it's there.
00383     if (ch != EoF())
00384     {
00385       *pptr() = char(ch);
00386       pbump(1);
00387     }
00388     return result;
00389   }
00390 
00391   virtual int_type underflow()
00392   {
00393     if (!gptr()) return EoF();
00394     char *const eb = eback();
00395     const int result = AdjustEOF(m_Obj.cread(eback(), m_BufSize));
00396     setg(eb, eb, eb + ((result==EoF()) ? 0 : result));
00397     return (!result || (result == EoF())) ? EoF() : *eb;
00398   }
00399 
00400 private:
00402   static int_type EoF() { return traits_type::eof(); }
00403 
00405   static PGSTD::streampos AdjustEOF(int pos)
00406   {
00407     return (pos == -1) ? EoF() : pos;
00408   }
00409 
00410   void initialize(openmode mode)
00411   {
00412     if (mode & PGSTD::ios::in) 
00413     {
00414       m_G = new char_type[m_BufSize];
00415       setg(m_G, m_G, m_G);
00416     }
00417     if (mode & PGSTD::ios::out)
00418     {
00419       m_P = new char_type[m_BufSize];
00420       setp(m_P, m_P + m_BufSize);
00421     }
00422   }
00423 
00424   const size_type m_BufSize;
00425   LargeObjectAccess m_Obj;
00426 
00427   // Get & put buffers
00428   char_type *m_G, *m_P;
00429 };
00430 
00431 
00433 
00440 template<typename CHAR=char, typename TRAITS=PGSTD::char_traits<CHAR> > 
00441   class basic_ilostream :
00442 #ifdef HAVE_STREAMBUF
00443     public PGSTD::basic_istream<CHAR, TRAITS>
00444 #else
00445     public PGSTD::istream
00446 #endif
00447 {
00448 #ifdef HAVE_STREAMBUF
00449   typedef PGSTD::basic_istream<CHAR, TRAITS> super;
00450 #else
00451   typedef PGSTD::istream super;
00452 #endif
00453 
00454 public:
00455   typedef CHAR char_type;
00456   typedef TRAITS traits_type;
00457   typedef typename traits_type::int_type int_type;
00458   typedef typename traits_type::pos_type pos_type;
00459   typedef typename traits_type::off_type off_type;
00460 
00462 
00466   basic_ilostream(Transaction_base &T, 
00467                   LargeObject O, 
00468                   LargeObject::size_type BufSize=512) :                 //[]
00469     super(m_Buf),
00470     m_Buf(T, O, in, BufSize) 
00471   { 
00472   }
00473 
00475 
00479   basic_ilostream(Transaction_base &T, 
00480                   Oid O, 
00481                   LargeObject::size_type BufSize=512) :                 //[t48]
00482     super(&m_Buf),
00483     m_Buf(T, O, in, BufSize) 
00484   { 
00485   }
00486 
00487 private:
00488   largeobject_streambuf<CHAR,TRAITS> m_Buf;
00489 };
00490 
00491 typedef basic_ilostream<char> ilostream;
00492 
00493 
00495 
00502 template<typename CHAR=char, typename TRAITS=PGSTD::char_traits<CHAR> > 
00503   class basic_olostream : 
00504 #ifdef HAVE_STREAMBUF
00505     public PGSTD::basic_ostream<CHAR, TRAITS>
00506 #else
00507     public PGSTD::ostream
00508 #endif
00509 {
00510 #ifdef HAVE_STREAMBUF
00511   typedef PGSTD::basic_ostream<CHAR, TRAITS> super;
00512 #else
00513   typedef PGSTD::ostream super;
00514 #endif
00515 public:
00516   typedef CHAR char_type;
00517   typedef TRAITS traits_type;
00518   typedef typename traits_type::int_type int_type;
00519   typedef typename traits_type::pos_type pos_type;
00520   typedef typename traits_type::off_type off_type;
00521 
00523 
00527   basic_olostream(Transaction_base &T, 
00528                   LargeObject O,
00529                   LargeObject::size_type BufSize=512) :                 //[t48]
00530     super(&m_Buf),
00531     m_Buf(T, O, out, BufSize) 
00532   { 
00533   }
00534 
00536 
00540   basic_olostream(Transaction_base &T, 
00541                   Oid O,
00542                   LargeObject::size_type BufSize=512) :                 //[]
00543     super(&m_Buf),
00544     m_Buf(T, O, out, BufSize) 
00545   { 
00546   }
00547 
00548   ~basic_olostream() 
00549   { 
00550 #ifdef HAVE_STREAMBUF
00551     m_Buf.pubsync(); m_Buf.pubsync(); 
00552 #else
00553     m_Buf.sync(); m_Buf.sync();
00554 #endif
00555   }
00556 
00557 private:
00558   largeobject_streambuf<CHAR,TRAITS> m_Buf;
00559 };
00560 
00561 typedef basic_olostream<char> olostream;
00562 
00563 
00565 
00572 template<typename CHAR=char, typename TRAITS=PGSTD::char_traits<CHAR> > 
00573   class basic_lostream :
00574 #ifdef HAVE_STREAMBUF
00575     public PGSTD::basic_iostream<CHAR, TRAITS>
00576 #else
00577     public PGSTD::iostream
00578 #endif
00579 {
00580 #ifdef HAVE_STREAMBUF
00581   typedef PGSTD::basic_iostream<CHAR, TRAITS> super;
00582 #else
00583   typedef PGSTD::iostream super;
00584 #endif
00585 
00586 public:
00587   typedef CHAR char_type;
00588   typedef TRAITS traits_type;
00589   typedef typename traits_type::int_type int_type;
00590   typedef typename traits_type::pos_type pos_type;
00591   typedef typename traits_type::off_type off_type;
00592 
00594 
00598   basic_lostream(Transaction_base &T, 
00599                  LargeObject O,
00600                  LargeObject::size_type BufSize=512) :                  //[]
00601     super(&m_Buf),
00602     m_Buf(T, O, in | out, BufSize) 
00603   { 
00604   }
00605 
00607 
00611   basic_lostream(Transaction_base &T, 
00612                  Oid O,
00613                  LargeObject::size_type BufSize=512) :                  //[]
00614     super(&m_Buf),
00615     m_Buf(T, O, in | out, BufSize) 
00616   { 
00617   }
00618 
00619   ~basic_lostream() 
00620   { 
00621 #ifdef HAVE_STREAMBUF
00622     m_Buf.pubsync(); m_Buf.pubsync(); 
00623 #else
00624     m_Buf.sync(); m_Buf.sync();
00625 #endif
00626   }
00627 
00628 private:
00629   largeobject_streambuf<CHAR,TRAITS> m_Buf;
00630 };
00631 
00632 typedef basic_lostream<char> lostream;
00633 
00634 }
00635 
00636 #endif
00637 

Generated on Sat May 24 02:03:11 2003 for libpqxx by doxygen1.3-rc3