00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "pqxx/libcompiler.h"
00020
00021 #include <new>
00022
00023 #ifdef PQXX_HAVE_STREAMBUF
00024 #include <streambuf>
00025 #else
00026 #include <streambuf.h>
00027 #endif
00028
00029 #include "pqxx/dbtransaction"
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();
00052
00054
00056 explicit largeobject(dbtransaction &T);
00057
00059
00063 explicit largeobject(oid O) : m_ID(O) {}
00064
00066
00070 largeobject(dbtransaction &T, const PGSTD::string &File);
00071
00073
00077 largeobject(const largeobjectaccess &O);
00078
00080
00084 oid id() const throw () { return m_ID; }
00085
00087 bool operator==(const largeobject &other) const
00088 { return m_ID == other.m_ID; }
00090 bool operator!=(const largeobject &other) const
00091 { return m_ID != other.m_ID; }
00093 bool operator<=(const largeobject &other) const
00094 { return m_ID <= other.m_ID; }
00096 bool operator>=(const largeobject &other) const
00097 { return m_ID >= other.m_ID; }
00099 bool operator<(const largeobject &other) const
00100 { return m_ID < other.m_ID; }
00102 bool operator>(const largeobject &other) const
00103 { return m_ID > other.m_ID; }
00104
00106
00110 void to_file(dbtransaction &T, const PGSTD::string &File) const;
00111
00113
00117 void remove(dbtransaction &T) const;
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
00131
00132
00133
00135 class PQXX_LIBEXPORT largeobjectaccess : private largeobject
00136 {
00137 public:
00138 using largeobject::size_type;
00139 typedef long off_type;
00140 typedef size_type pos_type;
00141
00143
00147 typedef PGSTD::ios::openmode openmode;
00148
00150
00154 typedef PGSTD::ios::seekdir seekdir;
00155
00157
00161 explicit largeobjectaccess(dbtransaction &T,
00162 openmode mode =
00163 PGSTD::ios::in |
00164 PGSTD::ios::out);
00165
00167
00173 largeobjectaccess(dbtransaction &T,
00174 oid O,
00175 openmode mode =
00176 PGSTD::ios::in |
00177 PGSTD::ios::out);
00178
00180
00185 largeobjectaccess(dbtransaction &T,
00186 largeobject O,
00187 openmode mode = PGSTD::ios::in | PGSTD::ios::out);
00188
00190
00195 largeobjectaccess(dbtransaction &T,
00196 const PGSTD::string &File,
00197 openmode mode =
00198 PGSTD::ios::in | PGSTD::ios::out);
00199
00200 ~largeobjectaccess() { close(); }
00201
00203
00206 using largeobject::id;
00207
00209
00212 void to_file(const PGSTD::string &File) const
00213 {
00214 largeobject::to_file(m_Trans, File);
00215 }
00216
00217 #ifdef PQXX_BROKEN_USING_DECL
00218
00219
00223 void to_file(dbtransaction &T, const PGSTD::string &F) const
00224 { largeobject::to_file(T, F); }
00225 #else
00226 using largeobject::to_file;
00227 #endif
00228
00229
00231
00235 void write(const char Buf[], size_type Len);
00236
00238
00241 void write(const PGSTD::string &Buf)
00242 { write(Buf.c_str(), Buf.size()); }
00243
00245
00251 size_type read(char Buf[], size_type Len);
00252
00254
00257 size_type seek(size_type dest, seekdir dir);
00258
00260
00268 pos_type cseek(off_type dest, seekdir dir) throw ();
00269
00271
00277 off_type cwrite(const char Buf[], size_type Len) throw ();
00278
00280
00286 off_type cread(char Buf[], size_type Len) throw ();
00287
00288 using largeobject::remove;
00289
00290 using largeobject::operator==;
00291 using largeobject::operator!=;
00292 using largeobject::operator<;
00293 using largeobject::operator<=;
00294 using largeobject::operator>;
00295 using largeobject::operator>=;
00296
00297 private:
00298 PGSTD::string Reason() const;
00299 PGconn *RawConnection() { return largeobject::RawConnection(m_Trans); }
00300
00301 void open(openmode mode);
00302 void close();
00303
00304 dbtransaction &m_Trans;
00305 int m_fd;
00306
00307
00308 largeobjectaccess();
00309 largeobjectaccess(const largeobjectaccess &);
00310 largeobjectaccess operator=(const largeobjectaccess &);
00311 };
00312
00313
00315
00323 template<typename CHAR=char, typename TRAITS=PGSTD::char_traits<CHAR> >
00324 class largeobject_streambuf :
00325 #ifdef PQXX_HAVE_STREAMBUF
00326 public PGSTD::basic_streambuf<CHAR, TRAITS>
00327 #else
00328 public PGSTD::streambuf
00329 #endif
00330 {
00331 typedef long size_type;
00332 public:
00333 typedef CHAR char_type;
00334 typedef TRAITS traits_type;
00335 typedef typename traits_type::int_type int_type;
00336 #ifdef PQXX_HAVE_STREAMBUF
00337 typedef typename traits_type::pos_type pos_type;
00338 typedef typename traits_type::off_type off_type;
00339 #else
00340 typedef streamoff off_type;
00341 typedef streampos pos_type;
00342 #endif
00343 typedef largeobjectaccess::openmode openmode;
00344 typedef largeobjectaccess::seekdir seekdir;
00345
00346 largeobject_streambuf(dbtransaction &T,
00347 largeobject O,
00348 openmode mode = in | out,
00349 size_type BufSize=512) :
00350 m_BufSize(BufSize),
00351 m_Obj(T, O),
00352 m_G(0),
00353 m_P(0)
00354 {
00355 initialize(mode);
00356 }
00357
00358 largeobject_streambuf(dbtransaction &T,
00359 oid O,
00360 openmode mode = in | out,
00361 size_type BufSize=512) :
00362 m_BufSize(BufSize),
00363 m_Obj(T, O),
00364 m_G(0),
00365 m_P(0)
00366 {
00367 initialize(mode);
00368 }
00369
00370 virtual ~largeobject_streambuf()
00371 {
00372 delete [] m_P;
00373 delete [] m_G;
00374 }
00375
00376
00377 #ifdef PQXX_HAVE_STREAMBUF
00378 protected:
00379 #endif
00380 virtual int sync()
00381 {
00382
00383 setg(eback(), eback(), egptr());
00384 return overflow(EoF());
00385 }
00386
00387 protected:
00388 virtual pos_type seekoff(off_type offset,
00389 seekdir dir,
00390 openmode mode = in|out)
00391 {
00392 if (!mode) {}
00393 return AdjustEOF(m_Obj.cseek(offset, dir));
00394 }
00395
00396 virtual pos_type seekpos(pos_type pos,
00397 openmode mode = in|out)
00398 {
00399 if (!mode) {}
00400 return AdjustEOF(m_Obj.cseek(pos, PGSTD::ios::beg));
00401 }
00402
00403 virtual int_type overflow(int_type ch = EoF())
00404 {
00405 char *const pp = pptr();
00406 if (!pp) return EoF();
00407 char *const pb = pbase();
00408 int_type res = 0;
00409
00410 if (pp > pb) res = AdjustEOF(m_Obj.cwrite(pb, pp-pb));
00411 setp(m_P, m_P + m_BufSize);
00412
00413
00414 if (ch != EoF())
00415 {
00416 *pptr() = char(ch);
00417 pbump(1);
00418 }
00419 return res;
00420 }
00421
00422 virtual int_type underflow()
00423 {
00424 if (!gptr()) return EoF();
00425 char *const eb = eback();
00426 const int res = AdjustEOF(m_Obj.cread(eback(), m_BufSize));
00427 setg(eb, eb, eb + ((res==EoF()) ? 0 : res));
00428 return (!res || (res == EoF())) ? EoF() : *eb;
00429 }
00430
00431 private:
00433 static int_type EoF() { return traits_type::eof(); }
00434
00436 static PGSTD::streampos AdjustEOF(int pos)
00437 {
00438 return (pos == -1) ? EoF() : pos;
00439 }
00440
00441 void initialize(openmode mode)
00442 {
00443 if (mode & PGSTD::ios::in)
00444 {
00445 m_G = new char_type[m_BufSize];
00446 setg(m_G, m_G, m_G);
00447 }
00448 if (mode & PGSTD::ios::out)
00449 {
00450 m_P = new char_type[m_BufSize];
00451 setp(m_P, m_P + m_BufSize);
00452 }
00453 }
00454
00455 const size_type m_BufSize;
00456 largeobjectaccess m_Obj;
00457
00458
00459 char_type *m_G, *m_P;
00460 };
00461
00462
00464
00472 template<typename CHAR=char, typename TRAITS=PGSTD::char_traits<CHAR> >
00473 class basic_ilostream :
00474 #ifdef PQXX_HAVE_STREAMBUF
00475 public PGSTD::basic_istream<CHAR, TRAITS>
00476 #else
00477 public PGSTD::istream
00478 #endif
00479 {
00480 #ifdef PQXX_HAVE_STREAMBUF
00481 typedef PGSTD::basic_istream<CHAR, TRAITS> super;
00482 #else
00483 typedef PGSTD::istream super;
00484 #endif
00485
00486 public:
00487 typedef CHAR char_type;
00488 typedef TRAITS traits_type;
00489 typedef typename traits_type::int_type int_type;
00490 typedef typename traits_type::pos_type pos_type;
00491 typedef typename traits_type::off_type off_type;
00492
00494
00498 basic_ilostream(dbtransaction &T,
00499 largeobject O,
00500 largeobject::size_type BufSize=512) :
00501 super(&m_Buf),
00502 m_Buf(T, O, in, BufSize)
00503 {
00504 }
00505
00507
00511 basic_ilostream(dbtransaction &T,
00512 oid O,
00513 largeobject::size_type BufSize=512) :
00514 super(&m_Buf),
00515 m_Buf(T, O, in, BufSize)
00516 {
00517 }
00518
00519 private:
00520 largeobject_streambuf<CHAR,TRAITS> m_Buf;
00521 };
00522
00523 typedef basic_ilostream<char> ilostream;
00524
00525
00527
00535 template<typename CHAR=char, typename TRAITS=PGSTD::char_traits<CHAR> >
00536 class basic_olostream :
00537 #ifdef PQXX_HAVE_STREAMBUF
00538 public PGSTD::basic_ostream<CHAR, TRAITS>
00539 #else
00540 public PGSTD::ostream
00541 #endif
00542 {
00543 #ifdef PQXX_HAVE_STREAMBUF
00544 typedef PGSTD::basic_ostream<CHAR, TRAITS> super;
00545 #else
00546 typedef PGSTD::ostream super;
00547 #endif
00548 public:
00549 typedef CHAR char_type;
00550 typedef TRAITS traits_type;
00551 typedef typename traits_type::int_type int_type;
00552 typedef typename traits_type::pos_type pos_type;
00553 typedef typename traits_type::off_type off_type;
00554
00556
00560 basic_olostream(dbtransaction &T,
00561 largeobject O,
00562 largeobject::size_type BufSize=512) :
00563 super(&m_Buf),
00564 m_Buf(T, O, out, BufSize)
00565 {
00566 }
00567
00569
00573 basic_olostream(dbtransaction &T,
00574 oid O,
00575 largeobject::size_type BufSize=512) :
00576 super(&m_Buf),
00577 m_Buf(T, O, out, BufSize)
00578 {
00579 }
00580
00581 ~basic_olostream()
00582 {
00583 #ifdef PQXX_HAVE_STREAMBUF
00584 m_Buf.pubsync(); m_Buf.pubsync();
00585 #else
00586 m_Buf.sync(); m_Buf.sync();
00587 #endif
00588 }
00589
00590 private:
00591 largeobject_streambuf<CHAR,TRAITS> m_Buf;
00592 };
00593
00594 typedef basic_olostream<char> olostream;
00595
00596
00598
00606 template<typename CHAR=char, typename TRAITS=PGSTD::char_traits<CHAR> >
00607 class basic_lostream :
00608 #ifdef PQXX_HAVE_STREAMBUF
00609 public PGSTD::basic_iostream<CHAR, TRAITS>
00610 #else
00611 public PGSTD::iostream
00612 #endif
00613 {
00614 #ifdef PQXX_HAVE_STREAMBUF
00615 typedef PGSTD::basic_iostream<CHAR, TRAITS> super;
00616 #else
00617 typedef PGSTD::iostream super;
00618 #endif
00619
00620 public:
00621 typedef CHAR char_type;
00622 typedef TRAITS traits_type;
00623 typedef typename traits_type::int_type int_type;
00624 typedef typename traits_type::pos_type pos_type;
00625 typedef typename traits_type::off_type off_type;
00626
00628
00632 basic_lostream(dbtransaction &T,
00633 largeobject O,
00634 largeobject::size_type BufSize=512) :
00635 super(&m_Buf),
00636 m_Buf(T, O, in | out, BufSize)
00637 {
00638 }
00639
00641
00645 basic_lostream(dbtransaction &T,
00646 oid O,
00647 largeobject::size_type BufSize=512) :
00648 super(&m_Buf),
00649 m_Buf(T, O, in | out, BufSize)
00650 {
00651 }
00652
00653 ~basic_lostream()
00654 {
00655 #ifdef PQXX_HAVE_STREAMBUF
00656 m_Buf.pubsync(); m_Buf.pubsync();
00657 #else
00658 m_Buf.sync(); m_Buf.sync();
00659 #endif
00660 }
00661
00662 private:
00663 largeobject_streambuf<CHAR,TRAITS> m_Buf;
00664 };
00665
00666 typedef basic_lostream<char> lostream;
00667
00668 }
00669
00670