src/ls-ascii-helper.cc
author Benjamin Lindner <lindnerb@users.sourceforge.net>
Wed Mar 18 15:23:14 2009 +0100 (2009-03-18)
changeset 7685 34b75a47e712
permissions -rw-r--r--
fix leaving stray '\r' in stream when reading from CRLF data file
* * *
fix CRLF issues with text-mode reading in windows when loading ascii data
     1 /*
     2 
     3 Copyright (C) 2003, 2005, 2006, 2007 John W. Eaton
     4 
     5 This file is part of Octave.
     6 
     7 Octave is free software; you can redistribute it and/or modify it
     8 under the terms of the GNU General Public License as published by the
     9 Free Software Foundation; either version 3 of the License, or (at your
    10 option) any later version.
    11 
    12 Octave is distributed in the hope that it will be useful, but WITHOUT
    13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    14 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    15 for more details.
    16 
    17 You should have received a copy of the GNU General Public License
    18 along with Octave; see the file COPYING.  If not, see
    19 <http://www.gnu.org/licenses/>.
    20 
    21 */
    22 
    23 
    24 #include "ls-ascii-helper.h"
    25 
    26 #include <iostream>
    27 #include <sstream>
    28 
    29 // Helper functions when reading from ascii files.
    30 // These function take care of CR/LF issues when files are opened in text-mode for reading 
    31 
    32 // Skip characters from stream IS until a newline is reached.
    33 // Depending on KEEP_NEWLINE, either eat newline from stream or
    34 // keep it unread
    35 
    36 void
    37 skip_until_newline( std::istream& is, bool keep_newline )
    38 {
    39   if (!is)
    40     return;
    41   
    42   char c,d;
    43   
    44   while (is)
    45   {
    46       c = is.peek();
    47       if (c == '\n' || c == '\r')
    48       {
    49 	  // reached newline
    50 	  if (keep_newline == false)
    51 	  {
    52 	      // eat the CR or LF character
    53 	      is.get(d);
    54 	      
    55 	      // make sure that for binary-mode opened ascii files containing CRLF line endings
    56 	      // we skip the LF after CR...
    57 	      if (c == '\r' && is.peek()=='\n')
    58 	      {
    59 		  // yes, LF following CR, eat it...
    60 		  is.get(d);
    61 	      }
    62 	  }
    63 	  
    64 	  // Newline was found, and read from stream if keep_newline==true, so exit loop
    65 	  break;
    66       }
    67       else
    68 	  // no newline charater peeked, so read it and proceed to next character
    69 	  is.get(d);
    70   }
    71   
    72   return;
    73 }
    74 
    75 
    76 // If stream IS currently points to a newline (a leftover from a previous read)
    77 // then eat newline(s) until a non-newline character is found
    78 
    79 void
    80 skip_preceeding_newline( std::istream& is )
    81 {
    82   if (!is)
    83     return;
    84   
    85   char c,d;
    86   
    87   // Check if IS currently points to newline character
    88   c = is.peek();
    89   if (c == '\n' || c == '\r')
    90   {
    91       // Yes, at newline
    92       do {
    93 	  // eat the CR or LF character
    94 	  is.get(d);
    95 	  
    96 	  // make sure that for binary-mode opened ascii files containing CRLF line endings
    97 	  // we skip the LF after CR...
    98 	  if (c == '\r' && is.peek() == '\n')
    99 	  {
   100 	      // yes, LF following CR, eat it...
   101 	      is.get(d);
   102 	  }
   103 	  
   104 	  // Peek into next character
   105 	  c = is.peek();
   106       // Loop while still a newline ahead
   107       } while( c == '\n' || c == '\r' );
   108   }
   109   
   110   return;
   111 }
   112 
   113 
   114 // Read charaters from stream IS until a newline is reached.
   115 // Depending on KEEP_NEWLINE, either eat newline from stream or
   116 // keep it unread
   117 // Characters read are stored and returned as std::string
   118 
   119 std::string
   120 read_until_newline( std::istream& is, bool keep_newline )
   121 {
   122   if (!is)
   123     return std::string();
   124   
   125   char c,d;
   126   std::ostringstream buf;
   127   
   128   while (is)
   129   {
   130       c = is.peek();
   131       if (c == '\n' || c == '\r')
   132       {
   133 	  // reached newline
   134 	  if (keep_newline == false)
   135 	  {
   136 	      // eat the CR or LF character
   137 	      is.get(d);
   138 	      
   139 	      // make sure that for binary-mode opened ascii files containing CRLF line endings
   140 	      // we skip the LF after CR...
   141 	      if (c == '\r' && is.peek() == '\n')
   142 	      {
   143 		  // yes, LF following CR, eat it...
   144 		  is.get(d);
   145 	      }
   146 	  }
   147 	  
   148 	  // Newline was found, and read from stream if keep_newline==true, so exit loop
   149 	  break;
   150       }
   151       else
   152       {
   153 	  // no newline charater peeked, so read it, store it, and proceed to next
   154 	  is.get(d);
   155 	  buf << d;
   156       }
   157   }
   158   
   159   return buf.str();
   160 }