GNU Octave  9.1.0
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
ls-ascii-helper.cc
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////
2 //
3 // Copyright (C) 2009-2024 The Octave Project Developers
4 //
5 // See the file COPYRIGHT.md in the top-level directory of this
6 // distribution or <https://octave.org/copyright/>.
7 //
8 // This file is part of Octave.
9 //
10 // Octave is free software: you can redistribute it and/or modify it
11 // under the terms of the GNU General Public License as published by
12 // the Free Software Foundation, either version 3 of the License, or
13 // (at your option) any later version.
14 //
15 // Octave is distributed in the hope that it will be useful, but
16 // WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 // GNU General Public License for more details.
19 //
20 // You should have received a copy of the GNU General Public License
21 // along with Octave; see the file COPYING. If not, see
22 // <https://www.gnu.org/licenses/>.
23 //
24 ////////////////////////////////////////////////////////////////////////
25 
26 #if defined (HAVE_CONFIG_H)
27 # include "config.h"
28 #endif
29 
30 #include "ls-ascii-helper.h"
31 
32 #include <istream>
33 #include <sstream>
34 
36 
37 // Helper functions when reading from ascii files.
38 
39 // These functions take care of different line endings (LF, CR, CRLF)
40 // when files were opened in text mode for writing and are now opened in
41 // binary mode for reading.
42 // Even though we no longer store files in text mode, keep this logic
43 // to allow loading older files that might have CRLF or CR line endings.
44 
45 // Skip characters from stream IS until a newline is reached.
46 // Depending on KEEP_NEWLINE, either eat newline from stream or
47 // keep it unread.
48 
49 void
50 skip_until_newline (std::istream& is, bool keep_newline)
51 {
52  if (! is)
53  return;
54 
55  while (is)
56  {
57  char c = is.peek ();
58 
59  if (c == '\n' || c == '\r')
60  {
61  // Reached newline.
62  if (! keep_newline)
63  {
64  // Eat the CR or LF character.
65  char d;
66  is.get (d);
67 
68  // Make sure that for binary-mode opened ascii files
69  // containing CRLF line endings we skip the LF after CR.
70  if (c == '\r' && is.peek () == '\n')
71  {
72  // Yes, LF following CR, eat it.
73  is.get (d);
74  }
75  }
76 
77  // Newline was found, and read from stream if
78  // keep_newline == true, so exit loop.
79  break;
80  }
81  else
82  {
83  // No newline character peeked, so read it and proceed to next
84  // character.
85  char d;
86  is.get (d);
87  }
88  }
89 }
90 
91 // If stream IS currently points to a newline (a leftover from a previous read)
92 // then eat newline(s) until a non-newline character is found.
93 
94 void
95 skip_preceeding_newline (std::istream& is)
96 {
97  if (! is)
98  return;
99 
100  // Check whether IS currently points to newline character.
101  char c = is.peek ();
102 
103  if (c == '\n' || c == '\r')
104  {
105  // Yes, at newline.
106  do
107  {
108  // Eat the CR or LF character.
109  char d;
110  is.get (d);
111 
112  // Make sure that for binary-mode opened ascii files
113  // containing CRLF line endings we skip the LF after CR.
114  if (c == '\r' && is.peek () == '\n')
115  {
116  // Yes, LF following CR, eat it.
117  is.get (d);
118  }
119 
120  // Peek into next character.
121  c = is.peek ();
122 
123  // Loop while still a newline ahead.
124  }
125  while (c == '\n' || c == '\r');
126  }
127 }
128 
129 // Read characters from stream IS until a newline is reached.
130 // Depending on KEEP_NEWLINE, either eat newline from stream or keep
131 // it unread. Characters read are stored and returned as
132 // std::string.
133 
134 std::string
135 read_until_newline (std::istream& is, bool keep_newline)
136 {
137  if (! is)
138  return "";
139 
140  std::ostringstream buf;
141 
142  while (is)
143  {
144  char c = is.peek ();
145 
146  if (c == '\n' || c == '\r')
147  {
148  // Reached newline.
149  if (! keep_newline)
150  {
151  // Eat the CR or LF character.
152  char d;
153  is.get (d);
154 
155  // Make sure that for binary-mode opened ascii files
156  // containing CRLF line endings we skip the LF after
157  // CR.
158 
159  if (c == '\r' && is.peek () == '\n')
160  {
161  // Yes, LF following CR, eat it.
162  is.get (d);
163  }
164  }
165 
166  // Newline was found, and read from stream if
167  // keep_newline == true, so exit loop.
168  break;
169  }
170  else
171  {
172  // No newline character peeked, so read it, store it, and
173  // proceed to next.
174  char d;
175  is.get (d);
176  buf << d;
177  }
178  }
179 
180  return buf.str ();
181 }
182 
183 OCTAVE_END_NAMESPACE(octave)
OCTAVE_BEGIN_NAMESPACE(octave) static octave_value daspk_fcn
F77_RET_T const F77_DBLE const F77_DBLE F77_DBLE * d
void skip_until_newline(std::istream &is, bool keep_newline)
std::string read_until_newline(std::istream &is, bool keep_newline)
void skip_preceeding_newline(std::istream &is)