~aleteoryx/muditaos

ref: e8f7a57219ea7c881cf53322fe6a3c6b0c5e7c56 muditaos/module-apps/application-settings-new/models/QuotesRepository.cpp -rw-r--r-- 3.4 KiB
e8f7a572 — Tomasz Langowski [EGD-5758] Restore auto locking timer in ApplicationManager 4 years ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include "QuotesRepository.hpp"

#include <module-utils/gsl/gsl_util>
#include <algorithm>
#include <utility>

namespace app
{
    QuotesJsonRepository::QuotesJsonRepository(const std::string &path) : repositoryPath{std::move(path)}
    {}

    void QuotesJsonRepository::get(std::uint32_t offset, std::uint32_t limit, const OnGetCallback &callback)
    {
        if (quotes.empty()) {
            readQuotes(repositoryPath);
        }

        if (callback) {
            std::uint32_t size = quotes.size();
            auto start         = std::next(quotes.begin(), std::min(offset, size));
            auto end           = std::next(quotes.begin(), std::min(offset + limit, size));
            std::list<QuoteRecord> result{start, end};
            callback(result, result.size());
        }
    }

    void QuotesJsonRepository::save(const QuoteRecord &quote)
    {
        auto toEdit = std::find_if(quotes.begin(), quotes.end(), [quote](auto &&d) { return d.id == quote.id; });

        if (toEdit != quotes.end()) {
            toEdit->quote  = quote.quote;
            toEdit->author = quote.author;
        }
        else if (quote.id == 0) {
            quotes.push_back(quote);
        }

        writeQuotes(repositoryPath);
    }

    void QuotesJsonRepository::remove(const QuoteRecord &quote)
    {
        quotes.remove_if([quote](auto &&d) { return d.id == quote.id; });
        writeQuotes(repositoryPath);
    }

    void QuotesJsonRepository::writeQuotes(const std::filesystem::path &quotesFilename)
    {
        if (auto file = std::fopen(repositoryPath.c_str(), "w"); file != nullptr) {
            auto _    = gsl::finally([file] { std::fclose(file); });
            auto body = json11::Json{quotes};
            auto text = body.dump();
            std::fwrite(text.c_str(), 1, text.length(), file);
        }
    }

    void QuotesJsonRepository::readQuotes(const std::filesystem::path &quotesFilename)
    {
        std::string err;

        const auto fileContents = readFileToString(quotesFilename);
        auto obj                = json11::Json::parse(fileContents.c_str(), err).array_items();

        if (!err.empty()) {
            LOG_ERROR("Error while parsing quotes from file: %s error: %s ", quotesFilename.c_str(), err.c_str());
            return;
        }

        quotes.clear();

        auto id = 1;
        std::transform(obj.begin(), obj.end(), std::back_inserter(quotes), [&id](auto item) {
            return QuoteRecord{id++, item["quote"].string_value(), item["author"].string_value()};
        });
    }

    auto QuotesJsonRepository::readFileToString(const std::filesystem::path &filename) -> std::string
    {
        constexpr auto tar_buf = 8192 * 4;
        auto file              = std::fopen(filename.c_str(), "r");
        if (file == nullptr) {
            return {};
        }
        auto _            = gsl::finally([file] { std::fclose(file); });
        const auto length = std::filesystem::file_size(filename);

        if (length >= tar_buf) {
            LOG_ERROR("File %s length is too high!", filename.c_str());
            return {};
        }
        LOG_INFO("file length: %u", static_cast<unsigned int>(length));
        auto buffer = std::make_unique<char[]>(length + 1);
        std::fread(buffer.get(), 1, length, file);
        return std::string(buffer.get());
    }
} // namespace app