view liboctave/util/file-info.cc @ 28467:159b6a1eb408

Use wide character overload to open file streams on Windows. * liboctave/system/lo-sysdep.cc, liboctave/system/lo-sysdep.h (fstream, ifstream, ofstream): Add "wrapper" functions to open file streams. * libinterp/corefcn/__fcn__.cc (F__ftp_mput__, F__ftp_mget__), libinterp/corefcn/debug.cc (do_dbtype), libinterp/corefcn/help.cc (help_system::raw_help_from_docstrings_file), libinterp/corefcn/load-save.cc (check_gzip_magic, load_save_system::get_file_format, load_save_system::dump_octave_core, load_save_system::load, load_save_system::save), libinterp/corefcn/oct-hist.cc (mk_tmp_hist_file, history_system::do_edit_history), libinterp/corefcn/urlwrite.cc (Furlwrite), libinterp/octave-value/ov-java.cc (read_java_opts, read_classpath_txt), libinterp/parse-tree/oct-parse.yy (get_file_line), liboctave/util/cmd-hist.cc (gnu_history::do_append), liboctave/util/file-info.cc (file_info::snarf_file), liboctave/util/url-transfer.cc (base_url_transfer::mget_directory, base_url_transfer::mput_directory): Use new functions. * libinterp/corefcn/dlmread.cc (dlmread): Use wide character overload for std::ifstream::open on Windows. * src/mkoctfile.in.cc (octave_u8_conv_to_encoding): Dummy function for cross-compiler. (main): Use wide character overload of std::ofstream::open on Windows.
author Markus Mützel <markus.muetzel@gmx.de>
date Fri, 12 Jun 2020 22:13:04 +0200
parents bd51beb6205e
children 0a5b15007766
line wrap: on
line source

////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001-2020 The Octave Project Developers
//
// See the file COPYRIGHT.md in the top-level directory of this
// distribution or <https://octave.org/copyright/>.
//
// This file is part of Octave.
//
// Octave is free software: you can redistribute it and/or modify it
// under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Octave is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Octave; see the file COPYING.  If not, see
// <https://www.gnu.org/licenses/>.
//
////////////////////////////////////////////////////////////////////////

#if defined (HAVE_CONFIG_H)
#  include "config.h"
#endif

#include <deque>
#include <fstream>

#include "file-info.h"
#include "file-stat.h"
#include "lo-error.h"
#include "lo-sysdep.h"

namespace octave
{
  std::string file_info::get_line (size_t line) const
  {
    std::string retval;

    if (line == 0)
      return retval;

    if (line < m_offsets.size ())
      {
        size_t bol = m_offsets[line-1];
        size_t eol = m_offsets[line];

        while (eol > 0 && eol > bol
               && (m_file_buf[eol-1] == '\n' || m_file_buf[eol-1] == '\r'))
          eol--;

        retval = m_file_buf.substr (bol, eol - bol);
      }

    return retval;
  }

  std::deque<std::string>
  file_info::get_lines (size_t line, size_t num_lines) const
  {
    std::deque<std::string> retval;

    for (size_t i = line; i < line+num_lines; i++)
      retval.push_back (get_line (i));

    return retval;
  }

  // Read entire file called fname and return the contents as a string

  std::string file_info::snarf_file (const std::string& fname)
  {
    std::string retval;

    sys::file_stat fs (fname);

    if (! fs)
      (*current_liboctave_error_handler) ("no such file, '%s'", fname.c_str ());

    size_t sz = fs.size ();

    std::ifstream file = sys::ifstream (fname.c_str (),
                                        std::ios::in | std::ios::binary);

    if (file)
      {
        std::string buf (sz+1, 0);

        file.read (&buf[0], sz+1);

        if (! file.eof ())
          (*current_liboctave_error_handler)
            ("error reading file %s", fname.c_str ());

        // Expected to read the entire file.
        retval = buf;
      }

    return retval;
  }

  std::vector<size_t> file_info::get_line_offsets (const std::string& buf)
  {
    std::deque<size_t> tmp_offsets;

    tmp_offsets.push_back (0);

    size_t len = buf.length ();

    for (size_t i = 0; i < len; i++)
      {
        char c = buf[i];

        if (c == '\r' && ++i < len)
          {
            c = buf[i];

            if (c == '\n')
              tmp_offsets.push_back (i+1);
            else
              tmp_offsets.push_back (i);
          }
        else if (c == '\n')
          tmp_offsets.push_back (i+1);
      }

    tmp_offsets.push_back (len-1);

    size_t n = tmp_offsets.size ();

    std::vector<size_t> retval (n);
    size_t i = 0;
    for (auto& elt : tmp_offsets)
      retval[i++] = elt;

    return retval;
  }
}