Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members

PStream.cc

Go to the documentation of this file.
00001 // -*- C++ -*- 00002 00003 // PStream.cc 00004 // Copyright (C) 1998 Pascal Vincent 00005 // Copyright (C) 1999-2001 Pascal Vincent, Yoshua Bengio and University of Montreal 00006 // Copyright (C) 2002 Frederic Morin, Xavier Saint-Mleux, Pascal Vincent 00007 // 00008 // Redistribution and use in source and binary forms, with or without 00009 // modification, are permitted provided that the following conditions are met: 00010 // 00011 // 1. Redistributions of source code must retain the above copyright 00012 // notice, this list of conditions and the following disclaimer. 00013 // 00014 // 2. Redistributions in binary form must reproduce the above copyright 00015 // notice, this list of conditions and the following disclaimer in the 00016 // documentation and/or other materials provided with the distribution. 00017 // 00018 // 3. The name of the authors may not be used to endorse or promote 00019 // products derived from this software without specific prior written 00020 // permission. 00021 // 00022 // THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR 00023 // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 00024 // OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN 00025 // NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 00026 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 00027 // TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 00028 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 00029 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 00030 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 00031 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00032 // 00033 // This file is part of the PLearn library. For more information on the PLearn 00034 // library, go to the PLearn Web site at www.plearn.org 00035 00036 //#include <iomanip> 00037 #include "PStream.h" 00038 //#include "stringutils.h" 00039 //#include "fileutils.h" 00040 #include <plearn/math/pl_math.h> 00041 00042 // norman: 00043 #ifdef WIN32 00044 #define snprintf _snprintf 00045 #endif 00046 00047 namespace PLearn { 00048 using namespace std; 00049 00050 char PStream::tmpbuf[100]; 00051 00052 PStream& flush(PStream& out) 00053 { 00054 out.flush(); 00055 return out; 00056 } 00057 00058 PStream& endl(PStream& out) 00059 { 00060 out.endl(); 00061 return out; 00062 } 00063 00064 PStream& ws(PStream& in) 00065 { 00066 in.skipBlanksAndComments(); 00067 return in; 00068 } 00069 00070 00072 PStream::PStream() 00073 :pstreambuf(new StdPStreamBuf), 00074 inmode(plearn_ascii), 00075 outmode(plearn_ascii), 00076 implicit_storage(true), compression_mode(compr_none) 00077 {} 00079 PStream::PStream(istream* pin_, bool own_pin_) 00080 :pstreambuf(new StdPStreamBuf(pin_,own_pin_)), 00081 inmode(plearn_ascii), 00082 outmode(plearn_ascii), 00083 implicit_storage(true), compression_mode(compr_none) 00084 {} 00086 00087 PStream::PStream(ostream* pout_, bool own_pout_) 00088 :pstreambuf(new StdPStreamBuf(pout_,own_pout_)), 00089 inmode(plearn_ascii), 00090 outmode(plearn_ascii), 00091 implicit_storage(true), compression_mode(compr_none) 00092 {} 00093 00095 PStream::PStream(iostream* pios_, bool own_pios_) 00096 :pstreambuf(new StdPStreamBuf(pios_,own_pios_)), 00097 inmode(plearn_ascii), 00098 outmode(plearn_ascii), 00099 implicit_storage(true), compression_mode(compr_none) 00100 {} 00101 00103 PStream::PStream(istream* pin_, ostream* pout_, bool own_pin_, bool own_pout_) 00104 :pstreambuf(new StdPStreamBuf(pin_,pout_,own_pin_,own_pout_)), 00105 inmode(plearn_ascii), 00106 outmode(plearn_ascii), 00107 implicit_storage(true), compression_mode(compr_none) 00108 {} 00109 00111 PStream::~PStream() 00112 { 00113 } 00114 00115 streamsize PStream::readUntil(char* buf, streamsize n, char stop_char) 00116 { 00117 streamsize nread = 0; 00118 00119 while(nread<n) 00120 { 00121 int c = get(); 00122 if(c==EOF) 00123 break; 00124 if((char)c == stop_char) 00125 { 00126 putback(c); 00127 break; 00128 } 00129 *buf++ = (char)c; 00130 ++nread; 00131 } 00132 00133 return nread; 00134 } 00135 00136 streamsize PStream::readUntil(char* buf, streamsize n, const char* stop_chars) 00137 { 00138 streamsize nread = 0; 00139 00140 while(nread<n) 00141 { 00142 int c = get(); 00143 if(c==EOF) 00144 break; 00145 if(strchr(stop_chars, c)) 00146 { 00147 putback(c); 00148 break; 00149 } 00150 *buf++ = (char)c; 00151 ++nread; 00152 } 00153 00154 return nread; 00155 } 00156 00157 int PStream::smartReadUntilNext(const string& stoppingsymbols, string& characters_read, bool ignore_brackets) 00158 { 00159 int c; 00160 while( (c=get()) != EOF) 00161 { 00162 if(stoppingsymbols.find(c)!=string::npos) 00163 break; 00164 else if(c=='#') // skip until end of line 00165 skipRestOfLine(); 00166 else 00167 { 00168 if(characters_read.length() == characters_read.capacity()) 00169 characters_read.reserve(characters_read.length()*2); //don't realloc&copy every time a char is appended... 00170 characters_read+= static_cast<char>(c); 00171 00172 switch(c) 00173 { 00174 case '(': 00175 smartReadUntilNext(")", characters_read, ignore_brackets); 00176 characters_read+= ')'; 00177 break; 00178 case '[': 00179 if(!ignore_brackets) 00180 { 00181 smartReadUntilNext("]", characters_read, ignore_brackets); 00182 characters_read+= ']'; 00183 } 00184 break; 00185 case '{': 00186 smartReadUntilNext("}", characters_read, ignore_brackets); 00187 characters_read+= '}'; 00188 break; 00189 case '"': 00190 smartReadUntilNext("\"", characters_read, ignore_brackets); 00191 characters_read+= '"'; 00192 break; 00193 } 00194 } 00195 } 00196 return c; 00197 } 00198 00200 void PStream::skipAll(const char* chars_to_skip) 00201 { 00202 int c = get(); 00203 while(c!=EOF && strchr(chars_to_skip, c)) 00204 c = get(); 00205 if(c!=EOF) 00206 putback(c); 00207 } 00208 00209 // reads everything until '\n' (also consumes the '\n') 00210 void PStream::skipRestOfLine() 00211 { 00212 int c = get(); 00213 while(c!='\n' && c!=EOF) 00214 c=get(); 00215 } 00216 00217 void PStream::skipBlanks() 00218 { 00219 int c = get(); 00220 while(c!=EOF && (c==' ' || c=='\t' || c=='\n' || c=='\r')) 00221 c = get(); 00222 if(c!=EOF) 00223 putback(c); 00224 } 00225 00226 void PStream::skipBlanksAndComments() 00227 { 00228 int c = get(); 00229 while(c!=EOF) 00230 { 00231 if(c=='#') 00232 skipRestOfLine(); 00233 else if(c!=' ' && c!='\t' && c!='\n' && c!='\r') 00234 break; 00235 c = get(); 00236 } 00237 if(c!=EOF) 00238 putback(c); 00239 } 00240 00241 void PStream::skipBlanksAndCommentsAndSeparators() 00242 { 00243 int c = get(); 00244 while(c!=EOF) 00245 { 00246 if(c=='#') 00247 skipRestOfLine(); 00248 else if(c!=' ' && c!='\t' && c!='\n' && c!='\r' && c!=';' && c!=',') 00249 break; 00250 c = get(); 00251 } 00252 if(c!=EOF) 00253 putback(c); 00254 } 00255 00256 void PStream::writeAsciiHexNum(unsigned char x) 00257 { 00258 int d = x>>4; 00259 put(d<0x0A ?(d+'0') :(d-0x0A+'A')); 00260 d = x & 0x0F; 00261 put(d<0x0A ?(d+'0') :(d-0x0A+'A')); 00262 } 00263 00264 00265 void PStream::writeAsciiNum(char x) 00266 { 00267 snprintf(tmpbuf, sizeof(tmpbuf), "%d", (int)x); 00268 write(tmpbuf, strlen(tmpbuf)); 00269 } 00270 00271 void PStream::writeAsciiNum(unsigned char x) 00272 { 00273 snprintf(tmpbuf, sizeof(tmpbuf), "%d", (int)x); 00274 write(tmpbuf, strlen(tmpbuf)); 00275 } 00276 00277 void PStream::writeAsciiNum(signed char x) 00278 { 00279 snprintf(tmpbuf, sizeof(tmpbuf), "%d", (int)x); 00280 write(tmpbuf, strlen(tmpbuf)); 00281 } 00282 00283 void PStream::writeAsciiNum(short x) 00284 { 00285 snprintf(tmpbuf, sizeof(tmpbuf), "%hd", x); 00286 write(tmpbuf, strlen(tmpbuf)); 00287 } 00288 00289 void PStream::writeAsciiNum(unsigned short x) 00290 { 00291 snprintf(tmpbuf, sizeof(tmpbuf), "%hu", x); 00292 write(tmpbuf, strlen(tmpbuf)); 00293 } 00294 00295 void PStream::writeAsciiNum(int x) 00296 { 00297 snprintf(tmpbuf, sizeof(tmpbuf), "%d", x); 00298 write(tmpbuf, strlen(tmpbuf)); 00299 } 00300 00301 void PStream::writeAsciiNum(unsigned int x) 00302 { 00303 snprintf(tmpbuf, sizeof(tmpbuf), "%u", x); 00304 write(tmpbuf, strlen(tmpbuf)); 00305 } 00306 00307 void PStream::writeAsciiNum(long x) 00308 { 00309 snprintf(tmpbuf, sizeof(tmpbuf), "%ld", x); 00310 write(tmpbuf, strlen(tmpbuf)); 00311 } 00312 00313 void PStream::writeAsciiNum(unsigned long x) 00314 { 00315 snprintf(tmpbuf, sizeof(tmpbuf), "%lu", x); 00316 write(tmpbuf, strlen(tmpbuf)); 00317 } 00318 00319 void PStream::writeAsciiNum(float x) 00320 { 00321 if(is_missing(x)) 00322 write("nan"); 00323 else 00324 { 00325 snprintf(tmpbuf, sizeof(tmpbuf), "%.8g", x); 00326 write(tmpbuf, strlen(tmpbuf)); 00327 } 00328 } 00329 00330 void PStream::writeAsciiNum(double x) 00331 { 00332 if(is_missing(x)) 00333 write("nan"); 00334 else 00335 { 00336 snprintf(tmpbuf, sizeof(tmpbuf), "%.18g", x); 00337 write(tmpbuf, strlen(tmpbuf)); 00338 } 00339 } 00340 00341 void PStream::readAsciiNum(char &x) 00342 { 00343 long dx; 00344 readAsciiNum(dx); 00345 x = char(dx); 00346 } 00347 00348 void PStream::readAsciiNum(unsigned char &x) 00349 { 00350 long dx; 00351 readAsciiNum(dx); 00352 x = (unsigned char)(dx); 00353 } 00354 00355 void PStream::readAsciiNum(signed char &x) 00356 { 00357 long dx; 00358 readAsciiNum(dx); 00359 x = (signed char)(dx); 00360 } 00361 00362 void PStream::readAsciiNum(short &x) 00363 { 00364 long dx; 00365 readAsciiNum(dx); 00366 x = short(dx); 00367 } 00368 00369 void PStream::readAsciiNum(unsigned short &x) 00370 { 00371 unsigned long dx; 00372 readAsciiNum(dx); 00373 x = (unsigned short)(dx); 00374 } 00375 00376 void PStream::readAsciiNum(int &x) 00377 { 00378 long dx; 00379 readAsciiNum(dx); 00380 x = int(dx); 00381 } 00382 00383 void PStream::readAsciiNum(unsigned int &x) 00384 { 00385 unsigned long dx; 00386 readAsciiNum(dx); 00387 x = (unsigned int)(dx); 00388 } 00389 00390 void PStream::readAsciiNum(long &x) 00391 { 00392 skipBlanks(); 00393 x = 0; 00394 char c = get(); 00395 int pos_or_neg = 1; 00396 if (c == '-') 00397 { 00398 pos_or_neg = -1; 00399 c = get(); 00400 } 00401 else if (c == '+') 00402 c = get(); 00403 00404 while(isdigit(c)) 00405 { 00406 x = x*10 + c-'0'; 00407 c = get(); 00408 } 00409 putback(c); 00410 x *= pos_or_neg; 00411 } 00412 00413 void PStream::readAsciiNum(unsigned long &x) 00414 { 00415 skipBlanks(); 00416 x = 0; 00417 char c = get(); 00418 while(isdigit(c)) 00419 { 00420 x = x*10 + c-'0'; 00421 c = get(); 00422 } 00423 putback(c); 00424 } 00425 00426 void PStream::readAsciiNum(float &x) 00427 { 00428 double dx; 00429 readAsciiNum(dx); 00430 x = float(dx); 00431 } 00432 00433 void PStream::readAsciiNum(double &x) 00434 { 00435 skipBlanks(); 00436 int l=0; 00437 00438 char c = get(); 00439 00440 switch(c) 00441 { 00442 case '?': 00443 x = MISSING_VALUE; 00444 break; 00445 case 'n': 00446 case 'N': 00447 if(get()=='a' && get()=='n') 00448 x = MISSING_VALUE; 00449 else 00450 PLERROR("Bug while reading file and expecting a double"); 00451 break; 00452 case 'i': 00453 case 'I': 00454 if (get()=='n' && get()=='f') 00455 x = 1.0/0.0; 00456 else 00457 PLERROR("Bug while reading file and expecting a double"); 00458 break ; 00459 default: 00460 while(isdigit(c) || c=='-' || c=='+' || c=='.' || c=='e' || c=='E') 00461 { 00462 tmpbuf[l++] = c; 00463 c = get(); 00464 } 00465 tmpbuf[l] = '\0'; 00466 putback(c); 00467 sscanf(tmpbuf,"%lf",&x); 00468 break; 00469 } 00470 } 00471 00472 00473 PStream& PStream::operator=(const PStream& pios) 00474 { 00475 if(this != &pios) 00476 { 00477 pstreambuf = pios.pstreambuf; 00478 inmode = pios.inmode; 00479 outmode = pios.outmode; 00480 implicit_storage = pios.implicit_storage; 00481 compression_mode = pios.compression_mode; 00482 } 00483 return *this; 00484 } 00485 00486 // Implementation of operator>>'s 00487 00488 PStream& PStream::operator>>(char &x) 00489 { 00490 switch(inmode) 00491 { 00492 case raw_binary: 00493 get(x); 00494 break; 00495 case pretty_ascii: 00496 case raw_ascii: 00497 skipBlanks(); 00498 get(x); 00499 break; 00500 case plearn_ascii: 00501 case plearn_binary: 00502 skipBlanksAndCommentsAndSeparators(); 00503 get(x); 00504 if (x == '\'') // ascii case (between single quotes) 00505 { 00506 get(x); 00507 get(); 00508 } 00509 else if (x == 0x01) // plearn_binary case 00510 get(x); 00511 break; 00512 default: 00513 PLERROR("In PStream::operator>> unknown inmode!!!!!!!!!"); 00514 break; 00515 } 00516 return *this; 00517 } 00518 00519 PStream& PStream::operator>>(signed char &x) 00520 { 00521 char c; 00522 operator>>(c); 00523 x = (signed char)c; 00524 return *this; 00525 } 00526 00527 PStream& PStream::operator>>(unsigned char &x) 00528 { 00529 switch(inmode) 00530 { 00531 case raw_binary: 00532 read(reinterpret_cast<char *>(&x), sizeof(unsigned char)); 00533 break; 00534 case raw_ascii: 00535 skipBlanks(); 00536 read(reinterpret_cast<char *>(&x), sizeof(unsigned char)); 00537 break; 00538 case pretty_ascii: 00539 case plearn_ascii: 00540 case plearn_binary: 00541 { 00542 skipBlanksAndCommentsAndSeparators(); 00543 char c = get(); 00544 if (c == '\'') // ascii 00545 { 00546 read(reinterpret_cast<char *>(&x), sizeof(unsigned char)); 00547 get(); 00548 } 00549 else if (c == 0x02) // plearn_binary 00550 read(reinterpret_cast<char *>(&x), sizeof(unsigned char)); 00551 else 00552 x = (unsigned char)c; 00553 break; 00554 } 00555 default: 00556 PLERROR("In PStream::operator>> unknown inmode!!!!!!!!!"); 00557 break; 00558 } 00559 return *this; 00560 } 00561 00562 PStream& PStream::operator>>(char *x) 00563 { 00564 if(!x) 00565 PLERROR("In PStream::operator>>(char*) character array must already be allocated to put the read string in"); 00566 00567 switch(inmode) 00568 { 00569 case PStream::raw_ascii: 00570 case PStream::raw_binary: 00571 case PStream::pretty_ascii: 00572 { 00573 skipBlanksAndComments(); 00574 int c = peek(); 00575 int i=0; // pos within the string 00576 c = get(); 00577 while (c!=EOF && wordseparators.find(c)==string::npos) // as long as we don't meet a wordseparator (or eof)... 00578 { 00579 x[i++] = static_cast<char>(c); 00580 c = get(); 00581 } 00582 x[i++] = 0; 00583 if(!isspace(c)) 00584 putback(c); 00585 } 00586 break; 00587 case PStream::plearn_ascii: 00588 case PStream::plearn_binary: 00589 { 00590 if(!x) 00591 PLERROR("In PStream::operator>>(char*) character array must already be allocated to put the read string in"); 00592 skipBlanksAndComments(); 00593 int c = peek(); 00594 int i=0; // pos within the string 00595 if(c=='"') // it's a quoted string "..." 00596 { 00597 c = get(); // skip the quote 00598 c = get(); // get the next character 00599 while(c!='"' && c!=EOF) 00600 { 00601 if(c=='\\') // escaped character 00602 c = get(); 00603 x[i++]= static_cast<char>(c); 00604 c = get(); 00605 } 00606 if(c==EOF) 00607 PLERROR("In read(istream&, char*) unterminated quoted string"); 00608 if(!isspace(c)) 00609 putback(c); 00610 } 00611 else // it's a single word without quotes 00612 { 00613 c= get(); 00614 while(c != EOF && wordseparators.find(c)==string::npos) // as long as we don't meet a wordseparator (or eof)... 00615 { 00616 x[i++]= static_cast<char>(c); 00617 c= get(); 00618 } 00619 if(!isspace(c)) 00620 putback(c); 00621 } 00622 x[i++] = 0; 00623 } 00624 break; 00625 default: 00626 PLERROR("In PStream::operator>> unknown inmode!!!!!!!!!"); 00627 break; 00628 } 00629 return *this; 00630 } 00631 00632 PStream& PStream::operator>>(string& x) 00633 { 00634 switch(inmode) 00635 { 00636 case PStream::raw_ascii: 00637 case PStream::raw_binary: 00638 case PStream::pretty_ascii: 00639 { 00640 skipBlanksAndComments(); 00641 int c = peek(); 00642 x.clear(); 00643 c = get(); 00644 while (c!=EOF && wordseparators.find(c)==string::npos) // as long as we don't meet a wordseparator (or eof)... 00645 { 00646 x += static_cast<char>(c); 00647 c = get(); 00648 } 00649 if(!isspace(c)) 00650 putback(c); 00651 } 00652 break; 00653 case PStream::plearn_ascii: 00654 case PStream::plearn_binary: 00655 { 00656 skipBlanksAndComments(); 00657 int c = peek(); 00658 if(c=='"') // it's a quoted string "..." 00659 { 00660 x.resize(0); 00661 c = get(); // skip the quote 00662 c = get(); // get the next character 00663 while(c!='"' && c!=EOF) 00664 { 00665 if(c=='\\') // escaped character 00666 c = get(); 00667 x+= static_cast<char>(c); 00668 c = get(); 00669 } 00670 if(c==EOF) 00671 PLERROR("In read(istream&, string&) unterminated quoted string"); 00672 if(!isspace(get())) // skip following blank if any 00673 putback(c); 00674 } 00675 else // it's a single word without quotes 00676 { 00677 x.resize(0); 00678 c= get(); 00679 while(c != EOF && wordseparators.find(c)==string::npos) // as long as we don't meet a wordseparator (or eof)... 00680 { 00681 x+= static_cast<char>(c); 00682 c= get(); 00683 } 00684 if(!isspace(c)) 00685 putback(c); 00686 } 00687 } 00688 break; 00689 default: 00690 PLERROR("In PStream::operator>> unknown inmode!!!!!!!!!"); 00691 break; 00692 } 00693 return *this; 00694 } 00695 00696 PStream& PStream::operator>>(int &x) 00697 { 00698 switch(inmode) 00699 { 00700 case raw_ascii: 00701 case pretty_ascii: 00702 skipBlanks(); 00703 readAsciiNum(x); 00704 break; 00705 case raw_binary: 00706 read(reinterpret_cast<char *>(&x), sizeof(int)); 00707 break; 00708 case plearn_ascii: 00709 case plearn_binary: 00710 { 00711 skipBlanksAndCommentsAndSeparators(); 00712 int c = get(); 00713 if(c==0x07 || c==0x08) // plearn_binary 00714 { 00715 read(reinterpret_cast<char*>(&x),sizeof(int)); 00716 if( (c==0x07 && byte_order()==BIG_ENDIAN_ORDER) 00717 || (c==0x08 && byte_order()==LITTLE_ENDIAN_ORDER) ) 00718 endianswap(&x); 00719 } 00720 else // plearn_ascii 00721 { 00722 putback(c); 00723 readAsciiNum(x); 00724 } 00725 break; 00726 } 00727 default: 00728 PLERROR("In PStream::operator>> unknown inmode!!!!!!!!!"); 00729 break; 00730 } 00731 return *this; 00732 } 00733 00734 PStream& PStream::operator>>(unsigned int &x) 00735 { 00736 switch(inmode) 00737 { 00738 case raw_ascii: 00739 case pretty_ascii: 00740 skipBlanks(); 00741 readAsciiNum(x); 00742 break; 00743 case raw_binary: 00744 read(reinterpret_cast<char *>(&x), sizeof(unsigned int)); 00745 break; 00746 case plearn_ascii: 00747 case plearn_binary: 00748 { 00749 skipBlanksAndCommentsAndSeparators(); 00750 int c = get(); 00751 if(c==0x0B || c==0x0C) // plearn_binary 00752 { 00753 read(reinterpret_cast<char*>(&x),sizeof(unsigned int)); 00754 if( (c==0x0B && byte_order()==BIG_ENDIAN_ORDER) 00755 || (c==0x0C && byte_order()==LITTLE_ENDIAN_ORDER) ) 00756 endianswap(&x); 00757 } 00758 else // plearn_ascii 00759 { 00760 putback(c); 00761 readAsciiNum(x); 00762 } 00763 break; 00764 } 00765 default: 00766 PLERROR("In PStream::operator>> unknown inmode!!!!!!!!!"); 00767 break; 00768 } 00769 return *this; 00770 } 00771 00772 PStream& PStream::operator>>(long &x) 00773 { 00774 switch(inmode) 00775 { 00776 case raw_ascii: 00777 case pretty_ascii: 00778 skipBlanks(); 00779 readAsciiNum(x); 00780 break; 00781 case raw_binary: 00782 read(reinterpret_cast<char *>(&x), sizeof(long)); 00783 break; 00784 case plearn_ascii: 00785 case plearn_binary: 00786 { 00787 skipBlanksAndCommentsAndSeparators(); 00788 int c = get(); 00789 if(c==0x07 || c==0x08) // plearn_binary 00790 { 00791 read(reinterpret_cast<char*>(&x),sizeof(long)); 00792 if( (c==0x07 && byte_order()==BIG_ENDIAN_ORDER) 00793 || (c==0x08 && byte_order()==LITTLE_ENDIAN_ORDER) ) 00794 endianswap(&x); 00795 } 00796 else // plearn_ascii 00797 { 00798 putback(c); 00799 readAsciiNum(x); 00800 } 00801 break; 00802 } 00803 default: 00804 PLERROR("In PStream::operator>> unknown inmode!!!!!!!!!"); 00805 break; 00806 } 00807 return *this; 00808 } 00809 00810 PStream& PStream::operator>>(unsigned long &x) 00811 { 00812 switch(inmode) 00813 { 00814 case raw_ascii: 00815 case pretty_ascii: 00816 skipBlanks(); 00817 readAsciiNum(x); 00818 break; 00819 case raw_binary: 00820 read(reinterpret_cast<char *>(&x), sizeof(unsigned long)); 00821 break; 00822 case plearn_ascii: 00823 case plearn_binary: 00824 { 00825 skipBlanksAndCommentsAndSeparators(); 00826 int c = get(); 00827 if(c==0x0B || c==0x0C) // plearn_binary 00828 { 00829 read(reinterpret_cast<char*>(&x),sizeof(unsigned long)); 00830 if( (c==0x0B && byte_order()==BIG_ENDIAN_ORDER) 00831 || (c==0x0C && byte_order()==LITTLE_ENDIAN_ORDER) ) 00832 endianswap(&x); 00833 } 00834 else // plearn_ascii 00835 { 00836 putback(c); 00837 readAsciiNum(x); 00838 } 00839 break; 00840 } 00841 default: 00842 PLERROR("In PStream::operator>> unknown inmode!!!!!!!!!"); 00843 break; 00844 } 00845 return *this; 00846 } 00847 00848 PStream& PStream::operator>>(short &x) 00849 { 00850 switch(inmode) 00851 { 00852 case raw_ascii: 00853 case pretty_ascii: 00854 skipBlanks(); 00855 readAsciiNum(x); 00856 break; 00857 case raw_binary: 00858 read(reinterpret_cast<char *>(&x), sizeof(short)); 00859 break; 00860 case plearn_ascii: 00861 case plearn_binary: 00862 { 00863 skipBlanksAndCommentsAndSeparators(); 00864 int c = get(); 00865 if(c==0x03 || c==0x04) // plearn_binary 00866 { 00867 read(reinterpret_cast<char*>(&x),sizeof(short)); 00868 if( (c==0x03 && byte_order()==BIG_ENDIAN_ORDER) 00869 || (c==0x04 && byte_order()==LITTLE_ENDIAN_ORDER) ) 00870 endianswap(&x); 00871 } 00872 else // plearn_ascii 00873 { 00874 putback(c); 00875 readAsciiNum(x); 00876 } 00877 break; 00878 } 00879 default: 00880 PLERROR("In PStream::operator>> unknown inmode!!!!!!!!!"); 00881 break; 00882 } 00883 return *this; 00884 } 00885 00886 PStream& PStream::operator>>(unsigned short &x) 00887 { 00888 switch(inmode) 00889 { 00890 case raw_ascii: 00891 case pretty_ascii: 00892 skipBlanks(); 00893 readAsciiNum(x); 00894 break; 00895 case raw_binary: 00896 read(reinterpret_cast<char *>(&x), sizeof(unsigned short)); 00897 break; 00898 case plearn_ascii: 00899 case plearn_binary: 00900 { 00901 skipBlanksAndCommentsAndSeparators(); 00902 int c = get(); 00903 if(c==0x05 || c==0x06) // plearn_binary 00904 { 00905 read(reinterpret_cast<char*>(&x),sizeof(unsigned short)); 00906 if( (c==0x05 && byte_order()==BIG_ENDIAN_ORDER) 00907 || (c==0x06 && byte_order()==LITTLE_ENDIAN_ORDER) ) 00908 endianswap(&x); 00909 } 00910 else // plearn_ascii 00911 { 00912 putback(c); 00913 readAsciiNum(x); 00914 } 00915 break; 00916 } 00917 default: 00918 PLERROR("In PStream::operator>> unknown inmode!!!!!!!!!"); 00919 break; 00920 } 00921 return *this; 00922 } 00923 00924 PStream& PStream::operator>>(bool &x) 00925 { 00926 char c; 00927 switch(inmode) 00928 { 00929 case raw_ascii: 00930 case pretty_ascii: 00931 case raw_binary: 00932 case plearn_ascii: 00933 case plearn_binary: 00934 skipBlanksAndCommentsAndSeparators(); 00935 c = get(); 00936 if(c==0x12) // plearn_binary 00937 c=get(); 00938 00939 if(c=='1') 00940 x = true; 00941 else if(c=='0') 00942 x = false; 00943 else 00944 PLERROR("In PStream::operator>>(bool &x) wrong format for bool, must be character 0 or 1"); 00945 break; 00946 00947 default: 00948 PLERROR("In PStream::operator>> unknown inmode!!!!!!!!!"); 00949 break; 00950 } 00951 return *this; 00952 } 00953 00954 PStream& PStream::operator>>(float &x) 00955 { 00956 switch(inmode) 00957 { 00958 case raw_ascii: 00959 case pretty_ascii: 00960 skipBlanks(); 00961 readAsciiNum(x); 00962 break; 00963 case raw_binary: 00964 read(reinterpret_cast<char *>(&x), sizeof(float)); 00965 break; 00966 case plearn_ascii: 00967 case plearn_binary: 00968 { 00969 skipBlanksAndCommentsAndSeparators(); 00970 int c = get(); 00971 if(c==0x0E || c==0x0F) // plearn_binary 00972 { 00973 read(reinterpret_cast<char*>(&x),sizeof(float)); 00974 if( (c==0x0E && byte_order()==BIG_ENDIAN_ORDER) 00975 || (c==0x0F && byte_order()==LITTLE_ENDIAN_ORDER) ) 00976 endianswap(&x); 00977 } 00978 else // plearn_ascii 00979 { 00980 putback(c); 00981 readAsciiNum(x); 00982 } 00983 break; 00984 } 00985 default: 00986 PLERROR("In PStream::operator>> unknown inmode!!!!!!!!!"); 00987 break; 00988 } 00989 return *this; 00990 } 00991 00992 PStream& PStream::operator>>(double &x) 00993 { 00994 switch(inmode) 00995 { 00996 case raw_ascii: 00997 case pretty_ascii: 00998 skipBlanks(); 00999 readAsciiNum(x); 01000 break; 01001 case raw_binary: 01002 read(reinterpret_cast<char *>(&x), sizeof(double)); 01003 break; 01004 case plearn_ascii: 01005 case plearn_binary: 01006 { 01007 skipBlanksAndCommentsAndSeparators(); 01008 int c = get(); 01009 if(c==0x10 || c==0x11) // plearn_binary 01010 { 01011 read(reinterpret_cast<char*>(&x),sizeof(double)); 01012 if( (c==0x10 && byte_order()==BIG_ENDIAN_ORDER) 01013 || (c==0x11 && byte_order()==LITTLE_ENDIAN_ORDER) ) 01014 endianswap(&x); 01015 } 01016 else // ascii 01017 { 01018 putback(c); 01019 readAsciiNum(x); 01020 } 01021 break; 01022 } 01023 default: 01024 PLERROR("In PStream::operator>> unknown inmode!!!!!!!!!"); 01025 break; 01026 } 01027 return *this; 01028 } 01029 01030 01031 // Implementation of operator<<'s 01032 01033 PStream& PStream::operator<<(char x) 01034 { 01035 switch(outmode) 01036 { 01037 case raw_ascii: 01038 case raw_binary: 01039 case pretty_ascii: 01040 put(x); 01041 break; 01042 case plearn_ascii: 01043 put('\''); 01044 put(x); 01045 put('\''); 01046 put(' '); 01047 break; 01048 case plearn_binary: 01049 put((char)0x01); 01050 put(x); 01051 break; 01052 default: 01053 PLERROR("In PStream::operator<< unknown outmode!!!!!!!!!"); 01054 break; 01055 } 01056 return *this; 01057 } 01058 01059 PStream& PStream::operator<<(signed char x) 01060 { 01061 operator<<(char(x)); 01062 return *this; 01063 } 01064 01065 PStream& PStream::operator<<(unsigned char x) 01066 { 01067 switch(outmode) 01068 { 01069 case raw_ascii: 01070 put(x); 01071 put(' '); 01072 break; 01073 case raw_binary: 01074 put(x); 01075 break; 01076 case pretty_ascii: 01077 case plearn_ascii: 01078 put('\''); 01079 put(x); 01080 put('\''); 01081 put(' '); 01082 break; 01083 case plearn_binary: 01084 put((char)0x02); 01085 put(x); 01086 break; 01087 default: 01088 PLERROR("In PStream::operator<< unknown outmode!!!!!!!!!"); 01089 break; 01090 } 01091 return *this; 01092 } 01093 01094 PStream& PStream::operator<<(const char *x) 01095 { 01096 int l = (int)strlen(x); 01097 switch(outmode) 01098 { 01099 case PStream::raw_ascii: 01100 case PStream::pretty_ascii: 01101 case PStream::raw_binary: 01102 write(x); 01103 break; 01104 01105 case PStream::plearn_ascii: 01106 case PStream::plearn_binary: 01107 { 01108 put('"'); 01109 for(int i=0; i<l; i++) 01110 { 01111 char c = x[i]; 01112 if(c=='"' || c=='\\') // escape quote and backslash 01113 put('\\'); 01114 put(c); 01115 } 01116 put('"'); 01117 put(' '); 01118 } 01119 break; 01120 01121 default: 01122 PLERROR("In PStream::operator<< unknown outmode!!!!!!!!!"); 01123 break; 01124 } 01125 return *this; 01126 } 01127 01128 PStream& PStream::operator<<(const string &x) 01129 { 01130 const char* array = x.c_str(); 01131 operator<<(array); 01132 return *this; 01133 } 01134 01135 PStream& PStream::operator<<(int x) 01136 { 01137 switch(outmode) 01138 { 01139 case raw_binary: 01140 write(reinterpret_cast<char *>(&x), sizeof(int)); 01141 break; 01142 case raw_ascii: 01143 case plearn_ascii: 01144 case pretty_ascii: 01145 writeAsciiNum(x); 01146 put(' '); 01147 break; 01148 case plearn_binary: 01149 #ifdef BIGENDIAN 01150 put((char)0x08); 01151 #else 01152 put((char)0x07); 01153 #endif 01154 write((char*)&x,sizeof(int)); 01155 break; 01156 default: 01157 PLERROR("In PStream::operator<< unknown outmode!!!!!!!!!"); 01158 break; 01159 } 01160 return *this; 01161 } 01162 01163 PStream& PStream::operator<<(unsigned int x) 01164 { 01165 switch(outmode) 01166 { 01167 case raw_binary: 01168 write(reinterpret_cast<char *>(&x), sizeof(unsigned int)); 01169 break; 01170 case raw_ascii: 01171 case plearn_ascii: 01172 case pretty_ascii: 01173 writeAsciiNum(x); 01174 put(' '); 01175 break; 01176 case plearn_binary: 01177 #ifdef BIGENDIAN 01178 put((char)0x0C); 01179 #else 01180 put((char)0x0B); 01181 #endif 01182 write((char*)&x,sizeof(unsigned int)); 01183 break; 01184 default: 01185 PLERROR("In PStream::operator<< unknown outmode!!!!!!!!!"); 01186 break; 01187 } 01188 return *this; 01189 } 01190 01191 PStream& PStream::operator<<(long x) 01192 { 01193 switch(outmode) 01194 { 01195 case raw_binary: 01196 write(reinterpret_cast<char *>(&x), sizeof(long)); 01197 break; 01198 case raw_ascii: 01199 case plearn_ascii: 01200 case pretty_ascii: 01201 writeAsciiNum(x); 01202 put(' '); 01203 break; 01204 case plearn_binary: 01205 #ifdef BIGENDIAN 01206 put((char)0x08); 01207 #else 01208 put((char)0x07); 01209 #endif 01210 write((char*)&x,sizeof(long)); 01211 break; 01212 default: 01213 PLERROR("In PStream::operator<< unknown outmode!!!!!!!!!"); 01214 break; 01215 } 01216 return *this; 01217 } 01218 01219 PStream& PStream::operator<<(unsigned long x) 01220 { 01221 switch(outmode) 01222 { 01223 case raw_binary: 01224 write(reinterpret_cast<char *>(&x), sizeof(unsigned long)); 01225 break; 01226 case raw_ascii: 01227 case plearn_ascii: 01228 case pretty_ascii: 01229 writeAsciiNum(x); 01230 put(' '); 01231 break; 01232 case plearn_binary: 01233 #ifdef BIGENDIAN 01234 put((char)0x0C); 01235 #else 01236 put((char)0x0B); 01237 #endif 01238 write((char*)&x,sizeof(unsigned long)); 01239 break; 01240 default: 01241 PLERROR("In PStream::operator<< unknown outmode!!!!!!!!!"); 01242 break; 01243 } 01244 return *this; 01245 } 01246 01247 PStream& PStream::operator<<(short x) 01248 { 01249 switch(outmode) 01250 { 01251 case raw_binary: 01252 write(reinterpret_cast<char *>(&x), sizeof(short)); 01253 break; 01254 case raw_ascii: 01255 case plearn_ascii: 01256 case pretty_ascii: 01257 writeAsciiNum(x); 01258 put(' '); 01259 break; 01260 case plearn_binary: 01261 #ifdef BIGENDIAN 01262 put((char)0x04); 01263 #else 01264 put((char)0x03); 01265 #endif 01266 write((char*)&x,sizeof(short)); 01267 break; 01268 default: 01269 PLERROR("In PStream::operator<< unknown outmode!!!!!!!!!"); 01270 break; 01271 } 01272 return *this; 01273 } 01274 01275 PStream& PStream::operator<<(unsigned short x) 01276 { 01277 switch(outmode) 01278 { 01279 case raw_binary: 01280 write(reinterpret_cast<char *>(&x), sizeof(unsigned short)); 01281 break; 01282 case raw_ascii: 01283 case plearn_ascii: 01284 case pretty_ascii: 01285 writeAsciiNum(x); 01286 put(' '); 01287 break; 01288 case plearn_binary: 01289 #ifdef BIGENDIAN 01290 put((char)0x06); 01291 #else 01292 put((char)0x05); 01293 #endif 01294 write((char*)&x,sizeof(unsigned short)); 01295 break; 01296 default: 01297 PLERROR("In PStream::operator<< unknown outmode!!!!!!!!!"); 01298 break; 01299 } 01300 return *this; 01301 } 01302 01303 PStream& PStream::operator<<(float x) 01304 { 01305 switch(outmode) 01306 { 01307 case raw_binary: 01308 write(reinterpret_cast<char *>(&x), sizeof(float)); 01309 break; 01310 case raw_ascii: 01311 case plearn_ascii: 01312 case pretty_ascii: 01313 writeAsciiNum(x); 01314 put(' '); 01315 break; 01316 case plearn_binary: 01317 #ifdef BIGENDIAN 01318 put((char)0x0F); 01319 #else 01320 put((char)0x0E); 01321 #endif 01322 write((char*)&x,sizeof(float)); 01323 break; 01324 default: 01325 PLERROR("In PStream::operator<< unknown outmode!!!!!!!!!"); 01326 break; 01327 } 01328 return *this; 01329 } 01330 01331 PStream& PStream::operator<<(double x) 01332 { 01333 switch(outmode) 01334 { 01335 case raw_binary: 01336 write(reinterpret_cast<char *>(&x), sizeof(double)); 01337 break; 01338 case raw_ascii: 01339 case plearn_ascii: 01340 case pretty_ascii: 01341 writeAsciiNum(x); 01342 put(' '); 01343 break; 01344 case plearn_binary: 01345 #ifdef BIGENDIAN 01346 put((char)0x11); 01347 #else 01348 put((char)0x10); 01349 #endif 01350 write((char*)&x,sizeof(double)); 01351 break; 01352 default: 01353 PLERROR("In PStream::operator<< unknown outmode!!!!!!!!!"); 01354 break; 01355 } 01356 return *this; 01357 } 01358 01359 01360 void binread_(PStream& in, bool* x, 01361 unsigned int n, unsigned char typecode) 01362 { 01363 if(typecode!=TypeTraits<bool>::little_endian_typecode()) 01364 PLERROR("In binread_ incompatible typecode"); 01365 01366 while(n--) 01367 { 01368 int c = in.get(); 01369 if(c=='0') 01370 *x = false; 01371 else if(c=='1') 01372 *x = true; 01373 else 01374 PLERROR("In binread_(PStream& in, bool* x, unsigned int n, unsigned char typecode): " 01375 "read invalid value for a boolean: should be '1' or '0', not %c", c); 01376 ++x; 01377 } 01378 } 01379 01380 #define IMPLEMENT_TYPICAL_BASETYPE_BINREAD_(BASETYPE) \ 01381 void binread_(PStream& in, BASETYPE* x, \ 01382 unsigned int n, unsigned char typecode) \ 01383 { \ 01384 if(typecode==TypeTraits<BASETYPE>::little_endian_typecode()) \ 01385 { \ 01386 in.read((char*)x, n*sizeof(BASETYPE)); \ 01387 if(byte_order()==BIG_ENDIAN_ORDER) \ 01388 endianswap(x,n); \ 01389 } \ 01390 else if(typecode==TypeTraits<BASETYPE>::big_endian_typecode()) \ 01391 { \ 01392 in.read((char*)x, n*sizeof(BASETYPE)); \ 01393 if(byte_order()==LITTLE_ENDIAN_ORDER) \ 01394 endianswap(x,n); \ 01395 } \ 01396 else \ 01397 PLERROR("In binread_ incompatible typecode"); \ 01398 } 01399 01400 01401 // IMPLEMENT_TYPICAL_BASETYPE_BINREAD_(char); 01402 IMPLEMENT_TYPICAL_BASETYPE_BINREAD_(short) 01403 IMPLEMENT_TYPICAL_BASETYPE_BINREAD_(unsigned short) 01404 IMPLEMENT_TYPICAL_BASETYPE_BINREAD_(int) 01405 IMPLEMENT_TYPICAL_BASETYPE_BINREAD_(unsigned int) 01406 IMPLEMENT_TYPICAL_BASETYPE_BINREAD_(long) 01407 IMPLEMENT_TYPICAL_BASETYPE_BINREAD_(unsigned long) 01408 01410 01411 void binread_(PStream& in, double* x, unsigned int n, unsigned char typecode) 01412 { 01413 if(typecode==TypeTraits<double>::little_endian_typecode()) 01414 { 01415 in.read((char*)x, n*sizeof(double)); 01416 #ifdef BIGENDIAN 01417 endianswap(x,n); 01418 #endif 01419 } 01420 else if(typecode==TypeTraits<double>::big_endian_typecode()) 01421 { 01422 in.read((char*)x, n*sizeof(double)); 01423 #ifdef LITTLEENDIAN 01424 endianswap(x,n); 01425 #endif 01426 } 01427 else if(typecode==TypeTraits<float>::little_endian_typecode()) 01428 { 01429 float val; 01430 while(n--) 01431 { 01432 in.read((char*)&val, sizeof(float)); 01433 #ifdef BIGENDIAN 01434 endianswap(&val); 01435 #endif 01436 *x++ = double(val); 01437 } 01438 } 01439 else if(typecode==TypeTraits<float>::big_endian_typecode()) 01440 { 01441 float val; 01442 while(n--) 01443 { 01444 in.read((char*)&val, sizeof(float)); 01445 #ifdef LITTLEENDIAN 01446 endianswap(&val); 01447 #endif 01448 *x++ = double(val); 01449 } 01450 } 01451 else 01452 PLERROR("In binread_ incompatible typecode"); 01453 } 01454 01455 01456 01457 void binread_(PStream& in, float* x, unsigned int n, unsigned char typecode) 01458 { 01459 if(typecode==TypeTraits<float>::little_endian_typecode()) 01460 { 01461 in.read((char*)x, n*sizeof(float)); 01462 #ifdef BIGENDIAN 01463 endianswap(x,n); 01464 #endif 01465 } 01466 else if(typecode==TypeTraits<float>::big_endian_typecode()) 01467 { 01468 in.read((char*)x, n*sizeof(float)); 01469 #ifdef LITTLEENDIAN 01470 endianswap(x,n); 01471 #endif 01472 } 01473 else if(typecode==TypeTraits<double>::little_endian_typecode()) 01474 { 01475 double val; 01476 while(n--) 01477 { 01478 in.read((char*)&val, sizeof(double)); 01479 #ifdef BIGENDIAN 01480 endianswap(&val); 01481 #endif 01482 *x++ = float(val); 01483 } 01484 } 01485 else if(typecode==TypeTraits<double>::big_endian_typecode()) 01486 { 01487 double val; 01488 while(n--) 01489 { 01490 in.read((char*)&val, sizeof(double)); 01491 #ifdef LITTLEENDIAN 01492 endianswap(&val); 01493 #endif 01494 *x++ = float(val); 01495 } 01496 } 01497 else 01498 PLERROR("In binread_ incompatible typecode"); 01499 } 01500 01501 } //end of namespace PLearn 01502

Generated on Tue Aug 17 16:03:17 2004 for PLearn by doxygen 1.3.7