00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
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();
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
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);
00166
00168
00174 largeobjectaccess(dbtransaction &T,
00175 oid O,
00176 openmode mode =
00177 PGSTD::ios::in |
00178 PGSTD::ios::out);
00179
00181
00186 largeobjectaccess(dbtransaction &T,
00187 largeobject O,
00188 openmode mode = PGSTD::ios::in | PGSTD::ios::out);
00189
00191
00196 largeobjectaccess(dbtransaction &T,
00197 const PGSTD::string &File,
00198 openmode mode =
00199 PGSTD::ios::in | PGSTD::ios::out);
00200
00201 ~largeobjectaccess() { close(); }
00202
00204
00207 using largeobject::id;
00208
00210
00213 void to_file(const PGSTD::string &File) const
00214 {
00215 largeobject::to_file(m_Trans, File);
00216 }
00217
00219
00223 void write(const char Buf[], size_type Len);
00224
00226
00229 void write(const PGSTD::string &Buf)
00230 { write(Buf.c_str(), Buf.size()); }
00231
00233
00239 size_type read(char Buf[], size_type Len);
00240
00242
00245 size_type seek(size_type dest, seekdir dir);
00246
00248
00256 pos_type cseek(off_type dest, seekdir dir) throw ();
00257
00259
00265 off_type cwrite(const char Buf[], size_type Len) throw ();
00266
00268
00274 off_type cread(char Buf[], size_type Len) throw ();
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
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) :
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) :
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
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) {}
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) {}
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
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
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) :
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) :
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