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 private:
00126 Oid m_ID;
00127 };
00128
00129
00131 class LargeObjectAccess : private LargeObject
00132 {
00133 public:
00134 using LargeObject::size_type;
00135
00137
00141 explicit LargeObjectAccess(TransactionItf &T,
00142 PGSTD::ios_base::openmode mode =
00143 PGSTD::ios_base::in |
00144 PGSTD::ios_base::out);
00145
00147
00153 explicit LargeObjectAccess(TransactionItf &T,
00154 Oid O,
00155 PGSTD::ios_base::openmode mode =
00156 PGSTD::ios_base::in |
00157 PGSTD::ios_base::out);
00158
00160
00165 explicit LargeObjectAccess(TransactionItf &T,
00166 LargeObject O,
00167 PGSTD::ios_base::openmode mode =
00168 PGSTD::ios_base::in |
00169 PGSTD::ios_base::out);
00170
00172
00177 LargeObjectAccess(TransactionItf &T,
00178 const PGSTD::string &File,
00179 PGSTD::ios_base::openmode mode =
00180 PGSTD::ios_base::in | PGSTD::ios_base::out);
00181
00182 ~LargeObjectAccess() { close(); }
00183
00185
00188 using LargeObject::id;
00189
00191
00194 void to_file(const char File[]) const
00195 {
00196 LargeObject::to_file(m_Trans, File);
00197 }
00198
00200
00203 void to_file(const PGSTD::string &File) const
00204 {
00205 LargeObject::to_file(m_Trans, File);
00206 }
00207
00209
00213 void write(const char Buf[], size_type Len);
00214
00216
00219 void write(const PGSTD::string &Buf)
00220 { write(Buf.c_str(), Buf.size()); }
00221
00223
00229 size_type read(char Buf[], size_type Len);
00230
00231
00233
00234 * @param dest offset to go to
00235 * @param dir origin to which dest is relative: ios_base::beg (from beginning
00236 * of the object), ios_base::cur (from current access position), or
00237 * ios_base;:end (from end of object)
00238 */
00239 long cseek(long dest, PGSTD::ios_base::seekdir dir) throw ();
00240
00242
00247 long cwrite(const char Buf[], size_type Len) throw ();
00248
00250
00255 long cread(char Buf[], size_type Len) throw ();
00256
00257 using LargeObject::operator==;
00258 using LargeObject::operator!=;
00259 using LargeObject::operator<;
00260 using LargeObject::operator<=;
00261 using LargeObject::operator>;
00262 using LargeObject::operator>=;
00263
00264 private:
00265 PGconn *RawConnection() { return LargeObject::RawConnection(m_Trans); }
00266
00267 void open(PGSTD::ios_base::openmode mode);
00268 void close();
00269
00270 TransactionItf &m_Trans;
00271 int m_fd;
00272
00273
00274 LargeObjectAccess();
00275 LargeObjectAccess(const LargeObjectAccess &);
00276 LargeObjectAccess operator=(const LargeObjectAccess &);
00277 };
00278
00279
00281
00288 template<typename CHAR=char, typename TRAITS=PGSTD::char_traits<CHAR> >
00289 class largeobject_streambuf : public PGSTD::basic_streambuf<CHAR, TRAITS>
00290 {
00291 typedef long size_type;
00292 public:
00293 typedef CHAR char_type;
00294 typedef TRAITS traits_type;
00295 typedef typename traits_type::int_type int_type;
00296 typedef typename traits_type::pos_type pos_type;
00297 typedef typename traits_type::off_type off_type;
00298
00299 largeobject_streambuf(TransactionItf &T,
00300 LargeObject O,
00301 PGSTD::ios_base::openmode mode =
00302 PGSTD::ios::in | PGSTD::ios::out,
00303 size_type BufSize=512) :
00304 m_BufSize(BufSize),
00305 m_Obj(T, O),
00306 m_G(0),
00307 m_P(0)
00308 {
00309 initialize(mode);
00310 }
00311
00312 largeobject_streambuf(TransactionItf &T,
00313 Oid O,
00314 PGSTD::ios_base::openmode mode =
00315 PGSTD::ios::in | PGSTD::ios::out,
00316 size_type BufSize=512) :
00317 m_BufSize(BufSize),
00318 m_Obj(T, O),
00319 m_G(0),
00320 m_P(0)
00321 {
00322 initialize(mode);
00323 }
00324
00325 virtual ~largeobject_streambuf()
00326 {
00327 delete [] m_P;
00328 delete [] m_G;
00329 }
00330
00331
00332 protected:
00333 virtual int sync()
00334 {
00335
00336 setg(eback(), eback(), egptr());
00337 return overflow(EoF());
00338 }
00339
00340 virtual pos_type seekoff(off_type offset,
00341 PGSTD::ios_base::seekdir dir,
00342 PGSTD::ios_base::openmode mode =
00343 PGSTD::ios_base::in|PGSTD::ios_base::out)
00344 {
00345 if (!mode) {}
00346 return AdjustEOF(m_Obj.cseek(offset, dir));
00347 }
00348
00349 virtual pos_type seekpos(pos_type pos,
00350 PGSTD::ios_base::openmode mode =
00351 PGSTD::ios_base::in|PGSTD::ios_base::out)
00352 {
00353 if (!mode) {}
00354 return AdjustEOF(m_Obj.cseek(pos, PGSTD::ios_base::beg));
00355 }
00356
00357 virtual int_type overflow(int_type ch = EoF())
00358 {
00359 char *const pp = pptr();
00360 if (!pp) return EoF();
00361 char *const pb = pbase();
00362 int_type result = 0;
00363
00364 if (pp > pb) result = AdjustEOF(m_Obj.cwrite(pb, pp-pb));
00365 setp(m_P, m_P + m_BufSize);
00366
00367
00368 if (ch != EoF())
00369 {
00370 *pptr() = char(ch);
00371 pbump(1);
00372 }
00373 return result;
00374 }
00375
00376 virtual int_type underflow()
00377 {
00378 if (!gptr()) return EoF();
00379 char *const eb = eback();
00380 const int result = AdjustEOF(m_Obj.cread(eback(), m_BufSize));
00381 setg(eb, eb, eb + ((result==EoF()) ? 0 : result));
00382 return (!result || (result == EoF())) ? EoF() : *eb;
00383 }
00384
00385 private:
00387 static int_type EoF() { return traits_type::eof(); }
00388
00390 static PGSTD::streampos AdjustEOF(int pos)
00391 {
00392 return (pos == -1) ? EoF() : pos;
00393 }
00394
00395 void initialize(PGSTD::ios_base::openmode mode)
00396 {
00397 if (mode & PGSTD::ios_base::in)
00398 {
00399 m_G = new char_type[m_BufSize];
00400 setg(m_G, m_G, m_G);
00401 }
00402 if (mode & PGSTD::ios_base::out)
00403 {
00404 m_P = new char_type[m_BufSize];
00405 setp(m_P, m_P + m_BufSize);
00406 }
00407 }
00408
00409 const size_type m_BufSize;
00410 LargeObjectAccess m_Obj;
00411
00412
00413 char_type *m_G, *m_P;
00414 };
00415
00416
00418
00425 template<typename CHAR=char, typename TRAITS=PGSTD::char_traits<CHAR> >
00426 class basic_ilostream : public PGSTD::basic_istream<CHAR, TRAITS>
00427 {
00428 public:
00429 typedef CHAR char_type;
00430 typedef TRAITS traits_type;
00431 typedef typename traits_type::int_type int_type;
00432 typedef typename traits_type::pos_type pos_type;
00433 typedef typename traits_type::off_type off_type;
00434
00436
00440 basic_ilostream(TransactionItf &T,
00441 LargeObject O,
00442 LargeObject::size_type BufSize=512) :
00443 PGSTD::basic_istream<CHAR,TRAITS>(&m_Buf),
00444 m_Buf(T, O, in, BufSize)
00445 {
00446 }
00447
00449
00453 basic_ilostream(TransactionItf &T,
00454 Oid O,
00455 LargeObject::size_type BufSize=512) :
00456 PGSTD::basic_istream<CHAR,TRAITS>(&m_Buf),
00457 m_Buf(T, O, in, BufSize)
00458 {
00459 }
00460
00461 private:
00462 largeobject_streambuf<CHAR,TRAITS> m_Buf;
00463 };
00464
00465 typedef basic_ilostream<char> ilostream;
00466
00467
00469
00476 template<typename CHAR=char, typename TRAITS=PGSTD::char_traits<CHAR> >
00477 class basic_olostream : public PGSTD::basic_ostream<CHAR, TRAITS>
00478 {
00479 public:
00480 typedef CHAR char_type;
00481 typedef TRAITS traits_type;
00482 typedef typename traits_type::int_type int_type;
00483 typedef typename traits_type::pos_type pos_type;
00484 typedef typename traits_type::off_type off_type;
00485
00487
00491 basic_olostream(TransactionItf &T,
00492 LargeObject O,
00493 LargeObject::size_type BufSize=512) :
00494 PGSTD::basic_ostream<CHAR,TRAITS>(&m_Buf),
00495 m_Buf(T, O, out, BufSize)
00496 {
00497 }
00498
00500
00504 basic_olostream(TransactionItf &T,
00505 Oid O,
00506 LargeObject::size_type BufSize=512) :
00507 PGSTD::basic_ostream<CHAR,TRAITS>(&m_Buf),
00508 m_Buf(T, O, out, BufSize)
00509 {
00510 }
00511
00512 ~basic_olostream() { m_Buf.pubsync(); m_Buf.pubsync(); }
00513
00514 private:
00515 largeobject_streambuf<CHAR,TRAITS> m_Buf;
00516 };
00517
00518 typedef basic_olostream<char> olostream;
00519
00520
00522
00529 template<typename CHAR=char, typename TRAITS=PGSTD::char_traits<CHAR> >
00530 class basic_lostream : public PGSTD::basic_iostream<CHAR, TRAITS>
00531 {
00532 public:
00533 typedef CHAR char_type;
00534 typedef TRAITS traits_type;
00535 typedef typename traits_type::int_type int_type;
00536 typedef typename traits_type::pos_type pos_type;
00537 typedef typename traits_type::off_type off_type;
00538
00540
00544 basic_lostream(TransactionItf &T,
00545 LargeObject O,
00546 LargeObject::size_type BufSize=512) :
00547 PGSTD::basic_iostream<CHAR,TRAITS>(&m_Buf),
00548 m_Buf(T, O, in | out, BufSize)
00549 {
00550 }
00551
00553
00557 basic_lostream(TransactionItf &T,
00558 Oid O,
00559 LargeObject::size_type BufSize=512) :
00560 PGSTD::basic_iostream<CHAR,TRAITS>(&m_Buf),
00561 m_Buf(T, O, in | out, BufSize)
00562 {
00563 }
00564
00565 ~basic_lostream() { m_Buf.pubsync(); m_Buf.pubsync(); }
00566
00567 private:
00568 largeobject_streambuf<CHAR,TRAITS> m_Buf;
00569 };
00570
00571 typedef basic_lostream<char> lostream;
00572
00573 }
00574
00575 #endif
00576