00001 /* 00002 00003 Copyright (C) 2009-2012 Benjamin Lindner 00004 00005 This file is part of Octave. 00006 00007 Octave is free software; you can redistribute it and/or modify it 00008 under the terms of the GNU General Public License as published by the 00009 Free Software Foundation; either version 3 of the License, or (at your 00010 option) any later version. 00011 00012 Octave is distributed in the hope that it will be useful, but WITHOUT 00013 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 00014 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 00015 for more details. 00016 00017 You should have received a copy of the GNU General Public License 00018 along with Octave; see the file COPYING. If not, see 00019 <http://www.gnu.org/licenses/>. 00020 00021 */ 00022 00023 #ifdef HAVE_CONFIG_H 00024 #include <config.h> 00025 #endif 00026 00027 #include "ls-ascii-helper.h" 00028 00029 #include <iostream> 00030 #include <sstream> 00031 00032 // Helper functions when reading from ascii files. 00033 00034 // These function take care of CR/LF issues when files are opened in 00035 // text-mode for reading. 00036 00037 // Skip characters from stream IS until a newline is reached. 00038 // Depending on KEEP_NEWLINE, either eat newline from stream or 00039 // keep it unread. 00040 00041 void 00042 skip_until_newline (std::istream& is, bool keep_newline) 00043 { 00044 if (! is) 00045 return; 00046 00047 while (is) 00048 { 00049 char c = is.peek (); 00050 00051 if (c == '\n' || c == '\r') 00052 { 00053 // Reached newline. 00054 if (! keep_newline) 00055 { 00056 // Eat the CR or LF character. 00057 char d; 00058 is.get (d); 00059 00060 // Make sure that for binary-mode opened ascii files 00061 // containing CRLF line endings we skip the LF after CR. 00062 if (c == '\r' && is.peek () == '\n') 00063 { 00064 // Yes, LF following CR, eat it. 00065 is.get (d); 00066 } 00067 } 00068 00069 // Newline was found, and read from stream if 00070 // keep_newline == true, so exit loop. 00071 break; 00072 } 00073 else 00074 { 00075 // No newline charater peeked, so read it and proceed to next 00076 // character. 00077 char d; 00078 is.get (d); 00079 } 00080 } 00081 } 00082 00083 00084 // If stream IS currently points to a newline (a leftover from a 00085 // previous read) then eat newline(s) until a non-newline character is 00086 // found. 00087 00088 void 00089 skip_preceeding_newline (std::istream& is) 00090 { 00091 if (! is) 00092 return; 00093 00094 // Check whether IS currently points to newline character. 00095 char c = is.peek (); 00096 00097 if (c == '\n' || c == '\r') 00098 { 00099 // Yes, at newline. 00100 do 00101 { 00102 // Eat the CR or LF character. 00103 char d; 00104 is.get (d); 00105 00106 // Make sure that for binary-mode opened ascii files 00107 // containing CRLF line endings we skip the LF after CR. 00108 if (c == '\r' && is.peek () == '\n') 00109 { 00110 // Yes, LF following CR, eat it. 00111 is.get (d); 00112 } 00113 00114 // Peek into next character. 00115 c = is.peek (); 00116 00117 // Loop while still a newline ahead. 00118 } 00119 while (c == '\n' || c == '\r'); 00120 } 00121 } 00122 00123 // Read charaters from stream IS until a newline is reached. 00124 // Depending on KEEP_NEWLINE, either eat newline from stream or keep 00125 // it unread. Characters read are stored and returned as 00126 // std::string. 00127 00128 std::string 00129 read_until_newline (std::istream& is, bool keep_newline) 00130 { 00131 if (! is) 00132 return std::string (); 00133 00134 std::ostringstream buf; 00135 00136 while (is) 00137 { 00138 char c = is.peek (); 00139 00140 if (c == '\n' || c == '\r') 00141 { 00142 // Reached newline. 00143 if (! keep_newline) 00144 { 00145 // Eat the CR or LF character. 00146 char d; 00147 is.get (d); 00148 00149 // Make sure that for binary-mode opened ascii files 00150 // containing CRLF line endings we skip the LF after 00151 // CR. 00152 00153 if (c == '\r' && is.peek () == '\n') 00154 { 00155 // Yes, LF following CR, eat it. 00156 is.get (d); 00157 } 00158 } 00159 00160 // Newline was found, and read from stream if 00161 // keep_newline == true, so exit loop. 00162 break; 00163 } 00164 else 00165 { 00166 // No newline charater peeked, so read it, store it, and 00167 // proceed to next. 00168 char d; 00169 is.get (d); 00170 buf << d; 00171 } 00172 } 00173 00174 return buf.str (); 00175 }