aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/test/unit_tests/shared/fixed_size.hpp
blob: a796f5612945c9621c36d2614f71798e11982fef (plain) (blame)
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
// Copyright (c) 2020 Egor Tensin <Egor.Tensin@gmail.com>
// This file is part of the "winapi-common" project.
// For details, see https://github.com/egor-tensin/winapi-common.
// Distributed under the MIT License.

#pragma once

#include <array>
#include <cstddef>
#include <cstring>
#include <string>
#include <vector>

namespace fixed_size {

/*
 * These are fixed-size classes, to be used as part of an interprocess shared
 * memory region.
 */

// 120 characters is an arbitrary limit, strings are cut to this many
// characters for storage.
template <std::size_t Length = 120>
class String : public std::array<char, Length> {
public:
    static String convert(const std::string& src) {
        String dest;
        std::size_t nch = dest.size() - 1;
        if (src.size() < nch) {
            nch = src.size();
        }
        std::memcpy(dest.data(), src.c_str(), nch);
        dest[nch] = '\0';
        return dest;
    }

    std::string extract() const {
        // Lines are null-terminated, and don't store their lenghts, so...
        return this->data();
    }
};

// 5 lines to store is also arbitrary, set it higher if needed.
template <std::size_t Length = 5, std::size_t StringLength = 120>
struct StringList : public std::array<String<StringLength>, Length> {
    static StringList convert(const std::vector<std::string>& src) {
        // If src.size() > Length, only the last Length lines from the source
        // list are stored.

        StringList dest;
        std::memset(&dest, 0, sizeof(dest));

        std::size_t src_offset = 0;
        if (src.size() > dest.size()) {
            src_offset = src.size() - dest.size();
        }

        for (std::size_t i = 0, j = src_offset; i < dest.size() && j < src.size();
             ++i, ++j, ++dest.numof_lines) {
            dest[i] = dest[i].convert(src[j]);
        }

        return dest;
    }

    std::vector<std::string> extract() const {
        std::vector<std::string> dest;
        for (std::size_t i = 0; i < numof_lines; ++i) {
            dest.emplace_back(this->at(i).extract());
        }
        return dest;
    }

    std::size_t numof_lines;
};

} // namespace fixed_size