diff --git a/src/gmenu2x.cpp b/src/gmenu2x.cpp index 08ff48e..232b136 100644 --- a/src/gmenu2x.cpp +++ b/src/gmenu2x.cpp @@ -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(); } } diff --git a/src/linkapp.cpp b/src/linkapp.cpp index 3ab9aae..a8baa6a 100644 --- a/src/linkapp.cpp +++ b/src/linkapp.cpp @@ -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; } diff --git a/src/utilities.cpp b/src/utilities.cpp index c85fff0..4ff4075 100644 --- a/src/utilities.cpp +++ b/src/utilities.cpp @@ -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 ""; + } + + // 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 ""; + } else { + contents.shrink_to_fit(); + return contents; + } +} + bool fileExists(const string &file) { fstream fin; fin.open(file.c_str() ,ios::in); diff --git a/src/utilities.h b/src/utilities.h index aa29308..d9f235d 100644 --- a/src/utilities.h +++ b/src/utilities.h @@ -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);