"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