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