00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
#ifndef PStream_INC
00037
#define PStream_INC
00038
00039
00040
#include <map>
00041
#include <set>
00042
00043
#include <sstream>
00044
#include <plearn/base/pl_hash_fun.h>
00045
00046
#include "PStream_util.h"
00047
#include <plearn/base/plerror.h>
00048
#include <fstream>
00049
00050
#include <plearn/base/byte_order.h>
00051
#include "fileutils.h"
00052
#include "PStreamBuf.h"
00053
#include "StdPStreamBuf.h"
00054
00055
00056
00057
00058
00059
00060
namespace PLearn {
00061
00062
using namespace std;
00063
00079 class PStream :
public PPointable
00080 {
00081
public:
00083 typedef PStream& (*pl_pstream_manip)(
PStream&);
00084
00086
00087
00088
00089
00090
00091
00092
#if __GNUC__ < 3 && !defined(WIN32)
00093
00094 typedef int streamsize;
00095 typedef ios
ios_base;
00096
#endif
00097
00098 enum mode_t
00099 {
00100
plearn_ascii,
00101
plearn_binary,
00102
raw_ascii,
00103
raw_binary,
00104
pretty_ascii
00105 };
00106
00109
00112 enum compr_mode_t {
00113
compr_none,
00114
compr_double_as_float,
00115
compr_sparse,
00116
compr_lossy_sparse
00117 };
00118
00119
00120
protected:
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130 PP<StdPStreamBuf> pstreambuf;
00131
00132
00133
public:
00134 mode_t inmode;
00135
00136 map<unsigned int, void *>
copies_map_in;
00137 mode_t outmode;
00138
00139 map<void *, unsigned int>
copies_map_out;
00140
00141
protected:
00142
00145
00146
00147
00148
private:
00149
static char tmpbuf[100];
00150
00151
public:
00154 bool implicit_storage;
00156 compr_mode_t compression_mode;
00157
00158
public:
00159
00161
PStream();
00162
00164
PStream(istream* pin_,
bool own_pin_=
false);
00165
00167
PStream(ostream* pout_,
bool own_pout_=
false);
00168
00170
PStream(
iostream* pios_,
bool own_pios_=
false);
00171
00173
PStream(istream* pin_, ostream* pout_,
bool own_pin_=
false,
bool own_pout_=
false);
00174
00176
00178
virtual ~PStream();
00179
00180 inline void setInMode(mode_t m) {
inmode = m; }
00181 inline void setOutMode(mode_t m) {
outmode = m; }
00182 inline void setMode(mode_t m) {
inmode = m;
outmode = m; }
00183
00184 PStream&
operator>>(mode_t m) {
inmode = m;
return *
this; }
00185 PStream&
operator<<(mode_t m) {
outmode = m;
return *
this; }
00186
00187
public:
00188
00189 inline PStream&
operator()(istream* pin)
00190 {
pstreambuf->setIn(pin);
return *
this; }
00191
00192 inline PStream&
operator()(ostream* pout)
00193 {
pstreambuf->setOut(pout);
return *
this; }
00194
00195 inline PStream&
operator()(
iostream* pios)
00196 {
pstreambuf->setIn(pios);
pstreambuf->setOut(pios);
return *
this; }
00197
00198 inline PStream&
operator()(istream* pin, ostream* pout)
00199 {
pstreambuf->setIn(pin);
pstreambuf->setOut(pout);
return *
this; }
00200
00201
PStream& operator=(
const PStream& pios);
00202
00203 inline PStream&
operator=(istream* pin) {
return operator()(pin); }
00204 inline PStream&
operator=(ostream* pout) {
return operator()(pout); }
00205 inline PStream&
operator=(
iostream* pios) {
return operator()(pios); }
00206
00207 inline PStream&
operator()(
const PStream& pios) {
return operator=(pios); }
00208
00209
00210
void writeAsciiNum(
char x);
00211
void writeAsciiNum(
unsigned char x);
00212
void writeAsciiNum(
signed char x);
00213
void writeAsciiNum(
short x);
00214
void writeAsciiNum(
unsigned short x);
00215
void writeAsciiNum(
int x);
00216
void writeAsciiNum(
unsigned int x);
00217
void writeAsciiNum(
long x);
00218
void writeAsciiNum(
unsigned long x);
00219
void writeAsciiNum(
float x);
00220
void writeAsciiNum(
double x);
00221
00222
void readAsciiNum(
char &x);
00223
void readAsciiNum(
unsigned char &x);
00224
void readAsciiNum(
signed char &x);
00225
void readAsciiNum(
short &x);
00226
void readAsciiNum(
unsigned short &x);
00227
void readAsciiNum(
int &x);
00228
void readAsciiNum(
unsigned int &x);
00229
void readAsciiNum(
long &x);
00230
void readAsciiNum(
unsigned long &x);
00231
void readAsciiNum(
float &x);
00232
void readAsciiNum(
double &x);
00233
00235
void writeAsciiHexNum(
unsigned char x);
00236
00238
00239
00240
00241 inline operator bool() {
return pstreambuf->rawin() &&
pstreambuf->rawin()->good() ||
pstreambuf->rawout() &&
pstreambuf->rawout()->good(); }
00242
00243 inline bool eof()
const {
return pstreambuf->rawin()->eof(); }
00244 inline bool good()
const {
return pstreambuf->rawin()->good() &&
pstreambuf->rawout()->good(); }
00245
00246 inline istream&
_do_not_use_this_method_rawin_() {
return *
pstreambuf->rawin(); }
00247
00248
00249
00250
00251 inline int get()
00252 {
00253
#if STREAMBUFVER == 1
00254
return pstreambuf->get();
00255
#else
00256
return pstreambuf->rawin()->get();
00257
#endif
00258
}
00259
00260 inline PStream&
get(
char& c)
00261 {
00262
#if STREAMBUFVER == 1
00263
c = (
char)
pstreambuf->get();
00264
#else
00265
pstreambuf->rawin()->get(c);
00266
#endif
00267
return *
this;
00268 }
00269
00271 inline PStream&
getline(
string& line,
char delimitor=
'\n')
00272 {
00273
#if STREAMBUFVER == 1
00274
line.clear();
00275
int c =
get();
00276
while(c!=EOF && c!=delimitor)
00277 line.push_back((
char)c);
00278
#else
00279
std::getline(*
pstreambuf->rawin(), line, delimitor);
00280
#endif
00281
return *
this;
00282 }
00283
00284 inline string getline()
00285 {
string s;
getline(s);
return s; }
00286
00287
00288
00289
00290 inline int peek()
00291 {
00292
#if STREAMBUFVER == 1
00293
return pstreambuf->peek();
00294
#else
00295
int c =
pstreambuf->rawin()->get();
00296
pstreambuf->rawin()->unget();
00297
return c;
00298
#endif
00299
}
00300
00301 inline PStream&
putback(
char c)
00302 {
00303
#if STREAMBUFVER == 1
00304
pstreambuf->unget(c);
00305
#else
00306
pstreambuf->rawin()->putback(c);
00307
#endif
00308
return *
this;
00309 }
00310
00311
#if STREAMBUFVER == 1
00312
00313
#else
00314 inline PStream&
unget() {
pstreambuf->rawin()->unget();
return *
this; }
00315
#endif
00316
00317
00318 inline PStream&
read(
char* s,
streamsize n)
00319 {
00320
#if STREAMBUFVER == 1
00321
pstreambuf->read(s,n);
00322
return *
this;
00323
00324
#else
00325
00326
00327
00328
while (n)
00329 {
00330
int c =
get();
00331
if (c == EOF)
break;
00332 *s++ = (
char) c;
00333 n--;
00334 }
00335
return *
this;
00336
#endif
00337
}
00338
00339 inline PStream&
read(
string& s,
streamsize n)
00340 {
00341
char* buf =
new char[n];
00342
read(buf, n);
00343 s.assign(buf,n);
00344
delete[] buf;
00345
return *
this;
00346 }
00347
00352 streamsize readUntil(
char* buf, streamsize n,
char stop_char);
00353
00358 streamsize readUntil(
char* buf, streamsize n,
const char* stop_chars);
00359
00360 inline PStream&
write(
const char* s,
streamsize n)
00361 {
00362
#if STREAMBUFVER == 1
00363
pstreambuf->write(s,n);
00364
#else
00365
pstreambuf->rawout()->write(s,n);
00366
#endif
00367
return *
this;
00368 }
00369
00370 inline PStream&
put(
char c)
00371 {
00372
#if STREAMBUFVER == 1
00373
pstreambuf->put(c);
00374
#else
00375
pstreambuf->rawout()->put(c);
return *
this;
00376
#endif
00377
}
00378
00379 inline PStream& put(
unsigned char c) {
write(reinterpret_cast<char *>(&c),
sizeof(c));
return *
this; }
00380 inline PStream& put(
int x) {
return put((
char)
x); }
00381
00382 inline PStream&
flush()
00383 {
00384
#if STREAMBUFVER == 1
00385
pstreambuf->flush();
00386
#else
00387
pstreambuf->rawout()->flush();
00388
#endif
00389
return *
this;
00390 }
00391
00392 inline PStream&
endl() { put(
'\n');
flush();
return *
this; }
00393
00394
00395
00396 inline PStream&
write(
const char* s)
00397 {
00398
write(s,
strlen(s));
00399
return *
this;
00400 }
00401
00402 inline PStream&
write(
const string& s)
00403 {
00404
write(s.data(),s.length());
00405
return *
this;
00406 }
00407
00408
#if STREAMBUFVER == 1
00409
00410
#else
00411
00412 inline void attach(
int fd)
00413 {
pstreambuf->attach(fd); }
00414
#endif
00415
00416
00417
00419
void skipRestOfLine();
00420
00422
void skipBlanks();
00423
00425
void skipBlanksAndComments();
00426
00428
void skipBlanksAndCommentsAndSeparators();
00429
00431
void skipAll(
const char* chars_to_skip);
00432
00440
int smartReadUntilNext(
const string& stoppingsymbols,
string& characters_read,
bool ignore_brackets=
false);
00441
00442
00443
PStream&
operator>>(
bool &x);
00444
PStream&
operator>>(
float &x);
00445
PStream&
operator>>(
double &x);
00446
PStream&
operator>>(
string &x);
00447
PStream&
operator>>(
char* x);
00448
PStream&
operator>>(
char &x);
00449
PStream&
operator>>(
signed char &x);
00450
PStream&
operator>>(
unsigned char &x);
00451
PStream&
operator>>(
int &x);
00452
PStream&
operator>>(
unsigned int &x);
00453
PStream&
operator>>(
long &x);
00454
PStream&
operator>>(
unsigned long &x);
00455
PStream&
operator>>(
short &x);
00456
PStream&
operator>>(
unsigned short &x);
00457 PStream&
operator>>(
pl_pstream_manip func) {
return (*func)(*this); }
00458
00459
00460
PStream&
operator<<(
float x);
00461
PStream&
operator<<(
double x);
00462
00465
PStream&
operator<<(
const char *x);
00466
00470
PStream&
operator<<(
const string &x);
00471
00472
PStream&
operator<<(
char x);
00473
PStream&
operator<<(
signed char x);
00474
PStream&
operator<<(
unsigned char x);
00475
PStream&
operator<<(
int x);
00476
PStream&
operator<<(
unsigned int x);
00477
PStream&
operator<<(
long x);
00478
PStream&
operator<<(
unsigned long x);
00479
PStream&
operator<<(
short x);
00480
PStream&
operator<<(
unsigned short x);
00481 PStream&
operator<<(pl_pstream_manip func) {
return (*func)(*this); }
00482
00483
#if STREAMBUFVER == 0
00486 inline pl_streambuf* pl_rdbuf() { return pstreambuf->pl_rdbuf(); }
00487
#endif
00488
00489 };
00490
00491
00492
00493
00494
extern PStream&
flush(
PStream& out);
00495
extern PStream&
endl(
PStream& out);
00496
extern PStream&
ws(
PStream& out);
00497
00498
00499
using std::flush;
00500
using std::endl;
00501
using std::ws;
00502
00503
00504
00505
00506
00507
00508
template <
class T>
00509 inline PStream&
operator>>(
PStream& in, T*& x)
00510 {
00511 in.
skipBlanksAndCommentsAndSeparators();
00512
if (in.
peek() ==
'*')
00513 {
00514 in.
get();
00515
unsigned int id;
00516 in >>
id;
00517 in.
skipBlanksAndCommentsAndSeparators();
00518
if (
id==0)
00519
x = 0;
00520
else if (in.
peek() ==
'-')
00521 {
00522 in.
get();
00523
char cc = in.
get();
00524
if(cc !=
'>')
00525
PLERROR(
"In PStream::operator>>(T*&) Wrong format. Expecting \"*%d->\" but got \"*%d-%c\".",
id,
id, cc);
00526 in.
skipBlanksAndCommentsAndSeparators();
00527
if(!
x)
00528
x=
new T();
00529 in >> *
x;
00530 in.
skipBlanksAndCommentsAndSeparators();
00531 in.
copies_map_in[
id]=
x;
00532 }
00533
else
00534 {
00535
00536 map<unsigned int, void *>::iterator it = in.
copies_map_in.find(
id);
00537
if (it == in.
copies_map_in.end())
00538
PLERROR(
"In PStream::operator>>(T*&) object (ptr) to be read has not been previously defined");
00539
x= static_cast<T *>(it->second);
00540 }
00541 }
00542
else
00543 {
00544 in >> *
x;
00545 in.
skipBlanksAndCommentsAndSeparators();
00546 }
00547
00548
return in;
00549 }
00550
00551
00552
template <
class T>
00553 inline PStream&
operator<<(
PStream& out,
const T*& x)
00554 {
00555
00556
if(
x)
00557 {
00558 map<void *, unsigned int>::iterator it = out.
copies_map_out.find(const_cast<T*&>(
x));
00559
if (it == out.
copies_map_out.end())
00560 {
00561
int id = (
int)out.
copies_map_out.size()+1;
00562 out.
put(
'*');
00563 out <<
id;
00564 out.
write(
"->");
00565 out.
copies_map_out[const_cast<T*&>(
x)] =
id;
00566 out << *
x;
00567 }
00568
else
00569 {
00570 out.
put(
'*');
00571 out << it->second;
00572 out.
put(
' ');
00573 }
00574 }
00575
else
00576 out.
write(
"*0 ");
00577
return out;
00578 }
00579
00580
template <
class T>
00581 inline PStream&
operator>>(
PStream& in,
PP<T> &o)
00582 {
00583 T *ptr;
00584
if (o.
isNull())
00585 ptr = 0;
00586
else
00587 ptr = o;
00588 in >> ptr;
00589 o = ptr;
00590
return in;
00591 }
00592
00593
template <
class T>
00594 inline PStream& operator<<(PStream& out, const PP<T> &o)
00595 {
00596 T *ptr = static_cast<T *>(o);
00597 out << const_cast<const T * &>(ptr);
00598
return out;
00599 }
00600
00601
template <
class T>
00602 inline PStream&
operator<<(
PStream& out, T*& ptr)
00603 {
00604 out << const_cast<const T * &>(ptr);
00605
return out;
00606 }
00607
00608 inline PStream&
operator<<(
PStream& out,
bool x)
00609 {
00610
switch(out.
outmode)
00611 {
00612
case PStream::raw_binary:
00613
case PStream::raw_ascii:
00614
case PStream::pretty_ascii:
00615
if(
x)
00616 out.
put(
'1');
00617
else
00618 out.
put(
'0');
00619
break;
00620
case PStream::plearn_ascii:
00621
if(
x)
00622 out.
put(
'1');
00623
else
00624 out.
put(
'0');
00625 out.
put(
' ');
00626
break;
00627
case PStream::plearn_binary:
00628 out.
put((
char)0x12);
00629
if(
x)
00630 out.
put(
'1');
00631
else
00632 out.
put(
'0');
00633
break;
00634
default:
00635
PLERROR(
"In PStream::operator<< unknown outmode!!!!!!!!!");
00636
break;
00637 }
00638
return out;
00639 }
00640
00641
00642
00643
00644
00645
00646
00647
template<
class A,
class B>
00648 inline PStream& operator<<(PStream& out, const pair<A,B>&
x)
00649 {
00650 out <<
x.first;
00651 out.write(
": ");
00652 out <<
x.second;
00653 out.put(
' ');
00654
return out;
00655 }
00656
00657
template <
typename S,
typename T>
00658 inline PStream&
operator>>(
PStream& in, pair<S, T> &x)
00659 {
00660 in.
skipBlanksAndCommentsAndSeparators();
00661 in >>
x.first;
00662 in.
skipBlanksAndComments();
00663
if(in.
get()!=
':')
00664
PLERROR(
"In operator>>(PStream& in, pair<S, T> &x) expected ':' to separate the 2 halves of the pair");
00665 in.
skipBlanksAndComments();
00666 in >>
x.second;
00667
return in;
00668 }
00669
00670
00671
00672
00673
template<
class MapT>
00674 void writeMap(
PStream& out,
const MapT& m)
00675 {
00676
typename MapT::const_iterator it = m.begin();
00677
typename MapT::const_iterator itend = m.end();
00678
00679 out.
put(
'{');
00680
if(!m.empty())
00681 {
00682
00683 out << it->first;
00684 out.
write(
": ");
00685 out << it->second;
00686 ++it;
00687
while(it!=itend)
00688 {
00689 out.
write(
", ");
00690 out << it->first;
00691 out.
write(
": ");
00692 out << it->second;
00693 ++it;
00694 }
00695 }
00696 out.
put(
'}');
00697 }
00698
00699
template<
class MapT>
00700 void readMap(
PStream& in, MapT& m)
00701 {
00702 m.clear();
00703 in.
skipBlanksAndCommentsAndSeparators();
00704
int c = in.
get();
00705
if(c!=
'{')
00706
PLERROR(
"In readMap(Pstream& in, MapT& m) expected '{' but read %c",c);
00707 in.
skipBlanksAndCommentsAndSeparators();
00708 c = in.
peek();
00709
while(c!=
'}')
00710 {
00711 pair<typename MapT::key_type, typename MapT::mapped_type>
val;
00712 in >>
val.first;
00713 in.
skipBlanksAndCommentsAndSeparators();
00714 c = in.
get();
00715
if(c!=
':')
00716
PLERROR(
"In readMap(Pstream& in, MapT& m) separator between key and value must be ':', but I read a '%c'",c);
00717 in.
skipBlanksAndCommentsAndSeparators();
00718 in >>
val.second;
00719 m.insert(
val);
00720 in.
skipBlanksAndCommentsAndSeparators();
00721 c = in.
peek();
00722 }
00723 in.
get();
00724 }
00725
00726
template<
class Key,
class Value>
00727 inline PStream& operator<<(PStream& out, const map<Key, Value>& m)
00728 {
writeMap(out, m);
return out; }
00729
00730
template<
class Key,
class Value>
00731 inline PStream&
operator>>(
PStream& in, map<Key, Value>& m)
00732 {
readMap(in, m);
return in; }
00733
00734
template<
class Key,
class Value>
00735 inline PStream& operator<<(PStream& out, const multimap<Key, Value>& m)
00736 {
writeMap(out, m);
return out; }
00737
00738
template<
class Key,
class Value>
00739 inline PStream&
operator>>(
PStream& in, multimap<Key, Value>& m)
00740 {
readMap(in, m);
return in; }
00741
00742
00743
template<
class Key,
class Value>
00744 inline PStream& operator<<(PStream& out, const hash_map<Key, Value>& m)
00745 {
writeMap(out, m);
return out; }
00746
00747
template<
class Key,
class Value>
00748 inline PStream&
operator>>(
PStream& in, hash_map<Key, Value>& m)
00749 {
readMap(in, m);
return in; }
00750
00751
template<
class Key,
class Value>
00752 inline PStream& operator<<(PStream& out, const hash_multimap<Key, Value>& m)
00753 {
writeMap(out, m);
return out; }
00754
00755
template<
class Key,
class Value>
00756 inline PStream&
operator>>(
PStream& in, hash_multimap<Key, Value>& m)
00757 {
readMap(in, m);
return in; }
00758
00759
00761
00762
00763
00764
template<
class Iterator>
00765 void binwrite_(
PStream& out, Iterator& it,
unsigned int n)
00766 {
00767 PStream::mode_t outmode = out.
outmode;
00768
if(outmode!=PStream::raw_binary && outmode!=PStream::plearn_binary)
00769 out.
outmode = PStream::plearn_binary;
00770
while(n--)
00771 {
00772 out << *it;
00773 ++it;
00774 }
00775 out.
outmode = outmode;
00776 }
00777
00778 inline void binwrite_(
PStream& out,
const bool* x,
unsigned int n)
00779 {
00780
while(n--)
00781 {
00782
if(*
x++)
00783 out.
put(
'1');
00784
else
00785 out.
put(
'0');
00786 }
00787 }
00788
00789 inline void binwrite_(
PStream& out,
const char* x,
unsigned int n)
00790 { out.
write((
char*)
x, n*
sizeof(
char)); }
00791 inline void binwrite_(
PStream& out,
char* x,
unsigned int n)
00792 { out.
write((
char*)
x, n*
sizeof(
char)); }
00793
00794 inline void binwrite_(
PStream& out,
const signed char* x,
unsigned int n)
00795 { out.
write((
char*)
x, n*
sizeof(
signed char)); }
00796 inline void binwrite_(
PStream& out,
signed char* x,
unsigned int n)
00797 { out.
write((
char*)
x, n*
sizeof(
signed char)); }
00798
00799 inline void binwrite_(
PStream& out,
const unsigned char* x,
unsigned int n)
00800 { out.
write((
char*)
x, n*
sizeof(
unsigned char)); }
00801 inline void binwrite_(
PStream& out,
unsigned char* x,
unsigned int n)
00802 { out.
write((
char*)
x, n*
sizeof(
unsigned char)); }
00803
00804 inline void binwrite_(
PStream& out,
const short* x,
unsigned int n)
00805 { out.
write((
char*)
x, n*
sizeof(
short)); }
00806 inline void binwrite_(
PStream& out,
short* x,
unsigned int n)
00807 { out.
write((
char*)
x, n*
sizeof(
short)); }
00808
00809 inline void binwrite_(
PStream& out,
const unsigned short* x,
unsigned int n)
00810 { out.
write((
char*)
x, n*
sizeof(
unsigned short)); }
00811 inline void binwrite_(
PStream& out,
unsigned short* x,
unsigned int n)
00812 { out.
write((
char*)
x, n*
sizeof(
unsigned short)); }
00813
00814 inline void binwrite_(
PStream& out,
const int* x,
unsigned int n)
00815 { out.
write((
char*)
x, n*
sizeof(
int)); }
00816 inline void binwrite_(
PStream& out,
int* x,
unsigned int n)
00817 { out.
write((
char*)
x, n*
sizeof(
int)); }
00818
00819 inline void binwrite_(
PStream& out,
const unsigned int* x,
unsigned int n)
00820 { out.
write((
char*)
x, n*
sizeof(
unsigned int)); }
00821 inline void binwrite_(
PStream& out,
unsigned int* x,
unsigned int n)
00822 { out.
write((
char*)
x, n*
sizeof(
unsigned int)); }
00823
00824 inline void binwrite_(
PStream& out,
const long* x,
unsigned int n)
00825 { out.
write((
char*)
x, n*
sizeof(
long)); }
00826 inline void binwrite_(
PStream& out,
long* x,
unsigned int n)
00827 { out.
write((
char*)
x, n*
sizeof(
long)); }
00828
00829 inline void binwrite_(
PStream& out,
const unsigned long* x,
unsigned int n)
00830 { out.
write((
char*)
x, n*
sizeof(
unsigned long)); }
00831 inline void binwrite_(
PStream& out,
unsigned long* x,
unsigned int n)
00832 { out.
write((
char*)
x, n*
sizeof(
unsigned long)); }
00833
00834 inline void binwrite_(
PStream& out,
const float* x,
unsigned int n)
00835 { out.
write((
char*)
x, n*
sizeof(
float)); }
00836 inline void binwrite_(
PStream& out,
float* x,
unsigned int n)
00837 { out.
write((
char*)
x, n*
sizeof(
float)); }
00838
00839 inline void binwrite_(
PStream& out,
const double* x,
unsigned int n)
00840 { out.
write((
char*)
x, n*
sizeof(
double)); }
00841 inline void binwrite_(
PStream& out,
double* x,
unsigned int n)
00842 { out.
write((
char*)
x, n*
sizeof(
double)); }
00843
00844
00845
00846
template<
class Iterator>
00847 void binread_(
PStream& in, Iterator it,
unsigned int n,
unsigned char typecode)
00848 {
00849
if(typecode!=0xFF)
00850
PLERROR(
"In binread_ : bug! A specialised binread_ should have been called for a typecode other than the 'generic' 0xFF");
00851
00852
while(n--)
00853 {
00854 in >> *it;
00855 ++it;
00856 }
00857 }
00858
00859
void binread_(
PStream& in,
bool* x,
unsigned int n,
unsigned char typecode);
00860
00861 inline void binread_(
PStream& in,
char* x,
00862
unsigned int n,
unsigned char typecode)
00863 {
00864
00865
00866
00867
if(typecode!=
TypeTraits<char>::little_endian_typecode()
00868 && typecode!=
TypeTraits<unsigned char>::little_endian_typecode())
00869
PLERROR(
"In binread_ incompatible typecode");
00870
00871 in.
read((
char*)
x, n);
00872 }
00873
00874 inline void binread_(
PStream& in,
signed char* x,
unsigned int n,
unsigned char typecode)
00875 {
binread_(in, (
char *)
x, n, typecode); }
00876
00877 inline void binread_(
PStream& in,
unsigned char* x,
unsigned int n,
unsigned char typecode)
00878 {
binread_(in, (
char *)
x, n, typecode); }
00879
00880
void binread_(
PStream& in,
short* x,
unsigned int n,
unsigned char typecode);
00881
void binread_(
PStream& in,
unsigned short* x,
unsigned int n,
unsigned char typecode);
00882
void binread_(
PStream& in,
int* x,
unsigned int n,
unsigned char typecode);
00883
void binread_(
PStream& in,
unsigned int* x,
unsigned int n,
unsigned char typecode);
00884
void binread_(
PStream& in,
long* x,
unsigned int n,
unsigned char typecode);
00885
void binread_(
PStream& in,
unsigned long* x,
unsigned int n,
unsigned char typecode);
00886
void binread_(
PStream& in,
float* x,
unsigned int n,
unsigned char typecode);
00887
void binread_(
PStream& in,
double* x,
unsigned int n,
unsigned char typecode);
00888
00889
00890
template<
class SequenceType>
00891 void writeSequence(
PStream& out,
const SequenceType& seq)
00892 {
00893
00894
unsigned int n = (
unsigned int)seq.size();
00895
typename SequenceType::const_iterator it = seq.begin();
00896
00897
switch(out.
outmode)
00898 {
00899
case PStream::raw_ascii:
00900
while(n--)
00901 {
00902 out << *it;
00903 out.
put(
' ');
00904 ++it;
00905 }
00906
break;
00907
00908
case PStream::pretty_ascii:
00909 out.
write(
"[ ");
00910
while(n--)
00911 {
00912 out << *it;
00913
if(n>0)
00914 out.
write(
", ");
00915 ++it;
00916 }
00917 out.
write(
" ] ");
00918
break;
00919
00920
case PStream::raw_binary:
00921
binwrite_(out, it, n);
00922
break;
00923
00924
case PStream::plearn_ascii:
00925 out << n;
00926 out.
write(
"[ ");
00927
while(n--)
00928 {
00929 out << *it;
00930 ++it;
00931 }
00932 out.
write(
"] ");
00933
break;
00934
00935
case PStream::plearn_binary:
00936 {
00937
unsigned char typecode;
00938
if(
byte_order()==
LITTLE_ENDIAN_ORDER)
00939 {
00940 out.
put((
char)0x12);
00941 typecode =
TypeTraits<typename SequenceType::value_type>::little_endian_typecode();
00942 }
00943
else
00944 {
00945 out.
put((
char)0x13);
00946 typecode =
TypeTraits<typename SequenceType::value_type>::big_endian_typecode();
00947 }
00948
00949
00950 out.
put(typecode);
00951
00952
00953 out.
write((
char*)&n,
sizeof(n));
00954
00955
00956
binwrite_(out, it, n);
00957 }
00958
break;
00959
00960
default:
00961
PLERROR(
"In PStream::writeSequence(Iterator& it, int n) unknown outmode!!!!!!!!!");
00962
break;
00963 }
00964 }
00965
00966
00968
00976
template<
class SequenceType>
00977 void readSequence(
PStream& in, SequenceType& seq)
00978 {
00979
switch(in.
inmode)
00980 {
00981
case PStream::raw_ascii:
00982 {
00983
00984
int n = (
int)seq.size();
00985
typename SequenceType::iterator it = seq.begin();
00986
while(n--)
00987 {
00988 in >> *it;
00989 in.
skipBlanks();
00990 ++it;
00991 }
00992 }
00993
break;
00994
case PStream::raw_binary:
00995 {
00996
int n = (
int)seq.size();
00997
typename SequenceType::iterator it = seq.begin();
00998
while(n--)
00999 {
01000 in >> *it;
01001 ++it;
01002 }
01003 }
01004
break;
01005
01006
case PStream::plearn_ascii:
01007
case PStream::plearn_binary:
01008 {
01009 in.
skipBlanksAndComments();
01010
int c = in.
peek();
01011
if(c==
'[')
01012 {
01013 in.
get();
01014 in.
skipBlanksAndCommentsAndSeparators();
01015 seq.resize(0);
01016
while(in.
peek()!=
']' && in.
peek()!=EOF && !in.
eof())
01017 {
01018
typename SequenceType::value_type
x;
01019 in >>
x;
01020 seq.push_back(
x);
01021 in.
skipBlanksAndCommentsAndSeparators();
01022 }
01023
if (in.
peek()==EOF || in.
eof())
01024
PLERROR(
"Reading stream, unmatched left bracket [, missing ]");
01025 in.
get();
01026 }
01027
else if(isdigit(c))
01028 {
01029
unsigned int n;
01030 in >> n;
01031 in.
skipBlanksAndComments();
01032 c = in.
get();
01033
if(c!=
'[')
01034
PLERROR(
"Error in readSequence(SequenceType& seq), expected '[', read '%c'",c);
01035 in.
skipBlanksAndCommentsAndSeparators();
01036 seq.resize((
typename SequenceType::size_type) n);
01037
if (n>0)
01038 {
01039
typename SequenceType::iterator it = seq.begin();
01040
while(n--)
01041 {
01042 in >> *it;
01043 in.
skipBlanksAndCommentsAndSeparators();
01044 ++it;
01045 }
01046 }
01047 in.
skipBlanksAndCommentsAndSeparators();
01048 c = in.
get();
01049
if(c!=
']')
01050
PLERROR(
"Error in readSequence(SequenceType& seq), expected ']', read '%c'",c);
01051
01052 }
01053
else if(c==0x12 || c==0x13)
01054 {
01055 in.
get();
01056
unsigned char typecode = in.
get();
01057
unsigned int l;
01058 in.
read((
char*)&l,
sizeof(l));
01059
01060
bool inverted_byte_order = ( (c==0x12 &&
byte_order()==
BIG_ENDIAN_ORDER)
01061 || (c==0x13 &&
byte_order()==
LITTLE_ENDIAN_ORDER) );
01062
01063
if(inverted_byte_order)
01064
endianswap(&l);
01065 seq.resize((
typename SequenceType::size_type) l);
01066
binread_(in, seq.begin(), l, typecode);
01067 }
01068
else
01069
PLERROR(
"In readSequence(SequenceType& seq) '%c' not a proper first character in the header of a sequence!",c);
01070 }
01071
break;
01072
01073
default:
01074
PLERROR(
"In PStream::operator>> unknown inmode!!!!!!!!!");
01075
break;
01076 }
01077
01078 }
01079
01080
01081
01082
01083
01084
template<
class T>
01085 inline void write(ostream& out_,
const T& o)
01086 {
01087
PStream out(&out_);
01088 out << o;
01089 }
01090
01091
template<
class T>
01092 inline void read(istream& in_, T& o)
01093 {
01094
PStream in(&in_);
01095 in >> o;
01096 }
01097
01098
template<
class T>
01099 inline void read(
const string& stringval, T& x)
01100 {
01101 istringstream in_(stringval);
01102
PStream in(&in_);
01103 in >>
x;
01104 }
01105
01106
01107
01108
01109
template <
class T>
inline PStream &
01110 operator>>(
PStream &in,
vector<T> &v)
01111 {
readSequence(in, v);
return in; }
01112
01113
template <
class T>
inline PStream &
01114 operator<<(PStream &out, const vector<T> &v)
01115 {
writeSequence(out, v);
return out; }
01116
01117
01118
01119
template<
class SetT>
01120 void writeSet(
PStream& out,
const SetT& s)
01121 {
01122
typename SetT::const_iterator it = s.begin();
01123
typename SetT::const_iterator itend = s.end();
01124
01125 out.
put(
'[');
01126
while(it!=itend)
01127 {
01128 out << *it;
01129 ++it;
01130
if (it != itend)
01131 out.
write(
", ");
01132 }
01133 out.
put(
']');
01134 }
01135
01136
template<
class SetT>
01137 void readSet(
PStream& in, SetT& s)
01138 {
01139 s.clear();
01140 in.
skipBlanksAndCommentsAndSeparators();
01141
int c = in.
get();
01142
if(c!=
'[')
01143
PLERROR(
"In readSet(Pstream& in, SetT& s) expected '[' but read %c",c);
01144 in.
skipBlanksAndCommentsAndSeparators();
01145 c = in.
peek();
01146
while(c!=
']')
01147 {
01148
typename SetT::value_type
val;
01149 in >>
val;
01150 in.
skipBlanksAndCommentsAndSeparators();
01151 s.insert(
val);
01152 c = in.
peek();
01153 }
01154 in.
get();
01155 }
01156
01157
template <
class T>
inline PStream &
01158 operator>>(
PStream &in,
set<T> &v)
01159 {
readSet(in, v);
return in; }
01160
01161
template <
class T>
inline PStream &
01162 operator<<(PStream &out, const set<T> &v)
01163 {
writeSet(out, v);
return out; }
01164
01165
01166
01167
01168
01169
01170
01171
template <
class T>
01172 inline void load(
const string &filepath, T &x)
01173 {
01174 ifstream in_(filepath.c_str());
01175
if (!in_)
01176
PLERROR(
"Could not open file \"%s\" for reading", filepath.c_str());
01177
PStream in(&in_);
01178 in >>
x;
01179 }
01180
01182
template<
class T>
01183 inline void save(
const string& filepath,
const T& x)
01184 {
01185
force_mkdir_for_file(filepath);
01186
01187 ofstream out_(filepath.c_str());
01188
if(!out_)
01189
PLERROR(
"Could not open file %s for writing",filepath.c_str());
01190
01191
PStream out(&out_);
01192 out <<
x;
01193 }
01194
01195
01196
01197
01198
01199 class PIFStream:
public PStream
01200 {
01201
public:
01202 PIFStream(
const string& fname, ios_base::openmode m = ios_base::in)
01203 :
PStream(new ifstream(
fname.
c_str()),true)
01204 {}
01205 };
01206
01207 class POFStream:
public PStream
01208 {
01209
public:
01210 POFStream(
const string& fname, ios_base::openmode m = ios_base::out | ios_base::trunc)
01211 :
PStream(new ofstream(
fname.
c_str()),true)
01212 {}
01213 };
01214
01215
01216
01217
01218
01219
01220 class PIStringStream:
public PStream
01221 {
01222
public:
01223 PIStringStream(
const string& s)
01224 :
PStream(new istringstream(s)) {}
01225 };
01226
01227
01228 }
01229
01230
#endif //ndef PStream_INC