"Fossies" - the Fresh Open Source Software Archive

Member "regexxer-0.10/src/fileio.cc" (6 Oct 2011, 5144 Bytes) of package /linux/privat/old/regexxer-0.10.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "fileio.cc" see the Fossies "Dox" file reference documentation.

    1 /*
    2  * Copyright (c) 2002-2007  Daniel Elstner  <daniel.kitta@gmail.com>
    3  *
    4  * This file is part of regexxer.
    5  *
    6  * regexxer is free software; you can redistribute it and/or modify
    7  * it under the terms of the GNU General Public License as published by
    8  * the Free Software Foundation; either version 2 of the License, or
    9  * (at your option) any later version.
   10  *
   11  * regexxer is distributed in the hope that it will be useful,
   12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
   13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   14  * GNU General Public License for more details.
   15  *
   16  * You should have received a copy of the GNU General Public License
   17  * along with regexxer; if not, write to the Free Software Foundation,
   18  * Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
   19  */
   20 
   21 #include "fileio.h"
   22 #include "filebuffer.h"
   23 #include "miscutils.h"
   24 #include "stringutils.h"
   25 
   26 #include <glib.h>
   27 #include <glibmm.h>
   28 #include <giomm.h>
   29 #include <gtksourceviewmm.h> 
   30 #include <cstring>
   31 
   32 namespace
   33 {
   34 
   35 using Regexxer::FileBuffer;
   36 
   37 enum { BUFSIZE = 4096 };
   38 
   39 static
   40 Glib::RefPtr<FileBuffer> load_iochannel(const Glib::RefPtr<Glib::IOChannel>& input)
   41 {
   42   const Glib::RefPtr<FileBuffer> text_buffer = FileBuffer::create();
   43   FileBuffer::iterator text_end = text_buffer->end();
   44 
   45   const Util::ScopedArray<char> inbuf (new char[BUFSIZE]);
   46   gsize bytes_read = 0;
   47 
   48   text_buffer->begin_not_undoable_action();
   49   while (input->read(inbuf.get(), BUFSIZE, bytes_read) == Glib::IO_STATUS_NORMAL)
   50   {
   51     if (std::memchr(inbuf.get(), '\0', bytes_read)) // binary file?
   52       throw Regexxer::ErrorBinaryFile();
   53 
   54     text_end = text_buffer->insert(text_end, inbuf.get(), inbuf.get() + bytes_read);
   55   }
   56   text_buffer->end_not_undoable_action();
   57 
   58   g_assert(bytes_read == 0);
   59 
   60   return text_buffer;
   61 }
   62 
   63 static
   64 void save_iochannel(const Glib::RefPtr<Glib::IOChannel>& output, const Glib::RefPtr<FileBuffer>& buffer)
   65 {
   66   FileBuffer::iterator stop = buffer->begin();
   67 
   68   for (FileBuffer::iterator start = stop; start; start = stop)
   69   {
   70     stop.forward_chars(BUFSIZE); // inaccurate, but doesn't matter
   71     const Glib::ustring chunk = buffer->get_slice(start, stop);
   72 
   73     gsize bytes_written = 0;
   74     const Glib::IOStatus status = output->write(chunk.data(), chunk.bytes(), bytes_written);
   75 
   76     // These conditions really must hold true at this point
   77     // since any error should have caused an exception.
   78     g_assert(status == Glib::IO_STATUS_NORMAL);
   79     g_assert(bytes_written == chunk.bytes());
   80   }
   81 }
   82 
   83 static
   84 Glib::RefPtr<FileBuffer> load_try_encoding(const std::string& filename, const std::string& encoding)
   85 {
   86   const Glib::RefPtr<Glib::IOChannel> channel = Glib::IOChannel::create_from_file(filename, "r");
   87 
   88   channel->set_buffer_size(BUFSIZE);
   89 
   90   try
   91   {
   92     channel->set_encoding(encoding);
   93     return load_iochannel(channel);
   94   }
   95   catch (const Glib::ConvertError&)
   96   {}
   97 
   98   return Glib::RefPtr<FileBuffer>();
   99 }
  100 
  101 } // anonymous namespace
  102 
  103 
  104 namespace Regexxer
  105 {
  106 
  107 /**** Regexxer::FileInfoBase ***********************************************/
  108 
  109 FileInfoBase::~FileInfoBase()
  110 {}
  111 
  112 
  113 /**** Regexxer::DirInfo ****************************************************/
  114 
  115 DirInfo::DirInfo()
  116 :
  117   file_count     (0),
  118   modified_count (0)
  119 {}
  120 
  121 DirInfo::~DirInfo()
  122 {}
  123 
  124 
  125 /**** Regexxer::FileInfo ***************************************************/
  126 
  127 FileInfo::FileInfo(const std::string& fullname_)
  128 :
  129   fullname    (fullname_),
  130   load_failed (false)
  131 {}
  132 
  133 FileInfo::~FileInfo()
  134 {}
  135 
  136 
  137 /**** Regexxer -- file I/O functions ***************************************/
  138 
  139 void load_file(const FileInfoPtr& fileinfo, const std::string& fallback_encoding)
  140 {
  141   fileinfo->load_failed = true;
  142 
  143   std::string encoding = "UTF-8";
  144   Glib::RefPtr<FileBuffer> buffer = load_try_encoding(fileinfo->fullname, encoding);
  145 
  146   if (!buffer && !Glib::get_charset(encoding)) // locale charset is _not_ UTF-8
  147   {
  148     buffer = load_try_encoding(fileinfo->fullname, encoding);
  149   }
  150 
  151   if (!buffer && !Util::encodings_equal(encoding, fallback_encoding))
  152   {
  153     encoding = fallback_encoding;
  154     buffer = load_try_encoding(fileinfo->fullname, encoding);
  155   }
  156 
  157   if (!buffer)
  158     throw ErrorBinaryFile();
  159 
  160   Glib::RefPtr<Gsv::LanguageManager> language_manager = Gsv::LanguageManager::create();
  161   
  162   bool uncertain = false;
  163   std::string content_type = Gio::content_type_guess(fileinfo->fullname, buffer->get_text(), uncertain);
  164 
  165   buffer->set_highlight_syntax(true);
  166   buffer->set_language(language_manager->guess_language(fileinfo->fullname, content_type));
  167   buffer->set_modified(false);
  168 
  169   fileinfo->encoding    = encoding;
  170   fileinfo->buffer      = buffer;
  171   fileinfo->load_failed = false;
  172 }
  173 
  174 void save_file(const FileInfoPtr& fileinfo)
  175 {
  176   const Glib::RefPtr<Glib::IOChannel> channel =
  177       Glib::IOChannel::create_from_file(fileinfo->fullname, "w");
  178 
  179   channel->set_buffer_size(BUFSIZE);
  180   channel->set_encoding(fileinfo->encoding);
  181 
  182   save_iochannel(channel, fileinfo->buffer);
  183 
  184   // Explicitely close() the buffer at this point so that
  185   // we get an exception if closing the file fails.
  186   channel->close();
  187 
  188   fileinfo->buffer->set_modified(false);
  189 }
  190 
  191 } // namespace Regexxer