00001 // --8<--8<--8<--8<-- 00002 // 00003 // Copyright (C) 2006 Smithsonian Astrophysical Observatory 00004 // 00005 // This file is part of suplibxx 00006 // 00007 // suplibxx is free software; you can redistribute it and/or 00008 // modify it under the terms of the GNU General Public License 00009 // as published by the Free Software Foundation; either version 2 00010 // of the License, or (at your option) any later version. 00011 // 00012 // suplibxx is distributed in the hope that it will be useful, 00013 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 // GNU General Public License for more details. 00016 // 00017 // You should have received a copy of the GNU General Public License 00018 // along with this program; if not, write to the 00019 // Free Software Foundation, Inc. 00020 // 51 Franklin Street, Fifth Floor 00021 // Boston, MA 02110-1301, USA 00022 // 00023 // -->8-->8-->8-->8-- 00024 00025 #ifdef sgi 00026 #include <ctype.h> 00027 #else 00028 #include <cctype> 00029 #endif 00030 #include <fstream> 00031 #include <iostream> 00032 #include <string> 00033 using namespace std; 00034 00035 #include "io.h" 00036 using namespace suplib; 00037 00038 #define WS " \t\n\r" 00039 00060 istream& suplib::getrecord( 00061 istream& is, 00062 string& str, 00063 int opt, 00064 char delim, 00065 char continuation 00066 ) { 00067 00068 str.erase( ); 00069 00070 // split appart logical and physical reads here. in the latter 00071 // case, can optimize a bit by reading directly into target string 00072 00073 if ( opt & suplib::READ_LOGICAL ) { 00074 00075 string tmp; 00076 00077 // are we there yet? 00078 bool done = false; 00079 00080 while ( !done && getline( is, tmp, delim ) ) { 00081 00082 // find last continuation char 00083 size_t last = tmp.find_last_of( continuation ); 00084 00085 // find last non whitespace char 00086 size_t eows = tmp.find_last_not_of( WS ); 00087 00088 // if there is nothing but whitespace after continuation... a 00089 // logical line, and lo, a continuation character. what shall 00090 // we do? 00091 if ( eows == last ) { 00092 00093 // well, if this CLEAN thing is requested, 00094 // remove any whitespace after the continuation character 00095 // and insert the delimiter, since it's been scrubbed 00096 // by getline() 00097 00098 if ( opt & suplib::CLEAN ) 00099 { 00100 tmp.erase( last + 1 ); 00101 tmp += delim; 00102 } 00103 00104 // this really isn't raw, as we don't know if we 00105 // ran out of characters or if the delimiter was 00106 // removed by getline. add the delimiter just to 00107 // make things peachy. 00108 else if (opt & suplib::RAW ) 00109 tmp += delim; 00110 00111 // normally, we just zap the continuation character and all 00112 // trailing white space 00113 else 00114 tmp.erase( last ); 00115 00116 } 00117 00118 // ok, it's not a continuation character, just worry about 00119 // cleaning out the end of the line. note that we 00120 // bail here, as we've hit the end of the record. 00121 else { 00122 00123 // zap end of line (no white space) 00124 if ( opt & suplib::STRIP ) 00125 tmp.erase( eows + 1 ); 00126 00127 // same bogus argument as before 00128 else if (opt & suplib::RAW ) 00129 tmp += delim; 00130 00131 // by default, just keep everything but the delimiter, 00132 // already removed by getline() 00133 00134 // we're done here, break out of the getline() loop 00135 done = true; 00136 } 00137 00138 // save the current line 00139 str.append( tmp ); 00140 } 00141 00142 } 00143 00144 00145 // read physical line 00146 else if ( getline( is, str, delim ) ) { 00147 00148 // strip trailing white space 00149 if ( opt & suplib::STRIP ) 00150 { 00151 size_t eows = str.find_last_not_of( WS ); 00152 str.erase( eows + 1 ); 00153 } 00154 00155 // same silliness as above 00156 else if ( opt & suplib::RAW ) 00157 str += delim; 00158 } 00159 00160 00161 return is; 00162 }