Tag Parser 11.2.0
C++ library for reading and writing MP4 (iTunes), ID3, Vorbis, Opus, FLAC and Matroska tags
utils.cpp
Go to the documentation of this file.
1#include "./helper.h"
2
3#include "../aspectratio.h"
4#include "../backuphelper.h"
5#include "../diagnostics.h"
6#include "../exceptions.h"
7#include "../margin.h"
8#include "../mediafileinfo.h"
9#include "../mediaformat.h"
10#include "../positioninset.h"
11#include "../progressfeedback.h"
12#include "../signature.h"
13#include "../size.h"
14#include "../tagtarget.h"
15
16#include <c++utilities/conversion/stringbuilder.h>
17#include <c++utilities/tests/testutils.h>
18using namespace CppUtilities;
19
20#include <cppunit/TestFixture.h>
21#include <cppunit/extensions/HelperMacros.h>
22
23#include <cstdio>
24#include <regex>
25
26#include <unistd.h>
27
28using namespace std;
29using namespace CppUtilities::Literals;
30using namespace TagParser;
31using namespace CPPUNIT_NS;
32
36class UtilitiesTests : public TestFixture {
37 CPPUNIT_TEST_SUITE(UtilitiesTests);
38 CPPUNIT_TEST(testSize);
39 CPPUNIT_TEST(testTagTarget);
40 CPPUNIT_TEST(testSignature);
41 CPPUNIT_TEST(testMargin);
42 CPPUNIT_TEST(testAspectRatio);
43 CPPUNIT_TEST(testMediaFormat);
44 CPPUNIT_TEST(testPositionInSet);
45 CPPUNIT_TEST(testProgressFeedback);
47 CPPUNIT_TEST(testDiagnostics);
48 CPPUNIT_TEST(testBackupFile);
49 CPPUNIT_TEST_SUITE_END();
50
51public:
52 void setUp() override;
53 void tearDown() override;
54
55 void testSize();
57 void testTagTarget();
58 void testSignature();
59 void testMargin();
60 void testAspectRatio();
61 void testMediaFormat();
62 void testPositionInSet();
65 void testDiagnostics();
66 void testBackupFile();
67};
68
70
72{
73}
74
76{
77}
78
80{
81 static_assert(Size().isNull(), "Size::isNull()");
82 static_assert(!Size(3, 4).isNull(), "Size::isNull()");
83 static_assert(Size(3, 4).resolution() == 12, "Size::resolution");
84
85 Size size(1920, 1080);
86 CPPUNIT_ASSERT_EQUAL("width: 1920, height: 1080"s, size.toString());
87 CPPUNIT_ASSERT_EQUAL("1080p"s, string(size.abbreviation()));
88 size.setWidth(1280);
89 size.setHeight(720);
90 CPPUNIT_ASSERT_EQUAL("720p"s, string(size.abbreviation()));
91}
92
94{
95 TagTarget target;
96 CPPUNIT_ASSERT(target.isEmpty());
97 CPPUNIT_ASSERT_EQUAL_MESSAGE("default level is 50", static_cast<std::uint64_t>(50), target.level());
98 CPPUNIT_ASSERT_EQUAL("level 50"s, target.toString(TagTargetLevel::Unspecified));
99 target = TagTarget(30, { 1, 2, 3 }, { 4 }, { 5, 6 }, { 7, 8, 9 });
100 CPPUNIT_ASSERT(!target.isEmpty());
101 const auto mapping = [](std::uint64_t level) { return level == 30 ? TagTargetLevel::Track : TagTargetLevel::Unspecified; };
102 CPPUNIT_ASSERT_EQUAL(
103 "level 30 'track, song, chapter', track 1, track 2, track 3, chapter 4, edition 5, edition 6, attachment 7, attachment 8, attachment 9"s,
104 target.toString(mapping));
105 target.setLevel(40);
106 CPPUNIT_ASSERT_EQUAL("level 40, track 1, track 2, track 3, chapter 4, edition 5, edition 6, attachment 7, attachment 8, attachment 9"s,
107 target.toString(mapping));
108 target.setLevelName("test");
109 CPPUNIT_ASSERT_EQUAL("level 40 'test', track 1, track 2, track 3, chapter 4, edition 5, edition 6, attachment 7, attachment 8, attachment 9"s,
110 target.toString(mapping));
111 CPPUNIT_ASSERT(target == TagTarget(40, { 1, 2, 3 }, { 4 }, { 5, 6 }, { 7, 8, 9 }));
112 target.clear();
113 CPPUNIT_ASSERT(target.isEmpty());
114}
115
117{
118 const unsigned char xzHead[12] = { 0xfd, 0x37, 0x7a, 0x58, 0x5a, 0x00, 0x00, 0x04, 0xe6, 0xd6, 0xb4, 0x46 };
119
120 // truncated buffer
121 CPPUNIT_ASSERT_EQUAL(ContainerFormat::Unknown, parseSignature(reinterpret_cast<const char *>(xzHead), 3));
122 CPPUNIT_ASSERT_EQUAL(ContainerFormat::Unknown, parseSignature(reinterpret_cast<const char *>(xzHead), 2));
123 CPPUNIT_ASSERT_EQUAL(ContainerFormat::Unknown, parseSignature(reinterpret_cast<const char *>(xzHead), 0));
124
125 const auto containerFormat = parseSignature(reinterpret_cast<const char *>(xzHead), sizeof(xzHead));
126 CPPUNIT_ASSERT_EQUAL(ContainerFormat::Xz, containerFormat);
127 CPPUNIT_ASSERT_EQUAL("xz compressed file"s, string(containerFormatName(containerFormat)));
128 CPPUNIT_ASSERT_EQUAL("xz"s, string(containerFormatAbbreviation(containerFormat)));
129 CPPUNIT_ASSERT_EQUAL(string(), string(containerFormatSubversion(containerFormat)));
130}
131
133{
134 static_assert(Margin().isNull(), "empty margin");
135 static_assert(!Margin(0, 2).isNull(), "non-empty margin");
136
137 CPPUNIT_ASSERT_EQUAL("top: 1; left: 2; bottom: 3; right: 4"s, Margin(1, 2, 3, 4).toString());
138}
139
141{
142 static_assert(!AspectRatio().isValid(), "invalid aspect ratio");
143 static_assert(AspectRatio(16, 9).isValid(), "valid aspect ratio");
144 static_assert(AspectRatio(16, 9).isExtended(), "extended aspect ratio");
145
146 const AspectRatio ratio(4);
147 CPPUNIT_ASSERT_EQUAL(static_cast<std::uint16_t>(16), ratio.numerator);
148 CPPUNIT_ASSERT_EQUAL(static_cast<std::uint16_t>(11), ratio.denominator);
149 const AspectRatio ratio2(77);
150 CPPUNIT_ASSERT_EQUAL(static_cast<std::uint16_t>(0), ratio2.numerator);
151 CPPUNIT_ASSERT_EQUAL(static_cast<std::uint16_t>(0), ratio2.denominator);
152}
153
155{
156 // unspecific format
158 CPPUNIT_ASSERT_EQUAL("Advanced Audio Coding"s, string(aac.name()));
159 CPPUNIT_ASSERT_EQUAL("AAC"s, string(aac.abbreviation()));
160 CPPUNIT_ASSERT_EQUAL("AAC"s, string(aac.shortAbbreviation()));
161
162 // specific format
164 CPPUNIT_ASSERT(aac == GeneralMediaFormat::Aac);
165 CPPUNIT_ASSERT(aac != GeneralMediaFormat::Mpeg1Audio);
166 CPPUNIT_ASSERT_EQUAL("Advanced Audio Coding Low Complexity Profile"s, string(aac.name()));
167 CPPUNIT_ASSERT_EQUAL("MPEG-4 AAC-LC"s, string(aac.abbreviation()));
168 CPPUNIT_ASSERT_EQUAL("HE-AAC"s, string(aac.shortAbbreviation()));
169 CPPUNIT_ASSERT_EQUAL("Spectral Band Replication / HE-AAC"s, string(aac.extensionName()));
170}
171
173{
174 const PositionInSet empty;
175 CPPUNIT_ASSERT(empty.isNull());
176 CPPUNIT_ASSERT_EQUAL(0, empty.position());
177 CPPUNIT_ASSERT_EQUAL(0, empty.total());
178 CPPUNIT_ASSERT_EQUAL(""s, empty.toString());
179
180 const PositionInSet oneOfThree(1, 3);
181 CPPUNIT_ASSERT(!oneOfThree.isNull());
182 CPPUNIT_ASSERT_EQUAL(1, oneOfThree.position());
183 CPPUNIT_ASSERT_EQUAL(3, oneOfThree.total());
184 CPPUNIT_ASSERT_EQUAL("1/3"s, oneOfThree.toString());
185
186 const PositionInSet posOnly(5, 0);
187 CPPUNIT_ASSERT(!posOnly.isNull());
188 CPPUNIT_ASSERT_EQUAL(5, posOnly.position());
189 CPPUNIT_ASSERT_EQUAL(0, posOnly.total());
190 CPPUNIT_ASSERT_EQUAL("5"s, posOnly.toString());
191
192 const PositionInSet totalOnly(0, 5);
193 CPPUNIT_ASSERT(!totalOnly.isNull());
194 CPPUNIT_ASSERT_EQUAL(0, totalOnly.position());
195 CPPUNIT_ASSERT_EQUAL(5, totalOnly.total());
196 CPPUNIT_ASSERT_EQUAL("/5"s, totalOnly.toString());
197}
198
200{
201 unsigned int steps = 0;
202 string step;
203 unsigned int stepPercentage;
204 unsigned int overallPercentage = 0;
205
206 ProgressFeedback progressFeedback(
207 [&](const ProgressFeedback &progress) {
208 ++steps;
209 step = progress.step();
210 stepPercentage = progress.stepPercentage();
211 overallPercentage = progress.overallPercentage();
212 },
213 [&](const ProgressFeedback &progress) {
214 stepPercentage = progress.stepPercentage();
215 overallPercentage = progress.overallPercentage();
216 });
217 CPPUNIT_ASSERT_EQUAL(0u, steps);
218 progressFeedback.updateOverallPercentage(25);
219 CPPUNIT_ASSERT_EQUAL(0u, steps);
220 CPPUNIT_ASSERT_EQUAL(25u, overallPercentage);
221 progressFeedback.updateStep("foo", 45);
222 CPPUNIT_ASSERT_EQUAL(1u, steps);
223 CPPUNIT_ASSERT_EQUAL("foo"s, step);
224 CPPUNIT_ASSERT_EQUAL(45u, stepPercentage);
225 CPPUNIT_ASSERT_EQUAL(25u, overallPercentage);
226 progressFeedback.updateStepPercentage(60);
227 CPPUNIT_ASSERT_EQUAL(1u, steps);
228 CPPUNIT_ASSERT_EQUAL("foo"s, step);
229 CPPUNIT_ASSERT_EQUAL(60u, stepPercentage);
230 CPPUNIT_ASSERT_EQUAL(25u, overallPercentage);
231 progressFeedback.updateStepPercentageFromFraction(0.75);
232 CPPUNIT_ASSERT_EQUAL(1u, steps);
233 CPPUNIT_ASSERT_EQUAL("foo"s, step);
234 CPPUNIT_ASSERT_EQUAL(75u, stepPercentage);
235 CPPUNIT_ASSERT_EQUAL(25u, overallPercentage);
236}
237
239{
240 unsigned int steps = 0;
241 string step;
242 unsigned int stepPercentage;
243 unsigned int overallPercentage = 0;
244
245 AbortableProgressFeedback progressFeedback(
246 [&](const AbortableProgressFeedback &progress) {
247 ++steps;
248 step = progress.step();
249 stepPercentage = progress.stepPercentage();
250 overallPercentage = progress.overallPercentage();
251 },
252 [&](const AbortableProgressFeedback &progress) {
253 stepPercentage = progress.stepPercentage();
254 overallPercentage = progress.overallPercentage();
255 });
256 CPPUNIT_ASSERT(!progressFeedback.isAborted());
257 CPPUNIT_ASSERT_NO_THROW_MESSAGE("stop does nothing if not aborted", progressFeedback.stopIfAborted());
258 CPPUNIT_ASSERT_EQUAL(0u, steps);
259 progressFeedback.updateOverallPercentage(25);
260 CPPUNIT_ASSERT_EQUAL(0u, steps);
261 CPPUNIT_ASSERT_EQUAL(25u, overallPercentage);
262 progressFeedback.updateStep("foo", 45);
263 CPPUNIT_ASSERT_EQUAL(1u, steps);
264 CPPUNIT_ASSERT_EQUAL("foo"s, step);
265 CPPUNIT_ASSERT_EQUAL(45u, stepPercentage);
266 CPPUNIT_ASSERT_EQUAL(25u, overallPercentage);
267 CPPUNIT_ASSERT_NO_THROW_MESSAGE("next step continues if not aborted", progressFeedback.nextStepOrStop("bar", 33));
268 CPPUNIT_ASSERT_EQUAL(2u, steps);
269 CPPUNIT_ASSERT_EQUAL("bar"s, step);
270 CPPUNIT_ASSERT_EQUAL(33u, stepPercentage);
271 CPPUNIT_ASSERT_EQUAL(25u, overallPercentage);
272 progressFeedback.tryToAbort();
273 CPPUNIT_ASSERT(progressFeedback.isAborted());
274 CPPUNIT_ASSERT_THROW(progressFeedback.nextStepOrStop("not going to happen", 33), OperationAbortedException);
275 CPPUNIT_ASSERT_EQUAL(2u, steps);
276 CPPUNIT_ASSERT_EQUAL("bar"s, step);
277 CPPUNIT_ASSERT_EQUAL(33u, stepPercentage);
278 CPPUNIT_ASSERT_EQUAL(25u, overallPercentage);
279}
280
282{
283 Diagnostics diag;
284 CPPUNIT_ASSERT_EQUAL(DiagLevel::None, diag.level());
285 diag.emplace_back(DiagLevel::Warning, "warning msg", "context");
286 CPPUNIT_ASSERT_EQUAL(DiagLevel::Warning, diag.level());
287 CPPUNIT_ASSERT(!diag.has(DiagLevel::Critical));
288 diag.emplace_back(DiagLevel::Critical, "critical msg", "context");
289 CPPUNIT_ASSERT_EQUAL(DiagLevel::Critical, diag.level());
290 CPPUNIT_ASSERT(diag.has(DiagLevel::Critical));
291}
292
294{
295 using namespace BackupHelper;
296
297 // setup testfile
298 MediaFileInfo file(workingCopyPath("unsupported.bin"));
299 file.setBackupDirectory(string()); // ensure backup directory is empty, so backups will be created in the same directory as the original file
300 const auto workingDir(file.containingDirectory());
301 file.open();
302
303 // create backup file
304 string backupPath1, backupPath2;
305 NativeFileStream backupStream1, backupStream2;
306 createBackupFile(string(), file.path(), backupPath1, file.stream(), backupStream1);
307 CPPUNIT_ASSERT_EQUAL(workingDir + "/unsupported.bin.bak", backupPath1);
308
309 // recreate original file (like the 'make' methods would do to apply changes)
310 file.stream().open(file.path(), ios_base::out);
311 file.stream() << "test1" << endl;
312
313 // create a 2nd backup which should not override the first one
314 createBackupFile(string(), file.path(), backupPath2, file.stream(), backupStream2);
315 CPPUNIT_ASSERT_EQUAL(workingDir + "/unsupported.bin.1.bak", backupPath2);
316
317 // get rid of 2nd backup, recreate original file
318 backupStream2.close();
319 remove(backupPath2.data());
320 file.stream().open(file.path(), ios_base::out);
321 file.stream() << "test2" << endl;
322
323 // create backup under another location
324 try {
325 createBackupFile("bak", file.path(), backupPath2, file.stream(), backupStream2);
326 CPPUNIT_FAIL("renaming failed because backup dir does not exist");
327 } catch (const std::ios_base::failure &failure) {
328 TESTUTILS_ASSERT_LIKE("renaming error", "Unable to create backup file .* of .* before rewriting it: .*"s, string(failure.what()));
329 }
330 backupStream2.clear();
331 workingCopyPath("bak/unsupported.bin", WorkingCopyMode::NoCopy);
332 createBackupFile("bak", file.path(), backupPath2, file.stream(), backupStream2);
333 CPPUNIT_ASSERT_EQUAL(workingDir + "/bak/unsupported.bin", backupPath2);
334
335 // get rid of 2nd backup (again)
336 backupStream2.close();
337 CPPUNIT_ASSERT_EQUAL_MESSAGE("remove " + backupPath2, 0, remove(backupPath2.data()));
338 const auto backupDir(workingDir + "/bak");
339 CPPUNIT_ASSERT_EQUAL_MESSAGE("remove " + backupDir, 0, rmdir(backupDir.data()));
340
341 // should be able to use backup stream, eg. seek to the end
342 backupStream1.seekg(0, ios_base::end);
343 CPPUNIT_ASSERT_EQUAL(41_st, static_cast<size_t>(backupStream1.tellg()));
344
345 // restore backup
346 restoreOriginalFileFromBackupFile(file.path(), backupPath1, file.stream(), backupStream1);
347
348 // check restored backup
349 file.open(true);
350 file.stream().seekg(0x1D);
351 CPPUNIT_ASSERT_EQUAL(0x34_st, static_cast<size_t>(file.stream().get()));
352 file.close();
353
354 // restore after user aborted
355 createBackupFile(string(), file.path(), backupPath1, file.stream(), backupStream1);
356 try {
358 } catch (...) {
359 Diagnostics diag;
360 CPPUNIT_ASSERT_THROW(
361 handleFailureAfterFileModified(file, backupPath1, file.stream(), backupStream1, diag, "test"), OperationAbortedException);
362 CPPUNIT_ASSERT(diag.level() < DiagLevel::Critical);
363 CPPUNIT_ASSERT(!diag.empty());
364 CPPUNIT_ASSERT_EQUAL("Rewriting the file to apply changed tag information has been aborted."s, diag.front().message());
365 CPPUNIT_ASSERT_EQUAL("The original file has been restored."s, diag.back().message());
366 }
367
368 // restore after error
369 createBackupFile(string(), file.path(), backupPath1, file.stream(), backupStream1);
370 try {
371 throw Failure();
372 } catch (...) {
373 Diagnostics diag;
374 CPPUNIT_ASSERT_THROW(handleFailureAfterFileModified(file, backupPath1, file.stream(), backupStream1, diag, "test"), Failure);
375 CPPUNIT_ASSERT(diag.level() >= DiagLevel::Critical);
376 CPPUNIT_ASSERT_EQUAL("Rewriting the file to apply changed tag information failed."s, diag.front().message());
377 CPPUNIT_ASSERT_EQUAL("The original file has been restored."s, diag.back().message());
378 }
379
380 // restore after io failure
381 createBackupFile(string(), file.path(), backupPath1, file.stream(), backupStream1);
382 try {
383 throw std::ios_base::failure("simulated IO failure");
384 } catch (const std::ios_base::failure &) {
385 Diagnostics diag;
386 CPPUNIT_ASSERT_THROW_MESSAGE("IO failure re-thrown",
387 handleFailureAfterFileModified(file, backupPath1, file.stream(), backupStream1, diag, "test"), std::ios_base::failure);
388 CPPUNIT_ASSERT(diag.level() >= DiagLevel::Critical);
389 CPPUNIT_ASSERT_EQUAL("An IO error occurred when rewriting the file to apply changed tag information."s, diag.front().message());
390 CPPUNIT_ASSERT_EQUAL("The original file has been restored."s, diag.back().message());
391 }
392
393 CPPUNIT_ASSERT_EQUAL(0, remove(file.path().data()));
394}
The AbortableProgressFeedback class provides feedback about an ongoing operation via callbacks.
const std::string & path() const
Returns the path of the current file.
static std::string containingDirectory(std::string_view path)
Returns the path of the directory containing the given file.
CppUtilities::NativeFileStream & stream()
Returns the std::fstream for the current instance.
Definition: basicfileinfo.h:85
void open(bool readOnly=false)
Opens a std::fstream for the current file.
void close()
A possibly opened std::fstream will be closed.
std::uint8_t stepPercentage() const
Returns the percentage of the current step (initially 0, supposed to be a value from 0 to 100).
const std::string & step() const
Returns the name of the current step (initially empty).
std::uint8_t overallPercentage() const
Returns the overall percentage (initially 0, supposed to be a value from 0 to 100).
The Diagnostics class is a container for DiagMessage.
Definition: diagnostics.h:156
bool has(DiagLevel level) const
Returns whether there's at least one DiagMessage which is at least as worse as level.
Definition: diagnostics.cpp:42
DiagLevel level() const
Returns the worst diag level present in the container.
Definition: diagnostics.cpp:55
The class inherits from std::exception and serves as base class for exceptions thrown by the elements...
Definition: exceptions.h:11
The Margin class defines the four margins of a rectangle.
Definition: margin.h:16
constexpr bool isNull() const
Returns true if all margins are is 0; otherwise returns false;.
Definition: margin.h:115
The MediaFileInfo class allows to read and write tag information providing a container/tag format ind...
Definition: mediafileinfo.h:76
void setBackupDirectory(std::string_view backupDirectory)
Sets the directory used to store backup files.
The MediaFormat class specifies the format of media data.
Definition: mediaformat.h:246
std::string_view abbreviation() const
Returns the abbreviation of the media format as C-style string.
std::string_view shortAbbreviation() const
Returns a short abbreviation of the media format as C-style string.
std::string_view name() const
Returns the name of the media format as C-style string.
Definition: mediaformat.cpp:17
std::string_view extensionName() const
Returns the abbreviation of the media format as C-style string.
The exception that is thrown when an operation has been stopped and thus not successfully completed b...
Definition: exceptions.h:46
The PositionInSet class describes the position of an element in a set which consists of a certain num...
Definition: positioninset.h:21
constexpr std::int32_t position() const
Returns the element position of the current instance.
Definition: positioninset.h:78
constexpr std::int32_t total() const
Returns the total element count of the current instance.
Definition: positioninset.h:86
StringType toString() const
Returns the string representation of the current PositionInSet.
constexpr bool isNull() const
Returns an indication whether both the element position and total element count is 0.
Definition: positioninset.h:94
The ProgressFeedback class provides feedback about an ongoing operation via callbacks.
The Size class defines the size of a two-dimensional object using integer point precision.
Definition: size.h:17
void setWidth(std::uint32_t value)
Sets the width.
Definition: size.h:76
bool constexpr isNull() const
Returns an indication whether both the width and height is 0.
Definition: size.h:100
std::string toString() const
Returns the string representation of the current size.
Definition: size.h:125
constexpr std::uint32_t resolution() const
Returns the resolution of the current instance (product of with and height).
Definition: size.h:92
void setHeight(std::uint32_t value)
Sets the height.
Definition: size.h:84
std::string_view abbreviation() const
Returns an abbreviation for the current instance, eg.
Definition: size.cpp:17
The TagTarget class specifies the target of a tag.
Definition: tagtarget.h:20
std::uint64_t level() const
Returns the level.
Definition: tagtarget.h:73
std::string toString(const std::function< TagTargetLevel(std::uint64_t)> &tagTargetMapping) const
Returns the string representation of the current instance.
Definition: tagtarget.h:217
bool isEmpty() const
Returns an indication whether the target is empty.
Definition: tagtarget.h:169
void clear()
Clears the TagTarget.
Definition: tagtarget.h:177
void setLevel(std::uint64_t level)
Sets the level.
Definition: tagtarget.h:81
void setLevelName(const std::string &levelName)
Sets the level name.
Definition: tagtarget.h:97
The UtilitiesTests class tests various utility classes and functions of the tagparser library.
Definition: utils.cpp:36
void testPositionInSet()
Definition: utils.cpp:172
void testSize()
Definition: utils.cpp:79
void testTagTarget()
Definition: utils.cpp:93
void testProgressFeedback()
Definition: utils.cpp:199
void tearDown() override
Definition: utils.cpp:75
void testStatusProvider()
void testAbortableProgressFeedback()
Definition: utils.cpp:238
void testAspectRatio()
Definition: utils.cpp:140
void testMargin()
Definition: utils.cpp:132
void testSignature()
Definition: utils.cpp:116
void testDiagnostics()
Definition: utils.cpp:281
void setUp() override
Definition: utils.cpp:71
void testBackupFile()
Definition: utils.cpp:293
void testMediaFormat()
Definition: utils.cpp:154
TAG_PARSER_EXPORT void createBackupFile(const std::string &backupDir, const std::string &originalPath, std::string &backupPath, CppUtilities::NativeFileStream &originalStream, CppUtilities::NativeFileStream &backupStream)
TAG_PARSER_EXPORT void restoreOriginalFileFromBackupFile(const std::string &originalPath, const std::string &backupPath, CppUtilities::NativeFileStream &originalStream, CppUtilities::NativeFileStream &backupStream)
TAG_PARSER_EXPORT void handleFailureAfterFileModified(MediaFileInfo &fileInfo, const std::string &backupPath, CppUtilities::NativeFileStream &outputStream, CppUtilities::NativeFileStream &backupStream, Diagnostics &diag, const std::string &context="making file")
Contains all classes and functions of the TagInfo library.
Definition: aaccodebook.h:10
TAG_PARSER_EXPORT std::string_view containerFormatSubversion(ContainerFormat containerFormat)
Returns the subversion of the container format as C-style string.
Definition: signature.cpp:478
TAG_PARSER_EXPORT std::string_view containerFormatAbbreviation(ContainerFormat containerFormat, MediaType mediaType=MediaType::Unknown, unsigned int version=0)
Returns the abbreviation of the container format as C-style string considering the specified media ty...
Definition: signature.cpp:251
TAG_PARSER_EXPORT std::string_view containerFormatName(ContainerFormat containerFormat)
Returns the name of the specified container format as C-style string.
Definition: signature.cpp:373
TAG_PARSER_EXPORT ContainerFormat parseSignature(const char *buffer, std::size_t bufferSize)
Definition: signature.h:80
The AspectRatio struct defines an aspect ratio.
Definition: aspectratio.h:13
std::uint16_t numerator
Definition: aspectratio.h:22
std::uint16_t denominator
Definition: aspectratio.h:23
constexpr bool isExtended() const
Returns whether numerator and denominator must be read from extended SAR header.
Definition: aspectratio.h:58
constexpr bool isValid() const
Returns an indication whether the aspect ratio is present and valid.
Definition: aspectratio.h:50
CPPUNIT_TEST_SUITE_REGISTRATION(UtilitiesTests)