suplibxx  1.3.13
getrecord.cc
1 // --8<--8<--8<--8<--
2 //
3 // Copyright (C) 2006 Smithsonian Astrophysical Observatory
4 //
5 // This file is part of suplibxx
6 //
7 // suplibxx is free software; you can redistribute it and/or
8 // modify it under the terms of the GNU General Public License
9 // as published by the Free Software Foundation; either version 2
10 // of the License, or (at your option) any later version.
11 //
12 // suplibxx is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 // GNU General Public License for more details.
16 //
17 // You should have received a copy of the GNU General Public License
18 // along with this program; if not, write to the
19 // Free Software Foundation, Inc.
20 // 51 Franklin Street, Fifth Floor
21 // Boston, MA 02110-1301, USA
22 //
23 // -->8-->8-->8-->8--
24 
25 #include <iostream>
26 #include <string>
27 
28 #include "io.h"
29 using namespace suplib;
30 
31 #define WS " \t\n\r"
32 
53 std::istream& suplib::getrecord(
54  std::istream& is,
55  std::string& str,
56  int opt,
57  char delim,
58  char continuation
59  ) {
60 
61  str.erase( );
62 
63  // split appart logical and physical reads here. in the latter
64  // case, can optimize a bit by reading directly into target string
65 
66  if ( opt & suplib::READ_LOGICAL ) {
67 
68  std::string tmp;
69 
70  // are we there yet?
71  bool done = false;
72 
73  while ( !done && getline( is, tmp, delim ) ) {
74 
75  // find last continuation char
76  size_t last = tmp.find_last_of( continuation );
77 
78  // find last non whitespace char
79  size_t eows = tmp.find_last_not_of( WS );
80 
81  // if there is nothing but whitespace after continuation... a
82  // logical line, and lo, a continuation character. what shall
83  // we do?
84  if ( eows == last ) {
85 
86  // well, if this CLEAN thing is requested,
87  // remove any whitespace after the continuation character
88  // and insert the delimiter, since it's been scrubbed
89  // by getline()
90 
91  if ( opt & suplib::CLEAN )
92  {
93  tmp.erase( last + 1 );
94  tmp += delim;
95  }
96 
97  // this really isn't raw, as we don't know if we
98  // ran out of characters or if the delimiter was
99  // removed by getline. add the delimiter just to
100  // make things peachy.
101  else if (opt & suplib::RAW )
102  tmp += delim;
103 
104  // normally, we just zap the continuation character and all
105  // trailing white space
106  else
107  tmp.erase( last );
108 
109  }
110 
111  // ok, it's not a continuation character, just worry about
112  // cleaning out the end of the line. note that we
113  // bail here, as we've hit the end of the record.
114  else {
115 
116  // zap end of line (no white space)
117  if ( opt & suplib::STRIP )
118  tmp.erase( eows + 1 );
119 
120  // same bogus argument as before
121  else if (opt & suplib::RAW )
122  tmp += delim;
123 
124  // by default, just keep everything but the delimiter,
125  // already removed by getline()
126 
127  // we're done here, break out of the getline() loop
128  done = true;
129  }
130 
131  // save the current line
132  str.append( tmp );
133  }
134 
135  }
136 
137 
138  // read physical line
139  else if ( getline( is, str, delim ) ) {
140 
141  // strip trailing white space
142  if ( opt & suplib::STRIP )
143  {
144  size_t eows = str.find_last_not_of( WS );
145  str.erase( eows + 1 );
146  }
147 
148  // same silliness as above
149  else if ( opt & suplib::RAW )
150  str += delim;
151  }
152 
153 
154  return is;
155 }
The suplib namespace encompasses all of the functions in the suplib++ library.
std::istream & getrecord(std::istream &is, std::string &str, int opt=READ_PHYS, char delim='\n', char continuation='\\')
Reads physical and logical lines.
Definition: getrecord.cc:53
Definition: io.h:90