PLearn 0.1
|
00001 // -*- C++ -*- 00002 00003 // PStream.cc 00004 // Copyright (C) 1998 Pascal Vincent 00005 // Copyright (C) 1999-2001 Pascal Vincent, Yoshua Bengio and 00006 // University of Montreal 00007 // Copyright (C) 2002 Frederic Morin, Xavier Saint-Mleux, Pascal Vincent 00008 // Copyright (C) 2007 Xavier Saint-Mleux, ApSTAT Technologies inc. 00009 // 00010 // Redistribution and use in source and binary forms, with or without 00011 // modification, are permitted provided that the following conditions are met: 00012 // 00013 // 1. Redistributions of source code must retain the above copyright 00014 // notice, this list of conditions and the following disclaimer. 00015 // 00016 // 2. Redistributions in binary form must reproduce the above copyright 00017 // notice, this list of conditions and the following disclaimer in the 00018 // documentation and/or other materials provided with the distribution. 00019 // 00020 // 3. The name of the authors may not be used to endorse or promote 00021 // products derived from this software without specific prior written 00022 // permission. 00023 // 00024 // THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR 00025 // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 00026 // OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN 00027 // NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 00028 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 00029 // TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 00030 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 00031 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 00032 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 00033 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00034 // 00035 // This file is part of the PLearn library. For more information on the PLearn 00036 // library, go to the PLearn Web site at www.plearn.org 00037 00038 #include <limits> 00039 #include "PStream.h" 00040 #include "NullPStreamBuf.h" 00041 #include "PrPStreamBuf.h" 00042 #include <plearn/math/pl_math.h> 00043 #include <nspr/prio.h> 00044 #include <ctype.h> 00045 #include <plearn/io/pl_log.h> 00046 00047 00048 // This is probably an ugly hack to get it to work under Visual Studio. 00049 #if defined(WIN32) && !defined(__CYGWIN__) 00050 #define snprintf _snprintf 00051 #endif 00052 00053 namespace PLearn { 00054 using namespace std; 00055 00056 // Default format string for floats and doubles 00057 const char* PStream::format_float_default = "%.8g"; 00058 //We put 15 decimal. We need 10 for the precision of double 00059 // + 4 as when the g format print as 0.0004... we need more digit. 00060 //Probably 14 was enought, but I put 15 as I was not sur of the border case. 00061 //Old version with 18 decimal printed value as 0.008659999999999999 00062 // are now printed as 0.00866(take less space and are more readable). 00063 const char* PStream::format_double_default = "%.15g"; 00064 bool PStream::windows_endl = false; 00065 // Initialization for pin, pout, ... 00066 00067 PStream& get_pnull() 00068 { 00069 static PStream pnull = new NullPStreamBuf(); 00070 return pnull; 00071 } 00072 00073 PStream pnull = get_pnull(); 00074 00075 PStream& get_pin() 00076 { 00077 static bool initialized = false; 00078 static PStream pin = new 00079 PrPStreamBuf(PR_GetSpecialFD(PR_StandardInput),0); 00080 if(!initialized) 00081 { 00082 pin.setMode(PStream::raw_ascii); // raw_ascii default mode 00083 initialized = true; 00084 } 00085 return pin; 00086 } 00087 00088 PStream pin = get_pin(); 00089 00090 PStream& get_pout() 00091 { 00092 static bool initialized = false; 00093 static PStream pout = new PrPStreamBuf(0, 00094 PR_GetSpecialFD(PR_StandardOutput)); 00095 if(!initialized) 00096 { 00097 pout.setMode(PStream::raw_ascii); // raw_ascii default mode 00098 initialized = true; 00099 } 00100 return pout; 00101 } 00102 00103 PStream pout = get_pout(); 00104 00105 PStream& get_pio() 00106 { 00107 static bool initialized = false; 00108 static PStream pio = new 00109 PrPStreamBuf(PR_GetSpecialFD(PR_StandardInput), 00110 PR_GetSpecialFD(PR_StandardOutput)); 00111 if(!initialized) 00112 { 00113 pio.setMode(PStream::raw_ascii); // raw_ascii default mode 00114 initialized = true; 00115 } 00116 return pio; 00117 } 00118 00119 PStream pio = get_pio(); 00120 00121 PStream& get_perr() 00122 { 00123 static bool initialized = false; 00124 static PStream perr = new PrPStreamBuf(0, 00125 PR_GetSpecialFD(PR_StandardError)); 00126 if(!initialized) 00127 { 00128 perr.setMode(PStream::raw_ascii); // raw_ascii default mode 00129 initialized = true; 00130 perr.setBufferCapacities(0,0,0); // perr is unbuffered by default 00131 } 00132 return perr; 00133 } 00134 00135 PStream perr = get_perr(); 00136 00137 PStream& flush(PStream& out) 00138 { 00139 out.flush(); 00140 return out; 00141 } 00142 00143 PStream& endl(PStream& out) 00144 { 00145 out.endl(); 00146 return out; 00147 } 00148 00149 PStream& ws(PStream& in) 00150 { 00151 switch(in.inmode) { 00152 case PStream::raw_ascii: 00153 case PStream::pretty_ascii: 00154 case PStream::raw_binary: 00155 in.skipBlanks(); 00156 break; 00157 case PStream::plearn_ascii: 00158 case PStream::plearn_binary: 00159 // Also skip comments. 00160 in.skipBlanksAndComments(); 00161 break; 00162 default: 00163 PLERROR("In ws(PStream& in) - in's inmode is not supported"); 00164 } 00165 return in; 00166 } 00167 00168 string pgetline(PStream& in) 00169 { 00170 string line; 00171 in.getline(line); 00172 // remove any trailing \n and \r 00173 string::size_type pos = line.length(); 00174 while(pos>=1 && (line[pos - 1]=='\r' || line[pos - 1]=='\n')) 00175 pos--; 00176 return line.substr(0,pos); 00177 } 00178 00179 PStream::PStream() 00180 :inherited(0), 00181 inmode(plearn_ascii), 00182 outmode(plearn_ascii), 00183 format_float (format_float_default), 00184 format_double(format_double_default), 00185 implicit_storage(true), 00186 compression_mode(compr_none), 00187 remote_plearn_comm(false) 00188 {} 00189 00190 PStream::PStream(streambuftype* sb) 00191 :inherited(sb), 00192 inmode(plearn_ascii), 00193 outmode(plearn_ascii), 00194 format_float (format_float_default), 00195 format_double(format_double_default), 00196 implicit_storage(true), 00197 compression_mode(compr_none), 00198 remote_plearn_comm(false) 00199 {} 00200 00201 00203 PStream::PStream(istream* pin_, bool own_pin_) 00204 :inherited(new StdPStreamBuf(pin_,own_pin_)), 00205 inmode(plearn_ascii), 00206 outmode(plearn_ascii), 00207 format_float (format_float_default), 00208 format_double(format_double_default), 00209 implicit_storage(true), 00210 compression_mode(compr_none), 00211 remote_plearn_comm(false) 00212 {} 00214 00215 PStream::PStream(ostream* pout_, bool own_pout_) 00216 :inherited(new StdPStreamBuf(pout_,own_pout_)), 00217 inmode(plearn_ascii), 00218 outmode(plearn_ascii), 00219 format_float (format_float_default), 00220 format_double(format_double_default), 00221 implicit_storage(true), 00222 compression_mode(compr_none), 00223 remote_plearn_comm(false) 00224 {} 00225 00227 PStream::PStream(iostream* pios_, bool own_pios_) 00228 :inherited(new StdPStreamBuf(pios_,own_pios_)), 00229 inmode(plearn_ascii), 00230 outmode(plearn_ascii), 00231 format_float (format_float_default), 00232 format_double(format_double_default), 00233 implicit_storage(true), 00234 compression_mode(compr_none), 00235 remote_plearn_comm(false) 00236 {} 00237 00239 PStream::PStream(istream* pin_, ostream* pout_, bool own_pin_, bool own_pout_) 00240 :inherited(new StdPStreamBuf(pin_,pout_,own_pin_,own_pout_)), 00241 inmode(plearn_ascii), 00242 outmode(plearn_ascii), 00243 format_float (format_float_default), 00244 format_double(format_double_default), 00245 implicit_storage(true), 00246 compression_mode(compr_none), 00247 remote_plearn_comm(false) 00248 {} 00249 00251 // ~PStream // 00253 PStream::~PStream() 00254 { } 00255 00257 // switchToPLearnOutMode // 00259 PStream::mode_t PStream::switchToPLearnOutMode() 00260 { 00261 mode_t oldmode = outmode; 00262 switch(outmode) 00263 { 00264 case PStream::raw_ascii: 00265 case PStream::pretty_ascii: 00266 outmode = PStream::plearn_ascii; 00267 break; 00268 case PStream::raw_binary: 00269 outmode = PStream::plearn_binary; 00270 break; 00271 default: 00272 break; 00273 } 00274 return oldmode; 00275 } 00276 00278 // parseModeT // 00280 PStream::mode_t PStream::parseModeT(const string& str_mode){ 00281 PStream::mode_t mode; 00282 if(str_mode.empty()) { 00283 PLDEPRECATED("The use of an empty string as PStream mode to default to" 00284 " 'plearn_ascii' is deprecated, please use 'plearn_ascii' " 00285 "directly"); 00286 mode = PStream::plearn_ascii; 00287 } else if(str_mode=="plearn_ascii") 00288 mode = PStream::plearn_ascii; 00289 else if(str_mode=="plearn_binary") 00290 mode = PStream::plearn_binary; 00291 else 00292 PLERROR("In PStream::parseModeT(%s): invalid mode", 00293 str_mode.c_str()); 00294 return mode; 00295 } 00297 // readAll // 00299 00300 string PStream::readAll() 00301 { 00302 const int bufsz= 4096; 00303 char buf[bufsz]; 00304 string s= ""; 00305 int nread= ptr->read(buf, bufsz); 00306 while(nread > 0) 00307 { 00308 s.append(buf, nread); 00309 nread= ptr->read(buf, bufsz); 00310 } 00311 return s; 00312 } 00313 00315 // readExpected // 00317 00318 void PStream::readExpected(char expect) 00319 { 00320 int c = get(); 00321 if(c!=expect) 00322 PLERROR("In readExpected : expected %c, but read %c",expect,c); 00323 } 00324 00325 void PStream::readExpected(char* expect) 00326 { 00327 for(char c = *expect; c!=0; c=*expect++) 00328 readExpected(c); 00329 } 00330 00331 void PStream::readExpected(const string& expect) 00332 { 00333 int l = int(expect.size()); 00334 for(int i=0; i<l; i++) 00335 readExpected(expect[i]); 00336 } 00337 00338 00339 streamsize PStream::readUntil(char* buf, streamsize n, char stop_char) 00340 { 00341 streamsize nread = 0; 00342 00343 while(nread<n) 00344 { 00345 int c = get(); 00346 if(c==EOF) 00347 break; 00348 if((char)c == stop_char) 00349 { 00350 putback(c); 00351 break; 00352 } 00353 *buf++ = (char)c; 00354 ++nread; 00355 } 00356 00357 return nread; 00358 } 00359 00360 streamsize PStream::readUntil(char* buf, streamsize n, const char* stop_chars) 00361 { 00362 streamsize nread = 0; 00363 00364 while(nread<n) 00365 { 00366 int c = get(); 00367 if(c==EOF) 00368 break; 00369 if(strchr(stop_chars, c)) 00370 { 00371 putback(c); 00372 break; 00373 } 00374 *buf++ = (char)c; 00375 ++nread; 00376 } 00377 00378 return nread; 00379 } 00380 00381 int PStream::smartReadUntilNext(const string& stoppingsymbols, string& characters_read, bool ignore_brackets, bool skip_comments) 00382 { 00383 int c; 00384 while( (c=get()) != EOF) 00385 { 00386 if(stoppingsymbols.find(c)!=string::npos) 00387 break; 00388 else if(skip_comments && c=='#') // skip until end of line 00389 skipRestOfLine(); 00390 else 00391 { 00392 if(characters_read.length() == characters_read.capacity()) 00393 characters_read.reserve(characters_read.length()*2); //don't realloc© every time a char is appended... 00394 characters_read+= static_cast<char>(c); 00395 00396 switch(c) 00397 { 00398 case '(': 00399 smartReadUntilNext(")", characters_read, ignore_brackets, skip_comments); 00400 characters_read+= ')'; 00401 break; 00402 case '[': 00403 if(!ignore_brackets) 00404 { 00405 smartReadUntilNext("]", characters_read, ignore_brackets, skip_comments); 00406 characters_read+= ']'; 00407 } 00408 break; 00409 case '{': 00410 smartReadUntilNext("}", characters_read, ignore_brackets, skip_comments); 00411 characters_read+= '}'; 00412 break; 00413 case '"': 00414 smartReadUntilNext("\"", characters_read, ignore_brackets, false); 00415 characters_read+= '"'; 00416 break; 00417 case '\\': // we consider backslash an escape character, 00418 c=get(); // thus the next character is read and appended without being interpreted 00419 if(c!=EOF) 00420 characters_read += static_cast<char>(c); 00421 break; 00422 } 00423 } 00424 } 00425 return c; 00426 } 00427 00429 void PStream::skipAll(const char* chars_to_skip) 00430 { 00431 int c = get(); 00432 while(c!=EOF && strchr(chars_to_skip, c)) 00433 c = get(); 00434 if(c!=EOF) 00435 putback(c); 00436 } 00437 00438 // reads everything until '\n' (also consumes the '\n') 00439 void PStream::skipRestOfLine() 00440 { 00441 int c = get(); 00442 while(c!='\n' && c!=EOF) 00443 c=get(); 00444 } 00445 00446 void PStream::skipBlanks() 00447 { 00448 int c = get(); 00449 while(c!=EOF && (c==' ' || c=='\t' || c=='\n' || c=='\r')) 00450 c = get(); 00451 if(c!=EOF) 00452 putback(c); 00453 } 00454 00455 void PStream::skipBlanksAndComments() 00456 { 00457 int c = get(); 00458 while(c!=EOF) 00459 { 00460 if(c=='#') 00461 skipRestOfLine(); 00462 else if(c!=' ' && c!='\t' && c!='\n' && c!='\r') 00463 break; 00464 c = get(); 00465 } 00466 if(c!=EOF) 00467 putback(c); 00468 } 00469 00470 void PStream::skipBlanksAndCommentsAndSeparators() 00471 { 00472 int c = get(); 00473 while(c!=EOF) 00474 { 00475 if(c=='#') 00476 skipRestOfLine(); 00477 else if(c!=' ' && c!='\t' && c!='\n' && c!='\r' && c!=';' && c!=',') 00478 break; 00479 c = get(); 00480 } 00481 if(c!=EOF) 00482 putback(c); 00483 } 00484 00486 // count // 00488 int PStream::count(char c) { 00489 char ch = get(); 00490 int counter = 0; 00491 while (ch != EOF) { 00492 if (ch == c) 00493 counter++; 00494 ch = get(); 00495 } 00496 return counter; 00497 } 00498 00499 void PStream::writeAsciiHexNum(unsigned char x) 00500 { 00501 int d = x>>4; 00502 put(d<0x0A ?(d+'0') :(d-0x0A+'A')); 00503 d = x & 0x0F; 00504 put(d<0x0A ?(d+'0') :(d-0x0A+'A')); 00505 } 00506 00507 00508 void PStream::writeAsciiNum(char x) 00509 { 00510 char tmpbuf[PSTREAM_BUF_SIZE]; 00511 snprintf(tmpbuf, sizeof(tmpbuf), "%d", (int)x); 00512 write(tmpbuf, streamsize(strlen(tmpbuf))); 00513 } 00514 00515 void PStream::writeAsciiNum(unsigned char x) 00516 { 00517 char tmpbuf[PSTREAM_BUF_SIZE]; 00518 snprintf(tmpbuf, sizeof(tmpbuf), "%d", (int)x); 00519 write(tmpbuf, streamsize(strlen(tmpbuf))); 00520 } 00521 00522 void PStream::writeAsciiNum(signed char x) 00523 { 00524 char tmpbuf[PSTREAM_BUF_SIZE]; 00525 snprintf(tmpbuf, sizeof(tmpbuf), "%d", (int)x); 00526 write(tmpbuf, streamsize(strlen(tmpbuf))); 00527 } 00528 00529 void PStream::writeAsciiNum(short x) 00530 { 00531 char tmpbuf[PSTREAM_BUF_SIZE]; 00532 snprintf(tmpbuf, sizeof(tmpbuf), "%hd", x); 00533 write(tmpbuf, streamsize(strlen(tmpbuf))); 00534 } 00535 00536 void PStream::writeAsciiNum(unsigned short x) 00537 { 00538 char tmpbuf[PSTREAM_BUF_SIZE]; 00539 snprintf(tmpbuf, sizeof(tmpbuf), "%hu", x); 00540 write(tmpbuf, streamsize(strlen(tmpbuf))); 00541 } 00542 00543 void PStream::writeAsciiNum(int x) 00544 { 00545 char tmpbuf[PSTREAM_BUF_SIZE]; 00546 snprintf(tmpbuf, sizeof(tmpbuf), "%d", x); 00547 write(tmpbuf, streamsize(strlen(tmpbuf))); 00548 } 00549 00550 void PStream::writeAsciiNum(unsigned int x) 00551 { 00552 char tmpbuf[PSTREAM_BUF_SIZE]; 00553 snprintf(tmpbuf, sizeof(tmpbuf), "%u", x); 00554 write(tmpbuf, streamsize(strlen(tmpbuf))); 00555 } 00556 00557 void PStream::writeAsciiNum(long x) 00558 { 00559 char tmpbuf[PSTREAM_BUF_SIZE]; 00560 snprintf(tmpbuf, sizeof(tmpbuf), "%ld", x); 00561 write(tmpbuf, streamsize(strlen(tmpbuf))); 00562 } 00563 00564 void PStream::writeAsciiNum(unsigned long x) 00565 { 00566 char tmpbuf[PSTREAM_BUF_SIZE]; 00567 snprintf(tmpbuf, sizeof(tmpbuf), "%lu", x); 00568 write(tmpbuf, streamsize(strlen(tmpbuf))); 00569 } 00570 00571 void PStream::writeAsciiNum(long long x) 00572 { 00573 long long zero(0); 00574 if(x>=zero) 00575 writeAsciiNum((unsigned long long)x); 00576 else 00577 { 00578 put('-'); 00579 writeAsciiNum((unsigned long long) -x); 00580 } 00581 } 00582 00583 void PStream::writeAsciiNum(unsigned long long x) 00584 { 00585 unsigned long long zero(0); 00586 if(x==zero) 00587 put('0'); 00588 else 00589 { 00590 char buf[30]; 00591 char* p = buf+29; 00592 int n = 0; 00593 while(x>zero) 00594 { 00595 *p-- = '0'+char(x%10); 00596 x /= 10; 00597 ++n; 00598 } 00599 ++p; 00600 write(p,n); 00601 } 00602 } 00603 00604 void PStream::writeAsciiNum(float x) 00605 { 00606 if(is_missing(x)) 00607 write("nan"); 00608 else if (isinf(x)) { 00609 if (x < 0) 00610 write("-inf"); 00611 else 00612 write("inf"); 00613 } 00614 else 00615 { 00616 char tmpbuf[PSTREAM_BUF_SIZE]; 00617 snprintf(tmpbuf, sizeof(tmpbuf), format_float, x); 00618 write(tmpbuf, streamsize(strlen(tmpbuf))); 00619 } 00620 } 00621 00622 void PStream::writeAsciiNum(double x) 00623 { 00624 if(is_missing(x)) 00625 write("nan"); 00626 else if (isinf(x)) { 00627 if (x < 0) 00628 write("-inf"); 00629 else 00630 write("inf"); 00631 } 00632 else 00633 { 00634 char tmpbuf[PSTREAM_BUF_SIZE]; 00635 snprintf(tmpbuf, sizeof(tmpbuf), format_double, x); 00636 write(tmpbuf, streamsize(strlen(tmpbuf))); 00637 } 00638 } 00639 00640 void PStream::readAsciiNum(char &x) 00641 { 00642 long dx; 00643 readAsciiNum(dx); 00644 x = char(dx); 00645 } 00646 00647 void PStream::readAsciiNum(unsigned char &x) 00648 { 00649 long dx; 00650 readAsciiNum(dx); 00651 x = (unsigned char)(dx); 00652 } 00653 00654 void PStream::readAsciiNum(signed char &x) 00655 { 00656 long dx; 00657 readAsciiNum(dx); 00658 x = (signed char)(dx); 00659 } 00660 00661 void PStream::readAsciiNum(short &x) 00662 { 00663 long dx; 00664 readAsciiNum(dx); 00665 x = short(dx); 00666 } 00667 00668 void PStream::readAsciiNum(unsigned short &x) 00669 { 00670 unsigned long dx; 00671 readAsciiNum(dx); 00672 x = (unsigned short)(dx); 00673 } 00674 00675 void PStream::readAsciiNum(int &x) 00676 { 00677 long dx; 00678 readAsciiNum(dx); 00679 x = int(dx); 00680 } 00681 00682 void PStream::readAsciiNum(unsigned int &x) 00683 { 00684 unsigned long dx; 00685 readAsciiNum(dx); 00686 x = (unsigned int)(dx); 00687 } 00688 00689 void PStream::readAsciiNum(long &x) 00690 { 00691 skipBlanks(); 00692 x = 0; 00693 char c = get(); 00694 bool negate = false; 00695 if (c == '-') 00696 { 00697 negate = true; 00698 c = get(); 00699 } 00700 else if (c == '+') 00701 c = get(); 00702 00703 if(!isdigit(c)) 00704 PLERROR("In readAsciiNum: not a valid ascii number, expected a digit, but read %c (ascii code %d)",c,c); 00705 00706 do 00707 { 00708 x = x*10 + c-'0'; 00709 c = get(); 00710 } while(isdigit(c)); 00711 00712 unget(); 00713 if(negate) 00714 x = -x; 00715 } 00716 00717 void PStream::readAsciiNum(unsigned long &x) 00718 { 00719 skipBlanks(); 00720 x = 0; 00721 char c = get(); 00722 while(isdigit(c)) 00723 { 00724 x = x*10 + c-'0'; 00725 c = get(); 00726 } 00727 unget(); 00728 } 00729 00730 void PStream::readAsciiNum(long long &x) 00731 { 00732 skipBlanks(); 00733 x = 0; 00734 char c = get(); 00735 bool negate = false; 00736 if (c == '-') 00737 { 00738 negate = true; 00739 c = get(); 00740 } 00741 else if (c == '+') 00742 c = get(); 00743 00744 if(!isdigit(c)) 00745 PLERROR("In readAsciiNum: not a valid ascii number, expected a digit, but read %c (ascii code %d)",c,c); 00746 00747 do 00748 { 00749 x *= 10; 00750 x += c-'0'; 00751 c = get(); 00752 } while(isdigit(c)); 00753 00754 unget(); 00755 if(negate) 00756 x = -x; 00757 } 00758 00759 void PStream::readAsciiNum(unsigned long long &x) 00760 { 00761 skipBlanks(); 00762 x = 0; 00763 char c = get(); 00764 while(isdigit(c)) 00765 { 00766 x *= 10; 00767 x += c-'0'; 00768 c = get(); 00769 } 00770 unget(); 00771 } 00772 00773 void PStream::readAsciiNum(float &x) 00774 { 00775 double dx; 00776 readAsciiNum(dx); 00777 x = float(dx); 00778 } 00779 00780 void PStream::readAsciiNum(double &x) 00781 { 00782 static const char* error_msg = "Bug while reading file and expecting a double"; 00783 char tmpbuf[PSTREAM_BUF_SIZE]; 00784 skipBlanks(); 00785 int l=0; 00786 bool opposite = false; 00787 00788 char c = get(); 00789 if (c == '-') { 00790 tmpbuf[l++] = c; 00791 opposite = true; 00792 c = get(); 00793 } 00794 else if (c == '+') // skip + sign 00795 c = get(); 00796 00797 bool E_seen= false; 00798 bool sign_seen= false; 00799 bool dot_seen= false; 00800 00801 switch(c) 00802 { 00803 case '?': 00804 x = MISSING_VALUE; 00805 break; 00806 case 'n': 00807 case 'N': 00808 if(toupper(get())=='A' && toupper(get())=='N') 00809 x = MISSING_VALUE; 00810 else 00811 PLERROR(error_msg); 00812 break; 00813 case 'i': 00814 case 'I': 00815 if (toupper(get())=='N' && toupper(get())=='F') 00816 { 00817 x = numeric_limits<double>::infinity(); 00818 if(opposite) 00819 x = -x; 00820 } 00821 else 00822 PLERROR(error_msg); 00823 break ; 00824 default: 00825 while(isdigit(c) 00826 || ((c=='e' || c=='E') && !E_seen) //only one E 00827 || ((c=='-' || c=='+') && E_seen && !sign_seen)//one sign, after E 00828 || (c=='.' && !E_seen && !dot_seen))//one dot, before E 00829 { 00830 if(c=='e' || c=='E') E_seen= true; 00831 if(c=='+' || c=='-') sign_seen= true; 00832 if(c=='.') dot_seen= true; 00833 tmpbuf[l++] = c; 00834 c = get(); 00835 } 00836 tmpbuf[l] = '\0'; 00837 unget(); 00838 sscanf(tmpbuf,"%lf",&x); 00839 if(l==0) 00840 PLERROR("In PStream::readAsciiNum - we read (%c) while we " 00841 "expected a digit", c); 00842 break; 00843 } 00844 } 00845 00846 00847 PStream& PStream::operator=(const PStream& pios) 00848 { 00849 if(this != &pios) 00850 { 00851 inherited::operator=((const inherited&)pios); 00852 inmode = pios.inmode; 00853 outmode = pios.outmode; 00854 implicit_storage = pios.implicit_storage; 00855 compression_mode = pios.compression_mode; 00856 } 00857 return *this; 00858 } 00859 00860 // Implementation of operator>>'s 00861 00862 PStream& PStream::operator>>(char &x) 00863 { 00864 switch(inmode) 00865 { 00866 case raw_binary: 00867 get(x); 00868 break; 00869 case pretty_ascii: 00870 case raw_ascii: 00871 skipBlanks(); 00872 get(x); 00873 break; 00874 case plearn_ascii: 00875 case plearn_binary: 00876 skipBlanksAndCommentsAndSeparators(); 00877 get(x); 00878 if (x == '\'') // ascii case (between single quotes) 00879 { 00880 get(x); 00881 get(); 00882 } 00883 else if (x == 0x01) // plearn_binary case 00884 get(x); 00885 break; 00886 default: 00887 PLERROR("In PStream::operator>> unknown inmode!!!!!!!!!"); 00888 break; 00889 } 00890 return *this; 00891 } 00892 00893 PStream& PStream::operator>>(signed char &x) 00894 { 00895 char c; 00896 operator>>(c); 00897 x = (signed char)c; 00898 return *this; 00899 } 00900 00901 PStream& PStream::operator>>(unsigned char &x) 00902 { 00903 switch(inmode) 00904 { 00905 case raw_binary: 00906 read(reinterpret_cast<char *>(&x), sizeof(unsigned char)); 00907 break; 00908 case raw_ascii: 00909 skipBlanks(); 00910 read(reinterpret_cast<char *>(&x), sizeof(unsigned char)); 00911 break; 00912 case pretty_ascii: 00913 case plearn_ascii: 00914 case plearn_binary: 00915 { 00916 skipBlanksAndCommentsAndSeparators(); 00917 char c = get(); 00918 if (c == '\'') // ascii 00919 { 00920 read(reinterpret_cast<char *>(&x), sizeof(unsigned char)); 00921 get(); 00922 } 00923 else if (c == 0x02) // plearn_binary 00924 read(reinterpret_cast<char *>(&x), sizeof(unsigned char)); 00925 else 00926 x = (unsigned char)c; 00927 break; 00928 } 00929 default: 00930 PLERROR("In PStream::operator>> unknown inmode!!!!!!!!!"); 00931 break; 00932 } 00933 return *this; 00934 } 00935 00936 PStream& PStream::operator>>(char *x) 00937 { 00938 if(!x) 00939 PLERROR("In PStream::operator>>(char*) character array must already be allocated to put the read string in"); 00940 00941 switch(inmode) 00942 { 00943 case PStream::raw_ascii: 00944 case PStream::raw_binary: 00945 case PStream::pretty_ascii: 00946 { 00947 skipBlanksAndComments(); 00948 int i=0; // pos within the string 00949 int c = get(); 00950 while (c!=EOF && wordseparators().find(c)==string::npos) // as long as we don't meet a wordseparator (or eof)... 00951 { 00952 x[i++] = static_cast<char>(c); 00953 c = get(); 00954 } 00955 x[i++] = 0; 00956 unget(); 00957 } 00958 break; 00959 case PStream::plearn_ascii: 00960 case PStream::plearn_binary: 00961 { 00962 skipBlanksAndComments(); 00963 int c = peek(); 00964 int i=0; // pos within the string 00965 if(c=='"') // it's a quoted string "..." 00966 { 00967 c = get(); // skip the quote 00968 c = get(); // get the next character 00969 while(c!='"' && c!=EOF) 00970 { 00971 if(c=='\\') // escaped character 00972 { 00973 c = get(); 00974 switch (c) 00975 { 00976 case 'n': 00977 x[i++] = '\n'; 00978 break; 00979 case 't': 00980 x[i++] = '\t'; 00981 break; 00982 case 'r': 00983 x[i++] = '\r'; 00984 break; 00985 case '0': 00986 x[i++] = '\0'; 00987 break; 00988 case 'a': 00989 x[i++] = '\a'; 00990 break; 00991 case 'b': 00992 x[i++] = '\b'; 00993 break; 00994 case 'v': 00995 x[i++] = '\v'; 00996 break; 00997 case 'f': 00998 x[i++] = '\f'; 00999 break; 01000 01001 default: 01002 x[i++] = static_cast<char>(c); 01003 break; 01004 } 01005 } 01006 else 01007 x[i++]= static_cast<char>(c); 01008 01009 c = get(); 01010 } 01011 if(c==EOF) 01012 PLERROR("In read(istream&, char*) unterminated quoted string"); 01013 if(!isspace(c)) 01014 putback(c); 01015 } 01016 else // it's a single word without quotes 01017 { 01018 c= get(); 01019 while(c != EOF && wordseparators().find(c)==string::npos) // as long as we don't meet a wordseparator (or eof)... 01020 { 01021 x[i++]= static_cast<char>(c); 01022 c= get(); 01023 } 01024 if(!isspace(c)) 01025 unget(); 01026 } 01027 x[i++] = 0; 01028 } 01029 break; 01030 default: 01031 PLERROR("In PStream::operator>> unknown inmode!!!!!!!!!"); 01032 break; 01033 } 01034 return *this; 01035 } 01036 01037 PStream& PStream::operator>>(string& x) 01038 { 01039 switch(inmode) 01040 { 01041 case PStream::raw_ascii: 01042 case PStream::raw_binary: 01043 case PStream::pretty_ascii: 01044 { 01045 skipBlanksAndComments(); 01046 int c = get(); 01047 x.clear(); 01048 // As long as we don't meet a (raw) wordseparator (or eof)... 01049 while (c!=EOF && raw_wordseparators().find(c)==string::npos) 01050 { 01051 x += static_cast<char>(c); 01052 c = get(); 01053 } 01054 unget(); 01055 } 01056 break; 01057 case PStream::plearn_ascii: 01058 case PStream::plearn_binary: 01059 { 01060 skipBlanksAndComments(); 01061 int c = peek(); 01062 if(c=='"') // it's a quoted string "..." 01063 { 01064 x.resize(0); 01065 c = get(); // skip the quote 01066 c = get(); // get the next character 01067 while(c!='"' && c!=EOF) 01068 { 01069 if(c=='\\') // escaped character 01070 { 01071 c = get(); 01072 switch (c) 01073 { 01074 case 'n': 01075 x += '\n'; 01076 break; 01077 case 't': 01078 x += '\t'; 01079 break; 01080 case 'r': 01081 x += '\r'; 01082 break; 01083 case '0': 01084 x += '\0'; 01085 break; 01086 case 'a': 01087 x += '\a'; 01088 break; 01089 case 'b': 01090 x += '\b'; 01091 break; 01092 case 'v': 01093 x += '\v'; 01094 break; 01095 case 'f': 01096 x += '\f'; 01097 break; 01098 01099 default: 01100 x += static_cast<char>(c); 01101 break; 01102 } 01103 } 01104 else 01105 x += static_cast<char>(c); 01106 01107 c = get(); 01108 } 01109 if(c==EOF) 01110 PLERROR("In read(istream&, string&) unterminated quoted string"); 01111 c = get(); 01112 if(!isspace(c)) // skip following blank if any 01113 unget(); 01114 } 01115 else // it's a single word without quotes 01116 { 01117 x.resize(0); 01118 c= get(); 01119 while(c != EOF && wordseparators().find(c)==string::npos) // as long as we don't meet a wordseparator (or eof)... 01120 { 01121 x+= static_cast<char>(c); 01122 c= get(); 01123 } 01124 if(!isspace(c)) 01125 unget(); 01126 } 01127 } 01128 break; 01129 default: 01130 PLERROR("In PStream::operator>> unknown inmode!!!!!!!!!"); 01131 break; 01132 } 01133 return *this; 01134 } 01135 01136 PStream& PStream::operator>>(bool &x) 01137 { 01138 int parsed = -1; 01139 01140 char c; 01141 switch(inmode) 01142 { 01143 case raw_ascii: 01144 case pretty_ascii: 01145 case raw_binary: 01146 case plearn_ascii: 01147 case plearn_binary: 01148 skipBlanksAndCommentsAndSeparators(); 01149 c = get(); 01150 if(c=='1') 01151 parsed = 1; 01152 01153 else if(c=='0') 01154 parsed = 0; 01155 01156 else if(c=='T') 01157 { 01158 char r = get(); 01159 char u = get(); 01160 char e = get(); 01161 if ( r == 'r' && u == 'u' && e == 'e' ) 01162 parsed = 1; 01163 } 01164 01165 else if(c=='F') 01166 { 01167 char a = get(); 01168 char l = get(); 01169 char s = get(); 01170 char e = get(); 01171 if ( a == 'a' && l == 'l' && s == 's' && e == 'e' ) 01172 parsed = 0; 01173 } 01174 01175 if ( parsed == -1 ) 01176 PLERROR("In PStream::operator>>(bool &x) wrong format for bool, must be one " 01177 "of characters 0 or 1 or unquoted strings True or False" ); 01178 else 01179 x = (parsed != 0); 01180 break; 01181 01182 default: 01183 PLERROR("In PStream::operator>> unknown inmode!!!!!!!!!"); 01184 break; 01185 } 01186 return *this; 01187 } 01188 01189 PStream& PStream::operator>>(short &x) 01190 { 01191 switch(inmode) 01192 { 01193 case raw_ascii: 01194 case pretty_ascii: 01195 skipBlanks(); 01196 readAsciiNum(x); 01197 break; 01198 case raw_binary: 01199 read(reinterpret_cast<char *>(&x), sizeof(short)); 01200 break; 01201 case plearn_ascii: 01202 case plearn_binary: 01203 { 01204 skipBlanksAndCommentsAndSeparators(); 01205 int c = get(); 01206 if(c>0x00 && c<0x20) // plearn_binary 01207 { 01208 readBinaryNum(x, c); 01209 } 01210 else // plearn_ascii 01211 { 01212 unget(); 01213 readAsciiNum(x); 01214 } 01215 break; 01216 } 01217 default: 01218 PLERROR("In PStream::operator>> unknown inmode!!!!!!!!!"); 01219 break; 01220 } 01221 return *this; 01222 } 01223 01224 PStream& PStream::operator>>(unsigned short &x) 01225 { 01226 switch(inmode) 01227 { 01228 case raw_ascii: 01229 case pretty_ascii: 01230 skipBlanks(); 01231 readAsciiNum(x); 01232 break; 01233 case raw_binary: 01234 read(reinterpret_cast<char *>(&x), sizeof(unsigned short)); 01235 break; 01236 case plearn_ascii: 01237 case plearn_binary: 01238 { 01239 skipBlanksAndCommentsAndSeparators(); 01240 int c = get(); 01241 if(c>0x00 && c<0x20) // plearn_binary 01242 { 01243 readBinaryNum(x, c); 01244 } 01245 else // plearn_ascii 01246 { 01247 unget(); 01248 readAsciiNum(x); 01249 } 01250 break; 01251 } 01252 default: 01253 PLERROR("In PStream::operator>> unknown inmode!!!!!!!!!"); 01254 break; 01255 } 01256 return *this; 01257 } 01258 01259 PStream& PStream::operator>>(int &x) 01260 { 01261 switch(inmode) 01262 { 01263 case raw_ascii: 01264 case pretty_ascii: 01265 skipBlanks(); 01266 readAsciiNum(x); 01267 break; 01268 case raw_binary: 01269 read(reinterpret_cast<char *>(&x), sizeof(int)); 01270 break; 01271 case plearn_ascii: 01272 case plearn_binary: 01273 { 01274 skipBlanksAndCommentsAndSeparators(); 01275 int c = get(); 01276 if(c>0x00 && c<0x20) // plearn_binary 01277 { 01278 readBinaryNum(x, c); 01279 } 01280 else // plearn_ascii 01281 { 01282 unget(); 01283 readAsciiNum(x); 01284 } 01285 break; 01286 } 01287 default: 01288 PLERROR("In PStream::operator>> unknown inmode!!!!!!!!!"); 01289 break; 01290 } 01291 return *this; 01292 } 01293 01294 PStream& PStream::operator>>(unsigned int &x) 01295 { 01296 switch(inmode) 01297 { 01298 case raw_ascii: 01299 case pretty_ascii: 01300 skipBlanks(); 01301 readAsciiNum(x); 01302 break; 01303 case raw_binary: 01304 read(reinterpret_cast<char *>(&x), sizeof(unsigned int)); 01305 break; 01306 case plearn_ascii: 01307 case plearn_binary: 01308 { 01309 skipBlanksAndCommentsAndSeparators(); 01310 int c = get(); 01311 if(c>0x00 && c<0x20) // plearn_binary 01312 { 01313 readBinaryNum(x, c); 01314 } 01315 else // plearn_ascii 01316 { 01317 unget(); 01318 readAsciiNum(x); 01319 } 01320 break; 01321 } 01322 default: 01323 PLERROR("In PStream::operator>> unknown inmode!!!!!!!!!"); 01324 break; 01325 } 01326 return *this; 01327 } 01328 01329 PStream& PStream::operator>>(long &x) 01330 { 01331 switch(inmode) 01332 { 01333 case raw_ascii: 01334 case pretty_ascii: 01335 skipBlanks(); 01336 readAsciiNum(x); 01337 break; 01338 case raw_binary: 01339 read(reinterpret_cast<char *>(&x), sizeof(long)); 01340 break; 01341 case plearn_ascii: 01342 case plearn_binary: 01343 { 01344 skipBlanksAndCommentsAndSeparators(); 01345 int c = get(); 01346 if(c>0x00 && c<0x20) // plearn_binary 01347 { 01348 readBinaryNum(x, c); 01349 } 01350 else // plearn_ascii 01351 { 01352 unget(); 01353 readAsciiNum(x); 01354 } 01355 break; 01356 } 01357 default: 01358 PLERROR("In PStream::operator>> unknown inmode!!!!!!!!!"); 01359 break; 01360 } 01361 return *this; 01362 } 01363 01364 PStream& PStream::operator>>(unsigned long &x) 01365 { 01366 switch(inmode) 01367 { 01368 case raw_ascii: 01369 case pretty_ascii: 01370 skipBlanks(); 01371 readAsciiNum(x); 01372 break; 01373 case raw_binary: 01374 read(reinterpret_cast<char *>(&x), sizeof(unsigned long)); 01375 break; 01376 case plearn_ascii: 01377 case plearn_binary: 01378 { 01379 skipBlanksAndCommentsAndSeparators(); 01380 int c = get(); 01381 if(c>0x00 && c<0x20) // plearn_binary 01382 { 01383 readBinaryNum(x, c); 01384 } 01385 else // plearn_ascii 01386 { 01387 unget(); 01388 readAsciiNum(x); 01389 } 01390 break; 01391 } 01392 default: 01393 PLERROR("In PStream::operator>> unknown inmode!!!!!!!!!"); 01394 break; 01395 } 01396 return *this; 01397 } 01398 01399 PStream& PStream::operator>>(long long &x) 01400 { 01401 switch(inmode) 01402 { 01403 case raw_ascii: 01404 case pretty_ascii: 01405 skipBlanks(); 01406 readAsciiNum(x); 01407 break; 01408 case raw_binary: 01409 read(reinterpret_cast<char *>(&x), sizeof(long long)); 01410 break; 01411 case plearn_ascii: 01412 case plearn_binary: 01413 { 01414 skipBlanksAndCommentsAndSeparators(); 01415 int c = get(); 01416 if(c>0x00 && c<0x20) // plearn_binary 01417 { 01418 readBinaryNum(x, c); 01419 } 01420 else // plearn_ascii 01421 { 01422 unget(); 01423 readAsciiNum(x); 01424 } 01425 break; 01426 } 01427 default: 01428 PLERROR("In PStream::operator>> unknown inmode!!!!!!!!!"); 01429 break; 01430 } 01431 return *this; 01432 } 01433 01434 PStream& PStream::operator>>(unsigned long long &x) 01435 { 01436 switch(inmode) 01437 { 01438 case raw_ascii: 01439 case pretty_ascii: 01440 skipBlanks(); 01441 readAsciiNum(x); 01442 break; 01443 case raw_binary: 01444 read(reinterpret_cast<char *>(&x), sizeof(unsigned long long)); 01445 break; 01446 case plearn_ascii: 01447 case plearn_binary: 01448 { 01449 skipBlanksAndCommentsAndSeparators(); 01450 int c = get(); 01451 if(c>0x00 && c<0x20) // plearn_binary 01452 { 01453 readBinaryNum(x, c); 01454 } 01455 else // plearn_ascii 01456 { 01457 unget(); 01458 readAsciiNum(x); 01459 } 01460 break; 01461 } 01462 default: 01463 PLERROR("In PStream::operator>> unknown inmode!!!!!!!!!"); 01464 break; 01465 } 01466 return *this; 01467 } 01468 01469 PStream& PStream::operator>>(float &x) 01470 { 01471 switch(inmode) 01472 { 01473 case raw_ascii: 01474 case pretty_ascii: 01475 skipBlanks(); 01476 readAsciiNum(x); 01477 break; 01478 case raw_binary: 01479 read(reinterpret_cast<char *>(&x), sizeof(float)); 01480 break; 01481 case plearn_ascii: 01482 case plearn_binary: 01483 { 01484 skipBlanksAndCommentsAndSeparators(); 01485 int c = get(); 01486 if(c>0x00 && c<0x20) // plearn_binary 01487 { 01488 readBinaryNum(x, c); 01489 } 01490 else // plearn_ascii 01491 { 01492 unget(); 01493 readAsciiNum(x); 01494 } 01495 break; 01496 } 01497 default: 01498 PLERROR("In PStream::operator>> unknown inmode!!!!!!!!!"); 01499 break; 01500 } 01501 return *this; 01502 } 01503 01504 PStream& PStream::operator>>(double &x) 01505 { 01506 switch(inmode) 01507 { 01508 case raw_ascii: 01509 case pretty_ascii: 01510 skipBlanks(); 01511 readAsciiNum(x); 01512 break; 01513 case raw_binary: 01514 read(reinterpret_cast<char *>(&x), sizeof(double)); 01515 break; 01516 case plearn_ascii: 01517 case plearn_binary: 01518 { 01519 skipBlanksAndCommentsAndSeparators(); 01520 int c = get(); 01521 if(c>0x00 && c<0x20) // plearn_binary 01522 { 01523 readBinaryNum(x, c); 01524 } 01525 else // ascii 01526 { 01527 unget(); 01528 readAsciiNum(x); 01529 } 01530 break; 01531 } 01532 default: 01533 PLERROR("In PStream::operator>> unknown inmode!!!!!!!!!"); 01534 break; 01535 } 01536 return *this; 01537 } 01538 01539 01540 // Implementation of operator<<'s 01541 01542 PStream& PStream::operator<<(char x) 01543 { 01544 switch(outmode) 01545 { 01546 case raw_ascii: 01547 case raw_binary: 01548 case pretty_ascii: 01549 put(x); 01550 break; 01551 case plearn_ascii: 01552 put('\''); 01553 put(x); 01554 put('\''); 01555 put(' '); 01556 break; 01557 case plearn_binary: 01558 writeBinaryNum(x); 01559 break; 01560 default: 01561 PLERROR("In PStream::operator<< unknown outmode!!!!!!!!!"); 01562 break; 01563 } 01564 return *this; 01565 } 01566 01567 PStream& PStream::operator<<(signed char x) 01568 { 01569 operator<<(char(x)); 01570 return *this; 01571 } 01572 01573 PStream& PStream::operator<<(unsigned char x) 01574 { 01575 switch(outmode) 01576 { 01577 case raw_ascii: 01578 put(x); 01579 put(' '); 01580 break; 01581 case raw_binary: 01582 put(x); 01583 break; 01584 case pretty_ascii: 01585 case plearn_ascii: 01586 put('\''); 01587 put(x); 01588 put('\''); 01589 put(' '); 01590 break; 01591 case plearn_binary: 01592 writeBinaryNum(x); 01593 break; 01594 default: 01595 PLERROR("In PStream::operator<< unknown outmode!!!!!!!!!"); 01596 break; 01597 } 01598 return *this; 01599 } 01600 01601 PStream& PStream::operator<<(const char *x) 01602 { 01603 int l = (int)strlen(x); 01604 switch(outmode) 01605 { 01606 case PStream::raw_ascii: 01607 case PStream::pretty_ascii: 01608 case PStream::raw_binary: 01609 write(x); 01610 break; 01611 01612 case PStream::plearn_ascii: 01613 case PStream::plearn_binary: 01614 { 01615 put('"'); 01616 for(int i=0; i<l; i++) 01617 { 01618 char c = x[i]; 01619 if(c=='"' || c=='\\') // escape quote and backslash 01620 put('\\'); 01621 put(c); 01622 } 01623 put('"'); 01624 put(' '); 01625 } 01626 break; 01627 01628 default: 01629 PLERROR("In PStream::operator<< unknown outmode!!!!!!!!!"); 01630 break; 01631 } 01632 return *this; 01633 } 01634 01635 PStream& PStream::operator<<(const void* x) 01636 { 01637 switch(outmode) 01638 { 01639 case PStream::raw_ascii: 01640 case PStream::pretty_ascii: 01641 case PStream::raw_binary: 01642 case PStream::plearn_ascii: 01643 case PStream::plearn_binary: 01644 { 01645 char buffer[1000]; 01646 snprintf(buffer, 1000, "%p ", x); 01647 buffer[999] = '\0'; 01648 write(buffer); 01649 break; 01650 } 01651 default: 01652 PLERROR("In PStream::operator<< unknown outmode!!!!!!!!!"); 01653 break; 01654 } 01655 return *this; 01656 } 01657 01658 01659 // TODO What if the string contains a word separator ?? 01660 PStream& PStream::operator<<(const string &x) 01661 { 01662 const char* array = x.c_str(); 01663 operator<<(array); 01664 return *this; 01665 } 01666 01667 PStream& PStream::operator<<(bool x) 01668 { 01669 switch(outmode) 01670 { 01671 case plearn_ascii: 01672 if(x) 01673 put('1'); 01674 else 01675 put('0'); 01676 put(' '); 01677 break; 01678 case raw_ascii: 01679 case pretty_ascii: 01680 case raw_binary: 01681 case plearn_binary: 01682 if(x) 01683 put('1'); 01684 else 01685 put('0'); 01686 break; 01687 default: 01688 PLERROR("In PStream::operator<< unknown outmode!!!!!!!!!"); 01689 break; 01690 } 01691 return *this; 01692 } 01693 01694 PStream& PStream::operator<<(short x) 01695 { 01696 switch(outmode) 01697 { 01698 case raw_binary: 01699 write(reinterpret_cast<char *>(&x), sizeof(short)); 01700 break; 01701 case raw_ascii: 01702 case pretty_ascii: 01703 writeAsciiNum(x); 01704 break; 01705 case plearn_ascii: 01706 writeAsciiNum(x); 01707 put(' '); 01708 break; 01709 case plearn_binary: 01710 writeBinaryNum(x); 01711 break; 01712 default: 01713 PLERROR("In PStream::operator<< unknown outmode!!!!!!!!!"); 01714 break; 01715 } 01716 return *this; 01717 } 01718 01719 PStream& PStream::operator<<(unsigned short x) 01720 { 01721 switch(outmode) 01722 { 01723 case raw_binary: 01724 write(reinterpret_cast<char *>(&x), sizeof(unsigned short)); 01725 break; 01726 case raw_ascii: 01727 case pretty_ascii: 01728 writeAsciiNum(x); 01729 break; 01730 case plearn_ascii: 01731 writeAsciiNum(x); 01732 put(' '); 01733 break; 01734 case plearn_binary: 01735 writeBinaryNum(x); 01736 break; 01737 default: 01738 PLERROR("In PStream::operator<< unknown outmode!!!!!!!!!"); 01739 break; 01740 } 01741 return *this; 01742 } 01743 01744 PStream& PStream::operator<<(int x) 01745 { 01746 switch(outmode) 01747 { 01748 case raw_binary: 01749 write(reinterpret_cast<char *>(&x), sizeof(int)); 01750 break; 01751 case raw_ascii: 01752 case pretty_ascii: 01753 writeAsciiNum(x); 01754 break; 01755 case plearn_ascii: 01756 writeAsciiNum(x); 01757 put(' '); 01758 break; 01759 case plearn_binary: 01760 writeBinaryNum(x); 01761 break; 01762 default: 01763 PLERROR("In PStream::operator<< unknown outmode!!!!!!!!!"); 01764 break; 01765 } 01766 return *this; 01767 } 01768 01769 PStream& PStream::operator<<(unsigned int x) 01770 { 01771 switch(outmode) 01772 { 01773 case raw_binary: 01774 write(reinterpret_cast<char *>(&x), sizeof(unsigned int)); 01775 break; 01776 case raw_ascii: 01777 case pretty_ascii: 01778 writeAsciiNum(x); 01779 break; 01780 case plearn_ascii: 01781 writeAsciiNum(x); 01782 put(' '); 01783 break; 01784 case plearn_binary: 01785 writeBinaryNum(x); 01786 break; 01787 default: 01788 PLERROR("In PStream::operator<< unknown outmode!!!!!!!!!"); 01789 break; 01790 } 01791 return *this; 01792 } 01793 01794 PStream& PStream::operator<<(long x) 01795 { 01796 switch(outmode) 01797 { 01798 case raw_binary: 01799 write(reinterpret_cast<char *>(&x), sizeof(long)); 01800 break; 01801 case raw_ascii: 01802 case pretty_ascii: 01803 writeAsciiNum(x); 01804 break; 01805 case plearn_ascii: 01806 writeAsciiNum(x); 01807 put(' '); 01808 break; 01809 case plearn_binary: 01810 writeBinaryNum(x); 01811 break; 01812 default: 01813 PLERROR("In PStream::operator<< unknown outmode!!!!!!!!!"); 01814 break; 01815 } 01816 return *this; 01817 } 01818 01819 PStream& PStream::operator<<(unsigned long x) 01820 { 01821 switch(outmode) 01822 { 01823 case raw_binary: 01824 write(reinterpret_cast<char *>(&x), sizeof(unsigned long)); 01825 break; 01826 case raw_ascii: 01827 case pretty_ascii: 01828 writeAsciiNum(x); 01829 break; 01830 case plearn_ascii: 01831 writeAsciiNum(x); 01832 put(' '); 01833 break; 01834 case plearn_binary: 01835 writeBinaryNum(x); 01836 break; 01837 default: 01838 PLERROR("In PStream::operator<< unknown outmode!!!!!!!!!"); 01839 break; 01840 } 01841 return *this; 01842 } 01843 01844 PStream& PStream::operator<<(long long x) 01845 { 01846 switch(outmode) 01847 { 01848 case raw_binary: 01849 write(reinterpret_cast<char *>(&x), sizeof(long long)); 01850 break; 01851 case raw_ascii: 01852 case pretty_ascii: 01853 writeAsciiNum(x); 01854 break; 01855 case plearn_ascii: 01856 writeAsciiNum(x); 01857 put(' '); 01858 break; 01859 case plearn_binary: 01860 writeBinaryNum(x); 01861 break; 01862 default: 01863 PLERROR("In PStream::operator<< unknown outmode!!!!!!!!!"); 01864 break; 01865 } 01866 return *this; 01867 } 01868 01869 PStream& PStream::operator<<(unsigned long long x) 01870 { 01871 switch(outmode) 01872 { 01873 case raw_binary: 01874 write(reinterpret_cast<char *>(&x), sizeof(unsigned long long)); 01875 break; 01876 case raw_ascii: 01877 case pretty_ascii: 01878 writeAsciiNum(x); 01879 break; 01880 case plearn_ascii: 01881 writeAsciiNum(x); 01882 put(' '); 01883 break; 01884 case plearn_binary: 01885 writeBinaryNum(x); 01886 break; 01887 default: 01888 PLERROR("In PStream::operator<< unknown outmode!!!!!!!!!"); 01889 break; 01890 } 01891 return *this; 01892 } 01893 01894 PStream& PStream::operator<<(float x) 01895 { 01896 switch(outmode) 01897 { 01898 case raw_binary: 01899 write(reinterpret_cast<char *>(&x), sizeof(float)); 01900 break; 01901 case raw_ascii: 01902 case pretty_ascii: 01903 writeAsciiNum(x); 01904 break; 01905 case plearn_ascii: 01906 writeAsciiNum(x); 01907 put(' '); 01908 break; 01909 case plearn_binary: 01910 writeBinaryNum(x); 01911 break; 01912 default: 01913 PLERROR("In PStream::operator<< unknown outmode!!!!!!!!!"); 01914 break; 01915 } 01916 return *this; 01917 } 01918 01919 PStream& PStream::operator<<(double x) 01920 { 01921 switch(outmode) 01922 { 01923 case raw_binary: 01924 write(reinterpret_cast<char *>(&x), sizeof(double)); 01925 break; 01926 case raw_ascii: 01927 case pretty_ascii: 01928 writeAsciiNum(x); 01929 break; 01930 case plearn_ascii: 01931 writeAsciiNum(x); 01932 put(' '); 01933 break; 01934 case plearn_binary: 01935 writeBinaryNum(x); 01936 break; 01937 default: 01938 PLERROR("In PStream::operator<< unknown outmode!!!!!!!!!"); 01939 break; 01940 } 01941 return *this; 01942 } 01943 01944 01945 void binread_(PStream& in, bool* x, 01946 unsigned int n, unsigned char typecode) 01947 { 01948 if(typecode!=TypeTraits<bool>::little_endian_typecode()) 01949 PLERROR("In binread_ incompatible typecode"); 01950 01951 while(n--) 01952 { 01953 int c = in.get(); 01954 if(c=='0') 01955 *x = false; 01956 else if(c=='1') 01957 *x = true; 01958 else 01959 PLERROR("In binread_(PStream& in, bool* x, unsigned int n, unsigned char typecode): " 01960 "read invalid value for a boolean: should be '1' or '0', not %c", c); 01961 ++x; 01962 } 01963 } 01964 01965 #define IMPLEMENT_NUMTYPE_BINREAD_(NUMTYPE) \ 01966 void binread_(PStream& in, NUMTYPE* x, \ 01967 unsigned int n, unsigned char typecode) \ 01968 { \ 01969 /* If typecode corresponds to NUMTYPE's typecode */ \ 01970 if (typecode==TypeTraits<NUMTYPE>::little_endian_typecode()) \ 01971 { \ 01972 in.read(reinterpret_cast<char*>(x), streamsize(n*sizeof(NUMTYPE))); \ 01973 if (byte_order()==BIG_ENDIAN_ORDER) \ 01974 endianswap(x,n); \ 01975 } \ 01976 else if (typecode==TypeTraits<NUMTYPE>::big_endian_typecode()) \ 01977 { \ 01978 in.read(reinterpret_cast<char*>(x), streamsize(n*sizeof(NUMTYPE))); \ 01979 if (byte_order()==LITTLE_ENDIAN_ORDER) \ 01980 endianswap(x,n); \ 01981 } \ 01982 /* Else, we need to try all the different types */ \ 01983 else if (typecode==TypeTraits<int8_t>::little_endian_typecode()) \ 01984 binread_as<int8_t>(in, x, n, false); \ 01985 else if (typecode==TypeTraits<uint8_t>::little_endian_typecode()) \ 01986 binread_as<uint8_t>(in, x, n, false); \ 01987 else if (typecode==TypeTraits<int16_t>::little_endian_typecode()) \ 01988 binread_as<int16_t>(in, x, n, false); \ 01989 else if (typecode==TypeTraits<uint16_t>::little_endian_typecode()) \ 01990 binread_as<uint16_t>(in, x, n, false); \ 01991 else if (typecode==TypeTraits<int32_t>::little_endian_typecode()) \ 01992 binread_as<int32_t>(in, x, n, false); \ 01993 else if (typecode==TypeTraits<uint32_t>::little_endian_typecode()) \ 01994 binread_as<uint32_t>(in, x, n, false); \ 01995 else if (typecode==TypeTraits<int64_t>::little_endian_typecode()) \ 01996 binread_as<int64_t>(in, x, n, false); \ 01997 else if (typecode==TypeTraits<uint64_t>::little_endian_typecode()) \ 01998 binread_as<uint64_t>(in, x, n, false); \ 01999 else if (typecode==TypeTraits<float>::little_endian_typecode()) \ 02000 binread_as<float>(in, x, n, false); \ 02001 else if (typecode==TypeTraits<double>::little_endian_typecode()) \ 02002 binread_as<double>(in, x, n, false); \ 02003 else \ 02004 PLERROR("In binread_: Unknown typecode '%c' (%x)", \ 02005 typecode, typecode); \ 02006 } 02007 02008 IMPLEMENT_NUMTYPE_BINREAD_(short) 02009 IMPLEMENT_NUMTYPE_BINREAD_(unsigned short) 02010 IMPLEMENT_NUMTYPE_BINREAD_(int) 02011 IMPLEMENT_NUMTYPE_BINREAD_(unsigned int) 02012 IMPLEMENT_NUMTYPE_BINREAD_(long) 02013 IMPLEMENT_NUMTYPE_BINREAD_(unsigned long) 02014 IMPLEMENT_NUMTYPE_BINREAD_(long long) 02015 IMPLEMENT_NUMTYPE_BINREAD_(unsigned long long) 02016 IMPLEMENT_NUMTYPE_BINREAD_(float) 02017 IMPLEMENT_NUMTYPE_BINREAD_(double) 02018 02019 } //end of namespace PLearn 02020 02021 02022 /* 02023 Local Variables: 02024 mode:c++ 02025 c-basic-offset:4 02026 c-file-style:"stroustrup" 02027 c-file-offsets:((innamespace . 0)(inline-open . 0)) 02028 indent-tabs-mode:nil 02029 fill-column:79 02030 End: 02031 */ 02032 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=79 :