update ffmpeg.git files for newer versions
[goodguy/cinelerra.git] / cinelerra-5.1 / tools / makeappimagetool / desktopfile.cpp
1 // system headers
2 #include <cassert>
3 #include <fstream>
4
5 // local headers
6 #include "includes/desktopfile_exceptions.h"
7 #include "includes/desktopfile.h"
8 #include "includes/desktopfilereader.h"
9 #include "includes/desktopfilewriter.h"
10
11 namespace linuxdeploy {
12     namespace desktopfile {
13         class DesktopFile::PrivateData {
14             public:
15                 std::string path;
16                 sections_t data;
17
18             public:
19                 PrivateData() = default;
20
21                 void copyData(const std::shared_ptr<PrivateData>& other) {
22                     path = other->path;
23                     data = other->data;
24                 }
25
26         public:
27             bool isEmpty() const {
28                 return data.empty();
29             }
30         };
31
32         DesktopFile::DesktopFile() : d(std::make_shared<PrivateData>()) {}
33
34         DesktopFile::DesktopFile(const std::string& path) : DesktopFile() {
35             // if the file doesn't exist, an exception shall be thrown
36             // otherwise, a user cannot know for sure whether a file was actually read (would need to check this
37             // manually beforehand
38             {
39                 std::ifstream ifs(path);
40                 if (!ifs) {
41                     throw IOError("Could not find file " + path);
42                 }
43             }
44
45             // will throw exceptions in case of issues
46             read(path);
47         };
48
49         DesktopFile::DesktopFile(std::istream& is) : DesktopFile() {
50             // will throw exceptions in case of issues
51             read(is);
52         };
53
54         // copy constructor
55         DesktopFile::DesktopFile(const DesktopFile& other) : DesktopFile() {
56             d->copyData(other.d);
57         }
58
59         // copy assignment constructor
60         DesktopFile& DesktopFile::operator=(const DesktopFile& other) {
61             if (this != &other) {
62                 d->copyData(other.d);
63             }
64
65             return *this;
66         }
67
68         // move assignment operator
69         DesktopFile& DesktopFile::operator=(DesktopFile&& other) noexcept {
70             if (this != &other) {
71                 d = other.d;
72                 other.d = nullptr;
73             }
74             return *this;
75         }
76
77         void DesktopFile::read(const std::string& path) {
78             setPath(path);
79
80             // clear data before reading a new file
81             clear();
82
83             DesktopFileReader reader(path);
84             d->data = std::move(reader.data());
85         }
86
87         void DesktopFile::read(std::istream& is) {
88             // clear data before reading a new file
89             clear();
90
91             DesktopFileReader reader(is);
92             d->data = reader.data();
93         }
94
95         std::string DesktopFile::path() const {
96             return d->path;
97         }
98
99         void DesktopFile::setPath(const std::string& path) {
100             d->path = path;
101         }
102
103         bool DesktopFile::isEmpty() const {
104             return d->isEmpty();
105         }
106
107         void DesktopFile::clear() {
108             d->data.clear();
109         }
110
111         bool DesktopFile::save() const {
112             return save(d->path);
113         }
114
115         bool DesktopFile::save(const std::string& path) const {
116             DesktopFileWriter writer(d->data);
117             writer.save(path);
118
119             return true;
120         }
121
122         bool DesktopFile::save(std::ostream& os) const {
123             DesktopFileWriter writer(d->data);
124             writer.save(os);
125
126             return true;
127         }
128
129         bool DesktopFile::entryExists(const std::string& section, const std::string& key) const {
130             auto it = d->data.find(section);
131             if (it == d->data.end())
132                 return false;
133
134             return (it->second.find(key) != it->second.end());
135         }
136
137         bool DesktopFile::setEntry(const std::string& section, const DesktopFileEntry& entry) {
138             // check if value exists -- used for return value
139             auto rv = entryExists(section, entry.key());
140
141             d->data[section][entry.key()] = entry;
142
143             return rv;
144         }
145
146         bool DesktopFile::setEntry(const std::string& section, DesktopFileEntry&& entry) {
147             // check if value exists -- used for return value
148             auto rv = entryExists(section, entry.key());
149
150             d->data[section][entry.key()] = entry;
151
152             return rv;
153         }
154
155         bool DesktopFile::getEntry(const std::string& section, const std::string& key, DesktopFileEntry& entry) const {
156             if (!entryExists(section, key))
157                 return false;
158
159             entry = d->data[section][key];
160
161             // make sure keys are equal
162             assert(key == entry.key());
163
164             return true;
165         }
166
167         bool DesktopFile::validate() const {
168             // FIXME: call desktop-file-validate
169             return true;
170         }
171
172         bool operator==(const DesktopFile& first, const DesktopFile& second) {
173             return first.d->path == second.d->path && first.d->data == second.d->data;
174         }
175
176         bool operator !=(const DesktopFile& first, const DesktopFile& second) {
177             return !operator==(first, second);
178         }
179     }
180 }
181
182
183