<commit_before>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#include <fstream>
#include <mpd/client.h>
#include <taglib/fileref.h>
#include "consumer.hh"
#include "globals.hh"


Consumer::Consumer(std::string&& throwaway)
    : _playlist_file_(std::move(throwaway))
    , _write_to_file_(true) {

    std::ifstream file(_playlist_file_);

    if (file) {
        std::string temp;
        while (getline(file, temp)) {
            _playlist_lines_.insert(temp);
        }
    }
}

void Consumer::_sorted_insert_song_(const std::string& str) {
    bool inserted = _playlist_lines_.insert(str).second;
    if (NONO && inserted) {
        std::printf("Insert `%s` into playlist `%s`.\n", str.c_str(),
                    _playlist_file_.c_str());
    }
}

Consumer::~Consumer() {
    if (_write_to_file_) {
        if (!NONO) {
            if (auto file = std::ofstream(_playlist_file_)) {
                for (const auto& s : _playlist_lines_) {
                    file << s << '\n';
                }
                if (USE_MPD) {
                    _run_mpd_();
                }
            } else {
                std::fprintf(stderr,
                             "Problem opening file %s!\nAborting!\n",
                             _playlist_file_.c_str());
                std::exit(EXIT_FAILURE);
            }
        } else if (USE_MPD) {
            std::printf("Will clear the mpd playlist, update the mpd "
                        "database, and load %s.\n",
                        boost::filesystem::path(_playlist_file_)
                            .filename()
                            .replace_extension()<commit_msg>Reinvent ifstream and ofstream to increase performance.<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#include <mpd/client.h>
#include <taglib/fileref.h>
#include <stdexcept>

#include "consumer.hh"
#include "globals.hh"

struct ifstream {
    std::FILE* file;

    explicit ifstream(const char* path) {
        file = std::fopen(path, "r");
    }
    ~ifstream() noexcept { std::fclose(file); }
    ifstream(const ifstream&) = delete;
    ifstream& operator=(const ifstream&) = delete;

    bool read_line(std::string& other) {
        other.clear();
        for (int c = std::fgetc(file); c != EOF;
             c = std::fgetc(file)) {
            if (c == int('\n')) {
                return true;
            } else {
                other += char(c);
            }
        }
        return false;
    }

    operator bool() noexcept { return file; }
};

struct ofstream {
    std::FILE* file;

    explicit ofstream(const char* path) {
        file = std::fopen(path, "w");
    }
    ~ofstream() noexcept { std::fclose(file); }
    ofstream(ofstream&& other) noexcept : file(nullptr) {
        *this = std::move(other);
    }
    ofstream& operator=(ofstream&& other) noexcept {
        std::swap(file, other.file);
        return *this;
    }

    bool write(const char* str) noexcept {
        return std::fputs(str, file) != EOF;
    }

    bool write(char c) noexcept {
        return std::fputc(c, file) != EOF;
    }

    operator bool() noexcept { return file; }
};

Consumer::Consumer(std::string&& throwaway)
    : _playlist_file_(std::move(throwaway))
    , _write_to_file_(true) {

    ifstream file(_playlist_file_.c_str());

    if (file) {
        std::string temp;
        while (file.read_line(temp)) {
            _playlist_lines_.insert(temp);
        }
    }
}

void Consumer::_sorted_insert_song_(const std::string& str) {
    bool inserted = _playlist_lines_.insert(str).second;
    if (NONO && inserted) {
        std::printf("Insert `%s` into playlist `%s`.\n", str.c_str(),
                    _playlist_file_.c_str());
    }
}

Consumer::~Consumer() {
    if (_write_to_file_) {
        if (!NONO) {
            if (auto file = ofstream(_playlist_file_.c_str())) {
                for (const auto& s : _playlist_lines_) {
                    if (!(file.write(s.c_str()) &&
                          file.write('\n'))) {
                        throw std::runtime_error(
                            "In ofstream::write: Error writing to "
                            "playlist file.");
                    }
                }
                if (USE_MPD) {
                    _run_mpd_();
                }
            } else {
                std::fprintf(stderr,
                             "Problem opening file %s!\nAborting!\n",
                             _playlist_file_.c_str());
                std::exit(EXIT_FAILURE);
            }
        } else if (USE_MPD) {
            std::printf("Will clear the mpd playlist, update the mpd "
                        "database, and load %s.\n",
                        boost::filesystem::path(_playlist_file_)
                            .filename()
                            .replace_extension()
{'fraction_non_alphanumeric': 0.1307722157547536, 'fraction_numerical': 0.0015521924718665113, 'mean_word_length': 1.7347480106100797, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '457060', 'n_tokens_mistral': 1584, 'n_tokens_neox': 1540, 'n_words': 355}