1
0
mirror of git://projects.qi-hardware.com/gmenu2x.git synced 2024-06-30 20:34:11 +03:00

Made text file reading more efficient and robust

Instead of reading the file line by line and then concatenating those
lines, just load the entire thing in one go. And pay more attention to
error conditions.
This commit is contained in:
Maarten ter Huurne 2014-07-24 10:41:20 +02:00
parent d0de870180
commit 485bab3b48
4 changed files with 46 additions and 45 deletions

View File

@ -409,45 +409,27 @@ void GMenu2X::initMenu() {
}
void GMenu2X::about() {
string str, line;
string fn(GMENU2X_SYSTEM_DIR);
string build_date("Build date: ");
fn.append("/about.txt");
build_date.append(__DATE__);
ifstream inf(fn.c_str(), ios_base::in);
while(getline(inf, line, '\n')) {
str.append(line).append("\n");
}
inf.close();
TextDialog td(this, "GMenu2X", build_date, "icons/about.png", str);
string text(readFileAsString(GMENU2X_SYSTEM_DIR "/about.txt"));
string build_date("Build date: " __DATE__);
TextDialog td(this, "GMenu2X", build_date, "icons/about.png", text);
td.exec();
}
void GMenu2X::viewLog() {
string logfile = LOG_FILE;
if (fileExists(logfile)) {
ifstream inf(logfile.c_str(), ios_base::in);
if (inf.is_open()) {
string str, line;
while (getline(inf, line, '\n')) {
str.append(line).append("\n");
}
inf.close();
string text(readFileAsString(LOG_FILE));
TextDialog td(this, tr["Log Viewer"], tr["Displays last launched program's output"], "icons/ebook.png", str);
td.exec();
TextDialog td(this, tr["Log Viewer"],
tr["Displays last launched program's output"],
"icons/ebook.png", text);
td.exec();
MessageBox mb(this, tr["Do you want to delete the log file?"], "icons/ebook.png");
mb.setButton(InputManager::ACCEPT, tr["Yes"]);
mb.setButton(InputManager::CANCEL, tr["No"]);
if (mb.exec() == InputManager::ACCEPT) {
unlink(logfile.c_str());
menu->deleteSelectedLink();
}
}
MessageBox mb(this, tr["Do you want to delete the log file?"],
"icons/ebook.png");
mb.setButton(InputManager::ACCEPT, tr["Yes"]);
mb.setButton(InputManager::CANCEL, tr["No"]);
if (mb.exec() == InputManager::ACCEPT) {
unlink(LOG_FILE);
menu->deleteSelectedLink();
}
}

View File

@ -491,18 +491,9 @@ void LinkApp::showManual() {
// Txt manuals
if (manual.substr(manual.size()-8,8)==".man.txt") {
string str, line;
ifstream infile(manual.c_str(), ios_base::in);
if (infile.is_open()) {
while (getline(infile, line, '\n')) {
str.append(line).append("\n");
}
infile.close();
TextManualDialog tmd(gmenu2x, getTitle(), getIconPath(), str);
tmd.exec();
}
string text(readFileAsString(manual.c_str()));
TextManualDialog tmd(gmenu2x, getTitle(), getIconPath(), text);
tmd.exec();
return;
}

View File

@ -56,6 +56,31 @@ string rtrim(const string& s) {
return e == string::npos ? "" : string(s, 0, e + 1);
}
// See this article for a performance comparison of different approaches:
// http://insanecoding.blogspot.com/2011/11/how-to-read-in-file-in-c.html
string readFileAsString(const char *filename) {
ifstream in(filename, ios::in | ios::binary);
if (!in) {
return "<error opening " + string(filename) + ">";
}
// Get file size.
in.seekg(0, ios::end);
auto size = max(int(in.tellg()), 0); // tellg() returns -1 on errors
in.seekg(0, ios::beg);
string contents(size, '\0');
in.read(&contents[0], contents.size());
in.close();
if (in.fail()) {
return "<error reading " + string(filename) + ">";
} else {
contents.shrink_to_fit();
return contents;
}
}
bool fileExists(const string &file) {
fstream fin;
fin.open(file.c_str() ,ios::in);

View File

@ -46,6 +46,9 @@ std::string ltrim(const std::string& s);
/** Returns the string with whitespace stripped from the end. */
std::string rtrim(const std::string& s);
/** Returns the contents of the given file as a string. */
std::string readFileAsString(const char *filename);
std::string strreplace(std::string orig, const std::string &search, const std::string &replace);
std::string cmdclean(std::string cmdline);