00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "pqxx/compiler-public.hxx"
00020 #include "pqxx/compiler-internal-pre.hxx"
00021
00022 #ifdef PQXX_HAVE_STREAMBUF
00023 #include <streambuf>
00024 #else
00025 #include <streambuf.h>
00026 #endif
00027
00028 #include "pqxx/dbtransaction"
00029
00030
00031 namespace pqxx
00032 {
00033
00034 class largeobjectaccess;
00035
00037
00044 class PQXX_LIBEXPORT largeobject
00045 {
00046 public:
00047 typedef long size_type;
00048
00050 largeobject() throw ();
00051
00053
00055 explicit largeobject(dbtransaction &T);
00056
00058
00062 explicit largeobject(oid O) throw () : m_ID(O) {}
00063
00065
00069 largeobject(dbtransaction &T, const PGSTD::string &File);
00070
00072
00076 largeobject(const largeobjectaccess &O) throw ();
00077
00079
00083 oid id() const throw () { return m_ID; }
00084
00093
00094
00095 bool operator==(const largeobject &other) const
00096 { return m_ID == other.m_ID; }
00098
00099 bool operator!=(const largeobject &other) const
00100 { return m_ID != other.m_ID; }
00102
00103 bool operator<=(const largeobject &other) const
00104 { return m_ID <= other.m_ID; }
00106
00107 bool operator>=(const largeobject &other) const
00108 { return m_ID >= other.m_ID; }
00110
00111 bool operator<(const largeobject &other) const
00112 { return m_ID < other.m_ID; }
00114
00115 bool operator>(const largeobject &other) const
00116 { return m_ID > other.m_ID; }
00118
00120
00124 void to_file(dbtransaction &T, const PGSTD::string &File) const;
00125
00127
00131 void remove(dbtransaction &T) const;
00132
00133 protected:
00134 static internal::pq::PGconn *RawConnection(const dbtransaction &T)
00135 {
00136 return T.conn().RawConnection();
00137 }
00138
00139 PGSTD::string Reason(int err) const;
00140
00141 private:
00142 oid m_ID;
00143 };
00144
00145
00146
00147
00149 class PQXX_LIBEXPORT largeobjectaccess : private largeobject
00150 {
00151 public:
00152 using largeobject::size_type;
00153 typedef long off_type;
00154 typedef size_type pos_type;
00155
00157
00161 typedef PGSTD::ios::openmode openmode;
00162
00164
00168 typedef PGSTD::ios::seekdir seekdir;
00169
00171
00175 explicit largeobjectaccess(dbtransaction &T,
00176 openmode mode =
00177 PGSTD::ios::in |
00178 PGSTD::ios::out);
00179
00181
00187 largeobjectaccess(dbtransaction &T,
00188 oid O,
00189 openmode mode =
00190 PGSTD::ios::in |
00191 PGSTD::ios::out);
00192
00194
00199 largeobjectaccess(dbtransaction &T,
00200 largeobject O,
00201 openmode mode = PGSTD::ios::in | PGSTD::ios::out);
00202
00204
00209 largeobjectaccess(dbtransaction &T,
00210 const PGSTD::string &File,
00211 openmode mode =
00212 PGSTD::ios::in | PGSTD::ios::out);
00213
00214 ~largeobjectaccess() throw () { close(); }
00215
00217
00220 using largeobject::id;
00221
00223
00226 void to_file(const PGSTD::string &File) const
00227 { largeobject::to_file(m_Trans, File); }
00228
00229 #ifdef PQXX_BROKEN_USING_DECL
00231
00235 void to_file(dbtransaction &T, const PGSTD::string &F) const
00236 { largeobject::to_file(T, F); }
00237 #else
00238 using largeobject::to_file;
00239 #endif
00240
00245
00246
00250 void write(const char Buf[], size_type Len);
00251
00253
00256 void write(const PGSTD::string &Buf)
00257 { write(Buf.c_str(), static_cast<size_type>(Buf.size())); }
00258
00260
00266 size_type read(char Buf[], size_type Len);
00267
00269
00272 size_type seek(size_type dest, seekdir dir);
00273
00275
00278 size_type tell() const;
00280
00290
00291
00299 pos_type cseek(off_type dest, seekdir dir) throw ();
00300
00302
00308 off_type cwrite(const char Buf[], size_type Len) throw ();
00309
00311
00317 off_type cread(char Buf[], size_type Len) throw ();
00318
00320
00324 pos_type ctell() const throw ();
00326
00331
00332 void process_notice(const PGSTD::string &) throw ();
00334
00335 using largeobject::remove;
00336
00337 using largeobject::operator==;
00338 using largeobject::operator!=;
00339 using largeobject::operator<;
00340 using largeobject::operator<=;
00341 using largeobject::operator>;
00342 using largeobject::operator>=;
00343
00344 private:
00345 PGSTD::string PQXX_PRIVATE Reason(int err) const;
00346 internal::pq::PGconn *RawConnection() const
00347 { return largeobject::RawConnection(m_Trans); }
00348
00349 void open(openmode mode);
00350 void close() throw ();
00351
00352 dbtransaction &m_Trans;
00353 int m_fd;
00354
00355
00356 largeobjectaccess();
00357 largeobjectaccess(const largeobjectaccess &);
00358 largeobjectaccess operator=(const largeobjectaccess &);
00359 };
00360
00361
00363
00371 template<typename CHAR=char, typename TRAITS=PGSTD::char_traits<CHAR> >
00372 class largeobject_streambuf :
00373 #ifdef PQXX_HAVE_STREAMBUF
00374 public PGSTD::basic_streambuf<CHAR, TRAITS>
00375 #else
00376 public PGSTD::streambuf
00377 #endif
00378 {
00379 typedef long size_type;
00380 public:
00381 typedef CHAR char_type;
00382 typedef TRAITS traits_type;
00383 typedef typename traits_type::int_type int_type;
00384 #ifdef PQXX_HAVE_STREAMBUF
00385 typedef typename traits_type::pos_type pos_type;
00386 typedef typename traits_type::off_type off_type;
00387 #else
00388 typedef streamoff off_type;
00389 typedef streampos pos_type;
00390 #endif
00391 typedef largeobjectaccess::openmode openmode;
00392 typedef largeobjectaccess::seekdir seekdir;
00393
00394 largeobject_streambuf(dbtransaction &T,
00395 largeobject O,
00396 openmode mode = PGSTD::ios::in | PGSTD::ios::out,
00397 size_type BufSize=512) :
00398 m_BufSize(BufSize),
00399 m_Obj(T, O),
00400 m_G(0),
00401 m_P(0)
00402 { initialize(mode); }
00403
00404 largeobject_streambuf(dbtransaction &T,
00405 oid O,
00406 openmode mode = PGSTD::ios::in | PGSTD::ios::out,
00407 size_type BufSize=512) :
00408 m_BufSize(BufSize),
00409 m_Obj(T, O),
00410 m_G(0),
00411 m_P(0)
00412 { initialize(mode); }
00413
00414 virtual ~largeobject_streambuf() throw () { delete [] m_P; delete [] m_G; }
00415
00416
00418 void process_notice(const PGSTD::string &s) { m_Obj.process_notice(s); }
00419
00420 #ifdef PQXX_HAVE_STREAMBUF
00421 protected:
00422 #endif
00423 virtual int sync()
00424 {
00425
00426 setg(this->eback(), this->eback(), this->egptr());
00427 return overflow(EoF());
00428 }
00429
00430 protected:
00431 virtual pos_type seekoff(off_type offset,
00432 seekdir dir,
00433 openmode)
00434 { return AdjustEOF(m_Obj.cseek(offset, dir)); }
00435
00436 virtual pos_type seekpos(pos_type pos, openmode)
00437 { return AdjustEOF(m_Obj.cseek(pos, PGSTD::ios::beg)); }
00438
00439 virtual int_type overflow(int_type ch = EoF())
00440 {
00441 char *const pp = this->pptr();
00442 if (!pp) return EoF();
00443 char *const pb = this->pbase();
00444 int_type res = 0;
00445
00446 if (pp > pb) res = AdjustEOF(m_Obj.cwrite(pb, pp-pb));
00447 setp(m_P, m_P + m_BufSize);
00448
00449
00450 if (ch != EoF())
00451 {
00452 *this->pptr() = char(ch);
00453 this->pbump(1);
00454 }
00455 return res;
00456 }
00457
00458 virtual int_type underflow()
00459 {
00460 if (!this->gptr()) return EoF();
00461 char *const eb = this->eback();
00462 const int res = AdjustEOF(m_Obj.cread(this->eback(), m_BufSize));
00463 setg(eb, eb, eb + ((res==EoF()) ? 0 : res));
00464 return (!res || (res == EoF())) ? EoF() : *eb;
00465 }
00466
00467 private:
00469 static int_type EoF() { return traits_type::eof(); }
00470
00472 static PGSTD::streampos AdjustEOF(int pos) { return (pos==-1) ? EoF() : pos; }
00473
00474 void initialize(openmode mode)
00475 {
00476 if (mode & PGSTD::ios::in)
00477 {
00478 m_G = new char_type[m_BufSize];
00479 setg(m_G, m_G, m_G);
00480 }
00481 if (mode & PGSTD::ios::out)
00482 {
00483 m_P = new char_type[m_BufSize];
00484 setp(m_P, m_P + m_BufSize);
00485 }
00486 }
00487
00488 const size_type m_BufSize;
00489 largeobjectaccess m_Obj;
00490
00491
00492 char_type *m_G, *m_P;
00493 };
00494
00495
00497
00505 template<typename CHAR=char, typename TRAITS=PGSTD::char_traits<CHAR> >
00506 class basic_ilostream :
00507 #ifdef PQXX_HAVE_STREAMBUF
00508 public PGSTD::basic_istream<CHAR, TRAITS>
00509 #else
00510 public PGSTD::istream
00511 #endif
00512 {
00513 #ifdef PQXX_HAVE_STREAMBUF
00514 typedef PGSTD::basic_istream<CHAR, TRAITS> super;
00515 #else
00516 typedef PGSTD::istream super;
00517 #endif
00518
00519 public:
00520 typedef CHAR char_type;
00521 typedef TRAITS traits_type;
00522 typedef typename traits_type::int_type int_type;
00523 typedef typename traits_type::pos_type pos_type;
00524 typedef typename traits_type::off_type off_type;
00525
00527
00532 basic_ilostream(dbtransaction &T,
00533 largeobject O,
00534 largeobject::size_type BufSize=512) :
00535 super(0),
00536 m_Buf(T, O, PGSTD::ios::in, BufSize)
00537 { super::init(&m_Buf); }
00538
00540
00545 basic_ilostream(dbtransaction &T,
00546 oid O,
00547 largeobject::size_type BufSize=512) :
00548 super(0),
00549 m_Buf(T, O, PGSTD::ios::in, BufSize)
00550 { super::init(&m_Buf); }
00551
00552 private:
00553 largeobject_streambuf<CHAR,TRAITS> m_Buf;
00554 };
00555
00556 typedef basic_ilostream<char> ilostream;
00557
00558
00560
00568 template<typename CHAR=char, typename TRAITS=PGSTD::char_traits<CHAR> >
00569 class basic_olostream :
00570 #ifdef PQXX_HAVE_STREAMBUF
00571 public PGSTD::basic_ostream<CHAR, TRAITS>
00572 #else
00573 public PGSTD::ostream
00574 #endif
00575 {
00576 #ifdef PQXX_HAVE_STREAMBUF
00577 typedef PGSTD::basic_ostream<CHAR, TRAITS> super;
00578 #else
00579 typedef PGSTD::ostream super;
00580 #endif
00581 public:
00582 typedef CHAR char_type;
00583 typedef TRAITS traits_type;
00584 typedef typename traits_type::int_type int_type;
00585 typedef typename traits_type::pos_type pos_type;
00586 typedef typename traits_type::off_type off_type;
00587
00589
00594 basic_olostream(dbtransaction &T,
00595 largeobject O,
00596 largeobject::size_type BufSize=512) :
00597 super(0),
00598 m_Buf(T, O, PGSTD::ios::out, BufSize)
00599 { super::init(&m_Buf); }
00600
00602
00607 basic_olostream(dbtransaction &T,
00608 oid O,
00609 largeobject::size_type BufSize=512) :
00610 super(0),
00611 m_Buf(T, O, PGSTD::ios::out, BufSize)
00612 { super::init(&m_Buf); }
00613
00614 ~basic_olostream()
00615 {
00616 try
00617 {
00618 #ifdef PQXX_HAVE_STREAMBUF
00619 m_Buf.pubsync(); m_Buf.pubsync();
00620 #else
00621 m_Buf.sync(); m_Buf.sync();
00622 #endif
00623 }
00624 catch (const PGSTD::exception &e)
00625 {
00626 m_Buf.process_notice(e.what());
00627 }
00628 }
00629
00630 private:
00631 largeobject_streambuf<CHAR,TRAITS> m_Buf;
00632 };
00633
00634 typedef basic_olostream<char> olostream;
00635
00636
00638
00646 template<typename CHAR=char, typename TRAITS=PGSTD::char_traits<CHAR> >
00647 class basic_lostream :
00648 #ifdef PQXX_HAVE_STREAMBUF
00649 public PGSTD::basic_iostream<CHAR, TRAITS>
00650 #else
00651 public PGSTD::iostream
00652 #endif
00653 {
00654 #ifdef PQXX_HAVE_STREAMBUF
00655 typedef PGSTD::basic_iostream<CHAR, TRAITS> super;
00656 #else
00657 typedef PGSTD::iostream super;
00658 #endif
00659
00660 public:
00661 typedef CHAR char_type;
00662 typedef TRAITS traits_type;
00663 typedef typename traits_type::int_type int_type;
00664 typedef typename traits_type::pos_type pos_type;
00665 typedef typename traits_type::off_type off_type;
00666
00668
00673 basic_lostream(dbtransaction &T,
00674 largeobject O,
00675 largeobject::size_type BufSize=512) :
00676 super(0),
00677 m_Buf(T, O, PGSTD::ios::in | PGSTD::ios::out, BufSize)
00678 { super::init(&m_Buf); }
00679
00681
00686 basic_lostream(dbtransaction &T,
00687 oid O,
00688 largeobject::size_type BufSize=512) :
00689 super(0),
00690 m_Buf(T, O, PGSTD::ios::in | PGSTD::ios::out, BufSize)
00691 { super::init(&m_Buf); }
00692
00693 ~basic_lostream()
00694 {
00695 try
00696 {
00697 #ifdef PQXX_HAVE_STREAMBUF
00698 m_Buf.pubsync(); m_Buf.pubsync();
00699 #else
00700 m_Buf.sync(); m_Buf.sync();
00701 #endif
00702 }
00703 catch (const PGSTD::exception &e)
00704 {
00705 m_Buf.process_notice(e.what());
00706 }
00707 }
00708
00709 private:
00710 largeobject_streambuf<CHAR,TRAITS> m_Buf;
00711 };
00712
00713 typedef basic_lostream<char> lostream;
00714
00715 }
00716
00717 #include "pqxx/compiler-internal-post.hxx"