00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
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();
00043
00045
00047 explicit LargeObject(TransactionItf &T);
00048
00050
00054 explicit LargeObject(Oid O) : m_ID(O) {}
00055
00057
00061 LargeObject(TransactionItf &T, const PGSTD::string &File);
00062
00064
00068 LargeObject(const LargeObjectAccess &O);
00069
00071
00074 Oid id() const throw () { return m_ID; }
00075
00077 bool operator==(const LargeObject &other) const
00078 { return m_ID == other.m_ID; }
00080 bool operator!=(const LargeObject &other) const
00081 { return m_ID != other.m_ID; }
00083 bool operator<=(const LargeObject &other) const
00084 { return m_ID <= other.m_ID; }
00086 bool operator>=(const LargeObject &other) const
00087 { return m_ID >= other.m_ID; }
00089 bool operator<(const LargeObject &other) const
00090 { return m_ID < other.m_ID; }
00092 bool operator>(const LargeObject &other) const
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;
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);
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);
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)
00222 { write(Buf.c_str(), Buf.size()); }
00223
00225
00231 size_type read(char Buf[], size_type Len);
00232
00234
00237 size_type seek(size_type dest, PGSTD::ios_base::seekdir dir);
00238
00240
00248 long cseek(long dest, PGSTD::ios_base::seekdir dir) throw ();
00249
00251
00257 long cwrite(const char Buf[], size_type Len) throw ();
00258
00260
00266 long cread(char Buf[], size_type Len) throw ();
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
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) :
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) :
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
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) {}
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) {}
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
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
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) :
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) :
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