Browse code

Port: Use std::filesystem::path for reading/writing files. - before override

Clarissa Walker authored on 2024/08/22 20:57:20
Showing 1 changed files
... ...
@@ -17,9 +17,6 @@
17 17
 #include "XSFCommon.h"
18 18
 #include "XSFFile.h"
19 19
 #include "convert.h"
20
-#if defined(_WIN32) && !defined(_MSC_VER)
21
-# include "fstream_wfopen.h"
22
-#endif
23 20
 #include "zlib.h"
24 21
 
25 22
 static inline void Set32BitsLE(std::uint32_t input, std::uint8_t *output)
... ...
@@ -61,65 +58,33 @@ static inline std::string TrimWhitespace(const std::string &orig)
61 58
 	return LeftTrimWhitespace(RightTrimWhitespace(orig));
62 59
 }
63 60
 
64
-XSFFile::XSFFile() : xSFType(0), hasFile(false), rawData(), reservedSection(), programSection(), tags(), fileName("")
61
+XSFFile::XSFFile() : xSFType(0), hasFile(false), rawData(), reservedSection(), programSection(), tags(), filePath()
65 62
 {
66 63
 }
67 64
 
68
-XSFFile::XSFFile(const std::string &filename) : xSFType(0), hasFile(false), rawData(), reservedSection(), programSection(), tags(), fileName(filename)
65
+XSFFile::XSFFile(const std::filesystem::path &path) : xSFType(0), hasFile(false), rawData(), reservedSection(), programSection(), tags(), filePath(path)
69 66
 {
70
-	this->ReadXSF(filename, 0, 0, true);
67
+	this->ReadXSF(path, 0, 0, true);
71 68
 }
72 69
 
73
-XSFFile::XSFFile(const std::string &filename, std::uint32_t programSizeOffset, std::uint32_t programHeaderSize) : xSFType(0), hasFile(false), rawData(), reservedSection(), programSection(), tags(), fileName(filename)
70
+XSFFile::XSFFile(const std::filesystem::path &path, std::uint32_t programSizeOffset, std::uint32_t programHeaderSize) : xSFType(0), hasFile(false), rawData(), reservedSection(), programSection(), tags(), filePath(path)
74 71
 {
75
-	this->ReadXSF(filename, programSizeOffset, programHeaderSize);
72
+	this->ReadXSF(path, programSizeOffset, programHeaderSize);
76 73
 }
77 74
 
78
-#ifdef _WIN32
79
-XSFFile::XSFFile(const std::wstring &filename) : xSFType(0), hasFile(false), rawData(), reservedSection(), programSection(), tags(), fileName(ConvertFuncs::WStringToString(filename))
75
+void XSFFile::ReadXSF(const std::filesystem::path &path, std::uint32_t programSizeOffset, std::uint32_t programHeaderSize, bool readTagsOnly)
80 76
 {
81
-	this->ReadXSF(filename, 0, 0, true);
82
-}
83
-
84
-XSFFile::XSFFile(const std::wstring &filename, std::uint32_t programSizeOffset, std::uint32_t programHeaderSize) : xSFType(0), hasFile(false), rawData(), reservedSection(), programSection(), tags(), fileName(ConvertFuncs::WStringToString(filename))
85
-{
86
-	this->ReadXSF(filename, programSizeOffset, programHeaderSize);
87
-}
88
-#endif
89
-
90
-void XSFFile::ReadXSF(const std::string &filename, std::uint32_t programSizeOffset, std::uint32_t programHeaderSize, bool readTagsOnly)
91
-{
92
-	if (!std::filesystem::is_regular_file(filename))
93
-		throw std::logic_error("File " + filename + " does not exist.");
94
-
95
-	std::ifstream xSF;
96
-	xSF.exceptions(std::ifstream::failbit | std::ifstream::badbit);
97
-	xSF.open(filename.c_str(), std::ifstream::in | std::ifstream::binary);
98
-
99
-	this->ReadXSF(xSF, programSizeOffset, programHeaderSize, readTagsOnly);
100
-
101
-	xSF.close();
102
-}
103
-
104
-#ifdef _WIN32
105
-void XSFFile::ReadXSF(const std::wstring &filename, std::uint32_t programSizeOffset, std::uint32_t programHeaderSize, bool readTagsOnly)
106
-{
107
-	if (!std::filesystem::is_regular_file(filename))
108
-		throw std::logic_error("File " + ConvertFuncs::WStringToString(filename) + " does not exist.");
77
+	if (!std::filesystem::is_regular_file(path))
78
+		throw std::logic_error("File " + path.string() + " does not exist.");
109 79
 
110
-#if defined(_WIN32) && !defined(_MSC_VER)
111
-	ifstream_wfopen xSF;
112
-#else
113 80
 	std::ifstream xSF;
114
-#endif
115 81
 	xSF.exceptions(std::ifstream::failbit | std::ifstream::badbit);
116
-	xSF.open(filename.c_str(), std::ifstream::in | std::ifstream::binary);
82
+	xSF.open(path, std::ifstream::in | std::ifstream::binary);
117 83
 
118 84
 	this->ReadXSF(xSF, programSizeOffset, programHeaderSize, readTagsOnly);
119 85
 
120 86
 	xSF.close();
121 87
 }
122
-#endif
123 88
 
124 89
 void XSFFile::ReadXSF(std::ifstream &xSF, std::uint32_t programSizeOffset, std::uint32_t programHeaderSize, bool readTagsOnly)
125 90
 {
... ...
@@ -462,29 +427,21 @@ std::string XSFFile::GetFormattedTitle(const std::string &format) const
462 427
 	return formattedTitle;
463 428
 }
464 429
 
465
-std::string XSFFile::GetFilename() const
430
+std::filesystem::path XSFFile::GetFilepath() const
466 431
 {
467
-	return this->fileName;
432
+	return this->filePath;
468 433
 }
469 434
 
470
-std::string XSFFile::GetFilenameWithoutPath() const
435
+std::filesystem::path XSFFile::GetFilenameWithoutPath() const
471 436
 {
472
-	return std::filesystem::path(this->fileName).filename().string();
437
+	return this->filePath.filename();
473 438
 }
474 439
 
475 440
 void XSFFile::SaveFile() const
476 441
 {
477
-#if defined(_WIN32) && !defined(_MSC_VER)
478
-	ofstream_wfopen xSF;
479
-#else
480 442
 	std::ofstream xSF;
481
-#endif
482 443
 	xSF.exceptions(std::ofstream::failbit);
483
-#ifdef _WIN32
484
-	xSF.open(ConvertFuncs::StringToWString(this->fileName).c_str(), std::ofstream::out | std::ofstream::binary);
485
-#else
486
-	xSF.open(this->fileName.c_str(), std::ofstream::out | std::ofstream::binary);
487
-#endif
444
+	xSF.open(this->filePath, std::ofstream::out | std::ofstream::binary);
488 445
 
489 446
 	xSF.write(reinterpret_cast<const char *>(&this->rawData[0]), this->rawData.size());
490 447
 
Browse code

Various changes:

* Use enum class instead of enum (except for the enums for the resource IDs, not really necessary there).
* For NCSF specifically, included a function to convert an enum class to its underlying integral type (as this is needed for use with the std::bitset class).
* Cleanup headers so all the ones needed in a file are explicitly included even if they may possibly be included in another header.
* Used forward declarations in a few spots.
* Explicitly namespaced all (u)int*_t uses (this might seem like overkill, but it helps me see when the standard types are being used with a simple search for std::).
* Made sure it all builds with MinGW-w64 as well (both gcc and clang).
* Removed some std::move from DialogBuilder.cpp based on clang's warnings for that.
* Replaced use of std::copy_n on strings in DialogBuilder.cpp with my CopyToString functions that use wcscpy.
* Replaced CHAR_MIN/CHAR_MAX in eqstr.h and ltstr.h with std::numeric_limits<char>::min/max().

Naram Qashat authored on 2021/03/21 03:16:45
Showing 1 changed files
... ...
@@ -7,17 +7,22 @@
7 7
 
8 8
 #include <algorithm>
9 9
 #include <filesystem>
10
-#include <functional>
10
+#include <fstream>
11 11
 #include <stdexcept>
12
+#include <string>
13
+#include <vector>
14
+#include <cmath>
15
+#include <cstddef>
16
+#include <cstdint>
17
+#include "XSFCommon.h"
18
+#include "XSFFile.h"
19
+#include "convert.h"
12 20
 #if defined(_WIN32) && !defined(_MSC_VER)
13 21
 # include "fstream_wfopen.h"
14 22
 #endif
15 23
 #include "zlib.h"
16
-#include "XSFFile.h"
17
-#include "XSFCommon.h"
18
-#include "convert.h"
19 24
 
20
-static inline void Set32BitsLE(uint32_t input, uint8_t *output)
25
+static inline void Set32BitsLE(std::uint32_t input, std::uint8_t *output)
21 26
 {
22 27
 	output[0] = input & 0xFF;
23 28
 	output[1] = (input >> 8) & 0xFF;
... ...
@@ -65,7 +70,7 @@ XSFFile::XSFFile(const std::string &filename) : xSFType(0), hasFile(false), rawD
65 70
 	this->ReadXSF(filename, 0, 0, true);
66 71
 }
67 72
 
68
-XSFFile::XSFFile(const std::string &filename, uint32_t programSizeOffset, uint32_t programHeaderSize) : xSFType(0), hasFile(false), rawData(), reservedSection(), programSection(), tags(), fileName(filename)
73
+XSFFile::XSFFile(const std::string &filename, std::uint32_t programSizeOffset, std::uint32_t programHeaderSize) : xSFType(0), hasFile(false), rawData(), reservedSection(), programSection(), tags(), fileName(filename)
69 74
 {
70 75
 	this->ReadXSF(filename, programSizeOffset, programHeaderSize);
71 76
 }
... ...
@@ -76,13 +81,13 @@ XSFFile::XSFFile(const std::wstring &filename) : xSFType(0), hasFile(false), raw
76 81
 	this->ReadXSF(filename, 0, 0, true);
77 82
 }
78 83
 
79
-XSFFile::XSFFile(const std::wstring &filename, uint32_t programSizeOffset, uint32_t programHeaderSize) : xSFType(0), hasFile(false), rawData(), reservedSection(), programSection(), tags(), fileName(ConvertFuncs::WStringToString(filename))
84
+XSFFile::XSFFile(const std::wstring &filename, std::uint32_t programSizeOffset, std::uint32_t programHeaderSize) : xSFType(0), hasFile(false), rawData(), reservedSection(), programSection(), tags(), fileName(ConvertFuncs::WStringToString(filename))
80 85
 {
81 86
 	this->ReadXSF(filename, programSizeOffset, programHeaderSize);
82 87
 }
83 88
 #endif
84 89
 
85
-void XSFFile::ReadXSF(const std::string &filename, uint32_t programSizeOffset, uint32_t programHeaderSize, bool readTagsOnly)
90
+void XSFFile::ReadXSF(const std::string &filename, std::uint32_t programSizeOffset, std::uint32_t programHeaderSize, bool readTagsOnly)
86 91
 {
87 92
 	if (!std::filesystem::is_regular_file(filename))
88 93
 		throw std::logic_error("File " + filename + " does not exist.");
... ...
@@ -97,7 +102,7 @@ void XSFFile::ReadXSF(const std::string &filename, uint32_t programSizeOffset, u
97 102
 }
98 103
 
99 104
 #ifdef _WIN32
100
-void XSFFile::ReadXSF(const std::wstring &filename, uint32_t programSizeOffset, uint32_t programHeaderSize, bool readTagsOnly)
105
+void XSFFile::ReadXSF(const std::wstring &filename, std::uint32_t programSizeOffset, std::uint32_t programHeaderSize, bool readTagsOnly)
101 106
 {
102 107
 	if (!std::filesystem::is_regular_file(filename))
103 108
 		throw std::logic_error("File " + ConvertFuncs::WStringToString(filename) + " does not exist.");
... ...
@@ -116,7 +121,7 @@ void XSFFile::ReadXSF(const std::wstring &filename, uint32_t programSizeOffset,
116 121
 }
117 122
 #endif
118 123
 
119
-void XSFFile::ReadXSF(std::ifstream &xSF, uint32_t programSizeOffset, uint32_t programHeaderSize, bool readTagsOnly)
124
+void XSFFile::ReadXSF(std::ifstream &xSF, std::uint32_t programSizeOffset, std::uint32_t programHeaderSize, bool readTagsOnly)
120 125
 {
121 126
 	xSF.seekg(0, std::ifstream::end);
122 127
 	auto filesize = xSF.tellg();
... ...
@@ -139,7 +144,7 @@ void XSFFile::ReadXSF(std::ifstream &xSF, uint32_t programSizeOffset, uint32_t p
139 144
 	if (filesize < 16)
140 145
 		throw std::runtime_error("File is too small.");
141 146
 
142
-	uint32_t reservedSize = Get32BitsLE(xSF), programCompressedSize = Get32BitsLE(xSF);
147
+	std::uint32_t reservedSize = Get32BitsLE(xSF), programCompressedSize = Get32BitsLE(xSF);
143 148
 	this->rawData.resize(reservedSize + programCompressedSize + 16);
144 149
 	Set32BitsLE(reservedSize, &this->rawData[4]);
145 150
 	Set32BitsLE(programCompressedSize, &this->rawData[8]);
... ...
@@ -169,11 +174,11 @@ void XSFFile::ReadXSF(std::ifstream &xSF, uint32_t programSizeOffset, uint32_t p
169 174
 			xSF.read(reinterpret_cast<char *>(&this->rawData[reservedSize + 16]), programCompressedSize);
170 175
 		else
171 176
 		{
172
-			auto programSectionCompressed = std::vector<uint8_t>(programCompressedSize);
177
+			auto programSectionCompressed = std::vector<std::uint8_t>(programCompressedSize);
173 178
 			xSF.read(reinterpret_cast<char *>(&programSectionCompressed[0]), programCompressedSize);
174 179
 			std::copy_n(&programSectionCompressed[0], programCompressedSize, &this->rawData[reservedSize + 16]);
175 180
 
176
-			auto programSectionUncompressed = std::vector<uint8_t>(programHeaderSize);
181
+			auto programSectionUncompressed = std::vector<std::uint8_t>(programHeaderSize);
177 182
 			unsigned long programUncompressedSize = programHeaderSize;
178 183
 			uncompress(&programSectionUncompressed[0], &programUncompressedSize, &programSectionCompressed[0], programCompressedSize);
179 184
 			programUncompressedSize = Get32BitsLE(&programSectionUncompressed[programSizeOffset]) + programHeaderSize;
... ...
@@ -231,7 +236,7 @@ void XSFFile::ReadXSF(std::ifstream &xSF, uint32_t programSizeOffset, uint32_t p
231 236
 	this->hasFile = true;
232 237
 }
233 238
 
234
-bool XSFFile::IsValidType(uint8_t type) const
239
+bool XSFFile::IsValidType(std::uint8_t type) const
235 240
 {
236 241
 	return this->xSFType == type;
237 242
 }
... ...
@@ -250,22 +255,22 @@ bool XSFFile::HasFile() const
250 255
 	return this->hasFile;
251 256
 }
252 257
 
253
-std::vector<uint8_t> &XSFFile::GetReservedSection()
258
+std::vector<std::uint8_t> &XSFFile::GetReservedSection()
254 259
 {
255 260
 	return this->reservedSection;
256 261
 }
257 262
 
258
-std::vector<uint8_t> XSFFile::GetReservedSection() const
263
+std::vector<std::uint8_t> XSFFile::GetReservedSection() const
259 264
 {
260 265
 	return this->reservedSection;
261 266
 }
262 267
 
263
-std::vector<uint8_t> &XSFFile::GetProgramSection()
268
+std::vector<std::uint8_t> &XSFFile::GetProgramSection()
264 269
 {
265 270
 	return this->programSection;
266 271
 }
267 272
 
268
-std::vector<uint8_t> XSFFile::GetProgramSection() const
273
+std::vector<std::uint8_t> XSFFile::GetProgramSection() const
269 274
 {
270 275
 	return this->programSection;
271 276
 }
... ...
@@ -322,19 +327,19 @@ unsigned long XSFFile::GetFadeMS(unsigned long defaultFade) const
322 327
 
323 328
 double XSFFile::GetVolume(VolumeType preferredVolumeType, PeakType preferredPeakType) const
324 329
 {
325
-	if (preferredVolumeType == VOLUMETYPE_NONE)
330
+	if (preferredVolumeType == VolumeType::None)
326 331
 		return 1.0;
327 332
 	std::string replaygain_album_gain = this->GetTagValue("replaygain_album_gain"), replaygain_album_peak = this->GetTagValue("replaygain_album_peak");
328 333
 	std::string replaygain_track_gain = this->GetTagValue("replaygain_track_gain"), replaygain_track_peak = this->GetTagValue("replaygain_track_peak");
329 334
 	std::string volume = this->GetTagValue("volume");
330 335
 	double gain = 0.0;
331 336
 	bool hadReplayGain = false;
332
-	if (preferredVolumeType == VOLUMETYPE_REPLAYGAIN_ALBUM && !replaygain_album_gain.empty())
337
+	if (preferredVolumeType == VolumeType::ReplayGainAlbum && !replaygain_album_gain.empty())
333 338
 	{
334 339
 		gain = convertTo<double>(replaygain_album_gain);
335 340
 		hadReplayGain = true;
336 341
 	}
337
-	if (!hadReplayGain && preferredVolumeType != VOLUMETYPE_VOLUME && !replaygain_track_gain.empty())
342
+	if (!hadReplayGain && preferredVolumeType != VolumeType::Volume && !replaygain_track_gain.empty())
338 343
 	{
339 344
 		gain = convertTo<double>(replaygain_track_gain);
340 345
 		hadReplayGain = true;
... ...
@@ -342,9 +347,9 @@ double XSFFile::GetVolume(VolumeType preferredVolumeType, PeakType preferredPeak
342 347
 	if (hadReplayGain)
343 348
 	{
344 349
 		double vol = std::pow(10.0, gain / 20.0), peak = 1.0;
345
-		if (preferredPeakType == PEAKTYPE_REPLAYGAIN_ALBUM && !replaygain_album_peak.empty())
350
+		if (preferredPeakType == PeakType::ReplayGainAlbum && !replaygain_album_peak.empty())
346 351
 			peak = convertTo<double>(replaygain_album_peak);
347
-		else if (preferredPeakType != PEAKTYPE_NONE && !replaygain_track_peak.empty())
352
+		else if (preferredPeakType != PeakType::None && !replaygain_track_peak.empty())
348 353
 			peak = convertTo<double>(replaygain_track_peak);
349 354
 		return !fEqual(peak, 1.0) ? std::min(vol, 1.0 / peak) : vol;
350 355
 	}
... ...
@@ -354,12 +359,12 @@ double XSFFile::GetVolume(VolumeType preferredVolumeType, PeakType preferredPeak
354 359
 std::string XSFFile::FormattedTitleOptionalBlock(const std::string &block, bool &hadReplacement, unsigned level) const
355 360
 {
356 361
 	std::string formattedBlock;
357
-	for (size_t x = 0, len = block.length(); x < len; ++x)
362
+	for (std::size_t x = 0, len = block.length(); x < len; ++x)
358 363
 	{
359 364
 		char c = block[x];
360 365
 		if (c == '%')
361 366
 		{
362
-			size_t origX = x;
367
+			std::size_t origX = x;
363 368
 			for (++x; x < len; ++x)
364 369
 				if (block[x] == '%')
365 370
 					break;
... ...
@@ -377,7 +382,7 @@ std::string XSFFile::FormattedTitleOptionalBlock(const std::string &block, bool
377 382
 		}
378 383
 		if (c == '[' && level + 1 < 10)
379 384
 		{
380
-			size_t origX = x;
385
+			std::size_t origX = x;
381 386
 			unsigned nests = 0;
382 387
 			for (++x; x < len; ++x)
383 388
 			{
... ...
@@ -408,12 +413,12 @@ std::string XSFFile::FormattedTitleOptionalBlock(const std::string &block, bool
408 413
 std::string XSFFile::GetFormattedTitle(const std::string &format) const
409 414
 {
410 415
 	std::string formattedTitle;
411
-	for (size_t x = 0, len = format.length(); x < len; ++x)
416
+	for (std::size_t x = 0, len = format.length(); x < len; ++x)
412 417
 	{
413 418
 		char c = format[x];
414 419
 		if (c == '%')
415 420
 		{
416
-			size_t origX = x;
421
+			std::size_t origX = x;
417 422
 			for (++x; x < len; ++x)
418 423
 				if (format[x] == '%')
419 424
 					break;
... ...
@@ -429,7 +434,7 @@ std::string XSFFile::GetFormattedTitle(const std::string &format) const
429 434
 		}
430 435
 		else if (c == '[')
431 436
 		{
432
-			size_t origX = x;
437
+			std::size_t origX = x;
433 438
 			unsigned nests = 0;
434 439
 			for (++x; x < len; ++x)
435 440
 			{
Browse code

Use C++17 std::filesystem functions instead of my own.

Naram Qashat authored on 2021/03/20 20:05:50
Showing 1 changed files
... ...
@@ -6,8 +6,12 @@
6 6
  */
7 7
 
8 8
 #include <algorithm>
9
+#include <filesystem>
9 10
 #include <functional>
10 11
 #include <stdexcept>
12
+#if defined(_WIN32) && !defined(_MSC_VER)
13
+# include "fstream_wfopen.h"
14
+#endif
11 15
 #include "zlib.h"
12 16
 #include "XSFFile.h"
13 17
 #include "XSFCommon.h"
... ...
@@ -80,7 +84,7 @@ XSFFile::XSFFile(const std::wstring &filename, uint32_t programSizeOffset, uint3
80 84
 
81 85
 void XSFFile::ReadXSF(const std::string &filename, uint32_t programSizeOffset, uint32_t programHeaderSize, bool readTagsOnly)
82 86
 {
83
-	if (!FileExists(filename))
87
+	if (!std::filesystem::is_regular_file(filename))
84 88
 		throw std::logic_error("File " + filename + " does not exist.");
85 89
 
86 90
 	std::ifstream xSF;
... ...
@@ -95,7 +99,7 @@ void XSFFile::ReadXSF(const std::string &filename, uint32_t programSizeOffset, u
95 99
 #ifdef _WIN32
96 100
 void XSFFile::ReadXSF(const std::wstring &filename, uint32_t programSizeOffset, uint32_t programHeaderSize, bool readTagsOnly)
97 101
 {
98
-	if (!FileExists(filename))
102
+	if (!std::filesystem::is_regular_file(filename))
99 103
 		throw std::logic_error("File " + ConvertFuncs::WStringToString(filename) + " does not exist.");
100 104
 
101 105
 #if defined(_WIN32) && !defined(_MSC_VER)
... ...
@@ -460,7 +464,7 @@ std::string XSFFile::GetFilename() const
460 464
 
461 465
 std::string XSFFile::GetFilenameWithoutPath() const
462 466
 {
463
-	return ExtractFilenameFromPath(this->fileName);
467
+	return std::filesystem::path(this->fileName).filename().string();
464 468
 }
465 469
 
466 470
 void XSFFile::SaveFile() const
Browse code

Replace std::not1 with a lamba.

Naram Qashat authored on 2021/03/20 17:45:09
Showing 1 changed files
... ...
@@ -24,24 +24,26 @@ static inline void Set32BitsLE(uint32_t input, uint8_t *output)
24 24
 // The whitespace trimming was modified from the following answer on Stack Overflow:
25 25
 // http://stackoverflow.com/a/217605
26 26
 
27
-struct IsWhitespace
27
+bool IsWhitespace(const char &x)
28 28
 {
29
-  using argument_type = char;;
30
-	bool operator()(const char &x) const
31
-	{
32
-		return x >= 0x01 && x <= 0x20;
33
-	}
34
-};
29
+	return x >= 0x01 && x <= 0x20;
30
+}
35 31
 
36 32
 static inline std::string LeftTrimWhitespace(const std::string &orig)
37 33
 {
38
-	auto first_non_space = std::find_if(orig.begin(), orig.end(), std::not1(IsWhitespace()));
34
+	auto first_non_space = std::find_if(orig.begin(), orig.end(), [](const char &x)
35
+	{
36
+		return !IsWhitespace(x);
37
+	});
39 38
 	return std::string(first_non_space, orig.end());
40 39
 }
41 40
 
42 41
 static inline std::string RightTrimWhitespace(const std::string &orig)
43 42
 {
44
-	auto last_non_space = std::find_if(orig.rbegin(), orig.rend(), std::not1(IsWhitespace())).base();
43
+	auto last_non_space = std::find_if(orig.rbegin(), orig.rend(), [](const char &x)
44
+	{
45
+		return !IsWhitespace(x);
46
+	}).base();
45 47
 	return std::string(orig.begin(), last_non_space);
46 48
 }
47 49
 
Browse code

Replace memcpy/memset with std::copy_n/std::fill_n.

Naram Qashat authored on 2021/03/19 16:25:21
Showing 1 changed files
... ...
@@ -128,7 +128,7 @@ void XSFFile::ReadXSF(std::ifstream &xSF, uint32_t programSizeOffset, uint32_t p
128 128
 	this->xSFType = PSFHeader[3];
129 129
 
130 130
 	this->rawData.resize(4);
131
-	memcpy(&this->rawData[0], PSFHeader, 4);
131
+	std::copy_n(PSFHeader, 4, &this->rawData[0]);
132 132
 
133 133
 	if (filesize < 16)
134 134
 		throw std::runtime_error("File is too small.");
... ...
@@ -150,7 +150,7 @@ void XSFFile::ReadXSF(std::ifstream &xSF, uint32_t programSizeOffset, uint32_t p
150 150
 		{
151 151
 			this->reservedSection.resize(reservedSize);
152 152
 			xSF.read(reinterpret_cast<char *>(&this->reservedSection[0]), reservedSize);
153
-			memcpy(&this->rawData[16], &this->reservedSection[0], reservedSize);
153
+			std::copy_n(&this->reservedSection[0], reservedSize, &this->rawData[16]);
154 154
 		}
155 155
 	}
156 156
 
... ...
@@ -165,7 +165,7 @@ void XSFFile::ReadXSF(std::ifstream &xSF, uint32_t programSizeOffset, uint32_t p
165 165
 		{
166 166
 			auto programSectionCompressed = std::vector<uint8_t>(programCompressedSize);
167 167
 			xSF.read(reinterpret_cast<char *>(&programSectionCompressed[0]), programCompressedSize);
168
-			memcpy(&this->rawData[reservedSize + 16], &programSectionCompressed[0], programCompressedSize);
168
+			std::copy_n(&programSectionCompressed[0], programCompressedSize, &this->rawData[reservedSize + 16]);
169 169
 
170 170
 			auto programSectionUncompressed = std::vector<uint8_t>(programHeaderSize);
171 171
 			unsigned long programUncompressedSize = programHeaderSize;
Browse code

Some conversion replacements:

* Replace the (w)stringify functions with the standard std::to_(w)string functions.
* Replace convertTo with versions that use type_traits to determine which standard string conversion function to call, as well as handle enums specically.

Naram Qashat authored on 2021/03/19 11:57:21
Showing 1 changed files
... ...
@@ -325,24 +325,24 @@ double XSFFile::GetVolume(VolumeType preferredVolumeType, PeakType preferredPeak
325 325
 	bool hadReplayGain = false;
326 326
 	if (preferredVolumeType == VOLUMETYPE_REPLAYGAIN_ALBUM && !replaygain_album_gain.empty())
327 327
 	{
328
-		gain = convertTo<double>(replaygain_album_gain, false);
328
+		gain = convertTo<double>(replaygain_album_gain);
329 329
 		hadReplayGain = true;
330 330
 	}
331 331
 	if (!hadReplayGain && preferredVolumeType != VOLUMETYPE_VOLUME && !replaygain_track_gain.empty())
332 332
 	{
333
-		gain = convertTo<double>(replaygain_track_gain, false);
333
+		gain = convertTo<double>(replaygain_track_gain);
334 334
 		hadReplayGain = true;
335 335
 	}
336 336
 	if (hadReplayGain)
337 337
 	{
338 338
 		double vol = std::pow(10.0, gain / 20.0), peak = 1.0;
339 339
 		if (preferredPeakType == PEAKTYPE_REPLAYGAIN_ALBUM && !replaygain_album_peak.empty())
340
-			peak = convertTo<double>(replaygain_album_peak, false);
340
+			peak = convertTo<double>(replaygain_album_peak);
341 341
 		else if (preferredPeakType != PEAKTYPE_NONE && !replaygain_track_peak.empty())
342
-			peak = convertTo<double>(replaygain_track_peak, false);
342
+			peak = convertTo<double>(replaygain_track_peak);
343 343
 		return !fEqual(peak, 1.0) ? std::min(vol, 1.0 / peak) : vol;
344 344
 	}
345
-	return volume.empty() ? 1.0 : convertTo<double>(volume, false);
345
+	return volume.empty() ? 1.0 : convertTo<double>(volume);
346 346
 }
347 347
 
348 348
 std::string XSFFile::FormattedTitleOptionalBlock(const std::string &block, bool &hadReplacement, unsigned level) const
Browse code

Remove last modification date from files.

(I never remember to update these and besides, GitHub history can show when they were last modified.)

Naram Qashat authored on 2021/03/19 10:58:12
Showing 1 changed files
... ...
@@ -1,7 +1,6 @@
1 1
 /*
2 2
  * xSF - File structure
3 3
  * By Naram Qashat (CyberBotX) [cyberbotx@cyberbotx.com]
4
- * Last modification on 2014-09-24
5 4
  *
6 5
  * Partially based on the vio*sf framework
7 6
  */
Browse code

update for C++17 compliance, update to latest 2sf, add WINE cross-compile makefiles

Adam Higerd authored on 2021/02/11 15:36:17
Showing 1 changed files
... ...
@@ -9,7 +9,7 @@
9 9
 #include <algorithm>
10 10
 #include <functional>
11 11
 #include <stdexcept>
12
-#include <zlib.h>
12
+#include "zlib.h"
13 13
 #include "XSFFile.h"
14 14
 #include "XSFCommon.h"
15 15
 #include "convert.h"
... ...
@@ -25,8 +25,9 @@ static inline void Set32BitsLE(uint32_t input, uint8_t *output)
25 25
 // The whitespace trimming was modified from the following answer on Stack Overflow:
26 26
 // http://stackoverflow.com/a/217605
27 27
 
28
-struct IsWhitespace : std::unary_function<char, bool>
28
+struct IsWhitespace
29 29
 {
30
+  using argument_type = char;;
30 31
 	bool operator()(const char &x) const
31 32
 	{
32 33
 		return x >= 0x01 && x <= 0x20;
Browse code

Lots of changes in regards to strings, as follows:

* Removed my custom String class, as well as removed the really old
Unicode ConvertUTF, the UTF Converter, and the UTF Encode/Decode
functions.
* Replaced the above with using standard C++ std::wstring_convert and
std::codecvt_utf8.
* Added headers adapted from llvm's libc++ project for allowing the
above C++ classes to exist with GCC and Clang when libc++ isn't being
used.
* Used std::string over std::wstring whenever possible.
* Added header adapted from llvm's libc++ project to create special
versions of the ifstream and ofstream classes that would utilize _wfopen
on non-MSVC Windows compilers, so those compilers could access files on
Windows that use characters outside the current codepage.
* Removed the -static-libgcc and -static-libstdc++ flags from the
Makefile for non-MSVC builds. The generated DLLs will require extra DLLs
from either Cygwin or MinGW (whichever is used to compile), I've only
tested with MinGW and for some reason they crash Winamp on exit, I have
no idea why.

Naram Qashat authored on 2014/09/24 13:58:55
Showing 1 changed files
... ...
@@ -1,7 +1,7 @@
1 1
 /*
2 2
  * xSF - File structure
3 3
  * By Naram Qashat (CyberBotX) [cyberbotx@cyberbotx.com]
4
- * Last modification on 2014-09-17
4
+ * Last modification on 2014-09-24
5 5
  *
6 6
  * Partially based on the vio*sf framework
7 7
  */
... ...
@@ -64,13 +64,13 @@ XSFFile::XSFFile(const std::string &filename, uint32_t programSizeOffset, uint32
64 64
 	this->ReadXSF(filename, programSizeOffset, programHeaderSize);
65 65
 }
66 66
 
67
-#ifdef _MSC_VER
68
-XSFFile::XSFFile(const std::wstring &filename) : xSFType(0), hasFile(false), rawData(), reservedSection(), programSection(), tags(), fileName(filename)
67
+#ifdef _WIN32
68
+XSFFile::XSFFile(const std::wstring &filename) : xSFType(0), hasFile(false), rawData(), reservedSection(), programSection(), tags(), fileName(ConvertFuncs::WStringToString(filename))
69 69
 {
70 70
 	this->ReadXSF(filename, 0, 0, true);
71 71
 }
72 72
 
73
-XSFFile::XSFFile(const std::wstring &filename, uint32_t programSizeOffset, uint32_t programHeaderSize) : xSFType(0), hasFile(false), rawData(), reservedSection(), programSection(), tags(), fileName(filename)
73
+XSFFile::XSFFile(const std::wstring &filename, uint32_t programSizeOffset, uint32_t programHeaderSize) : xSFType(0), hasFile(false), rawData(), reservedSection(), programSection(), tags(), fileName(ConvertFuncs::WStringToString(filename))
74 74
 {
75 75
 	this->ReadXSF(filename, programSizeOffset, programHeaderSize);
76 76
 }
... ...
@@ -86,19 +86,27 @@ void XSFFile::ReadXSF(const std::string &filename, uint32_t programSizeOffset, u
86 86
 	xSF.open(filename.c_str(), std::ifstream::in | std::ifstream::binary);
87 87
 
88 88
 	this->ReadXSF(xSF, programSizeOffset, programHeaderSize, readTagsOnly);
89
+
90
+	xSF.close();
89 91
 }
90 92
 
91
-#ifdef _MSC_VER
93
+#ifdef _WIN32
92 94
 void XSFFile::ReadXSF(const std::wstring &filename, uint32_t programSizeOffset, uint32_t programHeaderSize, bool readTagsOnly)
93 95
 {
94 96
 	if (!FileExists(filename))
95
-		throw std::logic_error("File " + String(filename).GetAnsi() + " does not exist.");
97
+		throw std::logic_error("File " + ConvertFuncs::WStringToString(filename) + " does not exist.");
96 98
 
99
+#if defined(_WIN32) && !defined(_MSC_VER)
100
+	ifstream_wfopen xSF;
101
+#else
97 102
 	std::ifstream xSF;
103
+#endif
98 104
 	xSF.exceptions(std::ifstream::failbit | std::ifstream::badbit);
99 105
 	xSF.open(filename.c_str(), std::ifstream::in | std::ifstream::binary);
100 106
 
101 107
 	this->ReadXSF(xSF, programSizeOffset, programHeaderSize, readTagsOnly);
108
+
109
+	xSF.close();
102 110
 }
103 111
 #endif
104 112
 
... ...
@@ -214,8 +222,6 @@ void XSFFile::ReadXSF(std::ifstream &xSF, uint32_t programSizeOffset, uint32_t p
214 222
 		}
215 223
 	}
216 224
 
217
-	xSF.close();
218
-
219 225
 	this->hasFile = true;
220 226
 }
221 227
 
... ...
@@ -268,9 +274,14 @@ void XSFFile::SetAllTags(const TagList &newTags)
268 274
 	this->tags = newTags;
269 275
 }
270 276
 
271
-void XSFFile::SetTag(const std::string &name, const String &value)
277
+void XSFFile::SetTag(const std::string &name, const std::string &value)
278
+{
279
+	this->tags[name] = value;
280
+}
281
+
282
+void XSFFile::SetTag(const std::string &name, const std::wstring &value)
272 283
 {
273
-	this->tags[name] = value.GetStr();
284
+	this->tags[name] = ConvertFuncs::WStringToString(value);
274 285
 }
275 286
 
276 287
 bool XSFFile::GetTagExists(const std::string &name) const
... ...
@@ -278,17 +289,17 @@ bool XSFFile::GetTagExists(const std::string &name) const
278 289
 	return this->tags.Exists(name);
279 290
 }
280 291
 
281
-String XSFFile::GetTagValue(const std::string &name) const
292
+std::string XSFFile::GetTagValue(const std::string &name) const
282 293
 {
283
-	return String(this->GetTagExists(name) ? this->tags[name] : "", this->GetTagExists("utf8"));
294
+	return this->GetTagExists(name) ? this->tags[name] : "";
284 295
 }
285 296
 
286 297
 unsigned long XSFFile::GetLengthMS(unsigned long defaultLength) const
287 298
 {
288 299
 	unsigned long length = 0;
289
-	String value = this->GetTagValue("length");
300
+	std::string value = this->GetTagValue("length");
290 301
 	if (!value.empty())
291
-		length = ConvertFuncs::StringToMS(value.GetAnsi());
302
+		length = ConvertFuncs::StringToMS(value);
292 303
 	if (!length)
293 304
 		length = defaultLength;
294 305
 	return length;
... ...
@@ -297,9 +308,9 @@ unsigned long XSFFile::GetLengthMS(unsigned long defaultLength) const
297 308
 unsigned long XSFFile::GetFadeMS(unsigned long defaultFade) const
298 309
 {
299 310
 	unsigned long fade = defaultFade;
300
-	String value = this->GetTagValue("fade");
311
+	std::string value = this->GetTagValue("fade");
301 312
 	if (!value.empty())
302
-		fade = ConvertFuncs::StringToMS(value.GetAnsi());
313
+		fade = ConvertFuncs::StringToMS(value);
303 314
 	return fade;
304 315
 }
305 316
 
... ...
@@ -307,49 +318,49 @@ double XSFFile::GetVolume(VolumeType preferredVolumeType, PeakType preferredPeak
307 318
 {
308 319
 	if (preferredVolumeType == VOLUMETYPE_NONE)
309 320
 		return 1.0;
310
-	String replaygain_album_gain = this->GetTagValue("replaygain_album_gain"), replaygain_album_peak = this->GetTagValue("replaygain_album_peak");
311
-	String replaygain_track_gain = this->GetTagValue("replaygain_track_gain"), replaygain_track_peak = this->GetTagValue("replaygain_track_peak");
312
-	String volume = this->GetTagValue("volume");
321
+	std::string replaygain_album_gain = this->GetTagValue("replaygain_album_gain"), replaygain_album_peak = this->GetTagValue("replaygain_album_peak");
322
+	std::string replaygain_track_gain = this->GetTagValue("replaygain_track_gain"), replaygain_track_peak = this->GetTagValue("replaygain_track_peak");
323
+	std::string volume = this->GetTagValue("volume");
313 324
 	double gain = 0.0;
314 325
 	bool hadReplayGain = false;
315 326
 	if (preferredVolumeType == VOLUMETYPE_REPLAYGAIN_ALBUM && !replaygain_album_gain.empty())
316 327
 	{
317
-		gain = convertTo<double>(replaygain_album_gain.GetAnsi(), false);
328
+		gain = convertTo<double>(replaygain_album_gain, false);
318 329
 		hadReplayGain = true;
319 330
 	}
320 331
 	if (!hadReplayGain && preferredVolumeType != VOLUMETYPE_VOLUME && !replaygain_track_gain.empty())
321 332
 	{
322
-		gain = convertTo<double>(replaygain_track_gain.GetAnsi(), false);
333
+		gain = convertTo<double>(replaygain_track_gain, false);
323 334
 		hadReplayGain = true;
324 335
 	}
325 336
 	if (hadReplayGain)
326 337
 	{
327 338
 		double vol = std::pow(10.0, gain / 20.0), peak = 1.0;
328 339
 		if (preferredPeakType == PEAKTYPE_REPLAYGAIN_ALBUM && !replaygain_album_peak.empty())
329
-			peak = convertTo<double>(replaygain_album_peak.GetAnsi(), false);
340
+			peak = convertTo<double>(replaygain_album_peak, false);
330 341
 		else if (preferredPeakType != PEAKTYPE_NONE && !replaygain_track_peak.empty())
331
-			peak = convertTo<double>(replaygain_track_peak.GetAnsi(), false);
342
+			peak = convertTo<double>(replaygain_track_peak, false);
332 343
 		return !fEqual(peak, 1.0) ? std::min(vol, 1.0 / peak) : vol;
333 344
 	}
334
-	return volume.empty() ? 1.0 : convertTo<double>(volume.GetAnsi(), false);
345
+	return volume.empty() ? 1.0 : convertTo<double>(volume, false);
335 346
 }
336 347
 
337
-String XSFFile::FormattedTitleOptionalBlock(const std::wstring &block, bool &hadReplacement, unsigned level) const
348
+std::string XSFFile::FormattedTitleOptionalBlock(const std::string &block, bool &hadReplacement, unsigned level) const
338 349
 {
339
-	String formattedBlock;
350
+	std::string formattedBlock;
340 351
 	for (size_t x = 0, len = block.length(); x < len; ++x)
341 352
 	{
342
-		wchar_t c = block[x];
343
-		if (c == L'%')
353
+		char c = block[x];
354
+		if (c == '%')
344 355
 		{
345 356
 			size_t origX = x;
346 357
 			for (++x; x < len; ++x)
347
-				if (block[x] == L'%')
358
+				if (block[x] == '%')
348 359
 					break;
349 360
 			if (x != len)
350 361
 			{
351
-				std::wstring tagname = block.substr(origX + 1, x - origX - 1);
352
-				String value = this->GetTagValue(String(tagname).GetAnsi());
362
+				std::string tagname = block.substr(origX + 1, x - origX - 1);
363
+				std::string value = this->GetTagValue(tagname);
353 364
 				if (!value.empty())
354 365
 				{
355 366
 					formattedBlock += value;
... ...
@@ -358,15 +369,15 @@ String XSFFile::FormattedTitleOptionalBlock(const std::wstring &block, bool &had
358 369
 			}
359 370
 			continue;
360 371
 		}
361
-		if (c == L'[' && level + 1 < 10)
372
+		if (c == '[' && level + 1 < 10)
362 373
 		{
363 374
 			size_t origX = x;
364 375
 			unsigned nests = 0;
365 376
 			for (++x; x < len; ++x)
366 377
 			{
367
-				if (block[x] == L'[')
378
+				if (block[x] == '[')
368 379
 					++nests;
369
-				else if (block[x] == L']')
380
+				else if (block[x] == ']')
370 381
 				{
371 382
 					if (!nests)
372 383
 						break;
... ...
@@ -375,9 +386,9 @@ String XSFFile::FormattedTitleOptionalBlock(const std::wstring &block, bool &had
375 386
 			}
376 387
 			if (x != len)
377 388
 			{
378
-				std::wstring innerBlock = block.substr(origX + 1, x - origX - 1);
389
+				std::string innerBlock = block.substr(origX + 1, x - origX - 1);
379 390
 				bool hadInnerReplacement = false;
380
-				String replacedBlock = this->FormattedTitleOptionalBlock(innerBlock, hadInnerReplacement, level + 1);
391
+				std::string replacedBlock = this->FormattedTitleOptionalBlock(innerBlock, hadInnerReplacement, level + 1);
381 392
 				if (hadInnerReplacement)
382 393
 					formattedBlock += replacedBlock;
383 394
 			}
... ...
@@ -388,37 +399,37 @@ String XSFFile::FormattedTitleOptionalBlock(const std::wstring &block, bool &had
388 399
 	return formattedBlock;
389 400
 }
390 401
 
391
-String XSFFile::GetFormattedTitle(const std::wstring &format) const
402
+std::string XSFFile::GetFormattedTitle(const std::string &format) const
392 403
 {
393
-	String formattedTitle;
404
+	std::string formattedTitle;
394 405
 	for (size_t x = 0, len = format.length(); x < len; ++x)
395 406
 	{
396
-		wchar_t c = format[x];
397
-		if (c == L'%')
407
+		char c = format[x];
408
+		if (c == '%')
398 409
 		{
399 410
 			size_t origX = x;
400 411
 			for (++x; x < len; ++x)
401
-				if (format[x] == L'%')
412
+				if (format[x] == '%')
402 413
 					break;
403 414
 			if (x != len)
404 415
 			{
405
-				std::wstring tagname = format.substr(origX + 1, x - origX - 1);
406
-				String value = this->GetTagValue(String(tagname).GetAnsi());
416
+				std::string tagname = format.substr(origX + 1, x - origX - 1);
417
+				std::string value = this->GetTagValue(tagname);
407 418
 				if (value.empty())
408 419
 					formattedTitle += "???";
409 420
 				else
410 421
 					formattedTitle += value;
411 422
 			}
412 423
 		}
413
-		else if (c == L'[')
424
+		else if (c == '[')
414 425
 		{
415 426
 			size_t origX = x;
416 427
 			unsigned nests = 0;
417 428
 			for (++x; x < len; ++x)
418 429
 			{
419
-				if (format[x] == L'[')
430
+				if (format[x] == '[')
420 431
 					++nests;
421
-				else if (format[x] == L']')
432
+				else if (format[x] == ']')
422 433
 				{
423 434
 					if (!nests)
424 435
 						break;
... ...
@@ -427,9 +438,9 @@ String XSFFile::GetFormattedTitle(const std::wstring &format) const
427 438
 			}
428 439
 			if (x != len)
429 440
 			{
430
-				std::wstring block = format.substr(origX + 1, x - origX - 1);
441
+				std::string block = format.substr(origX + 1, x - origX - 1);
431 442
 				bool hadReplacement = false;
432
-				String replacedBlock = this->FormattedTitleOptionalBlock(block, hadReplacement, 1);
443
+				std::string replacedBlock = this->FormattedTitleOptionalBlock(block, hadReplacement, 1);
433 444
 				if (hadReplacement)
434 445
 					formattedTitle += replacedBlock;
435 446
 			}
... ...
@@ -440,24 +451,28 @@ String XSFFile::GetFormattedTitle(const std::wstring &format) const
440 451
 	return formattedTitle;
441 452
 }
442 453
 
443
-String XSFFile::GetFilename() const
454
+std::string XSFFile::GetFilename() const
444 455
 {
445 456
 	return this->fileName;
446 457
 }
447 458
 
448
-String XSFFile::GetFilenameWithoutPath() const
459
+std::string XSFFile::GetFilenameWithoutPath() const
449 460
 {
450
-	return ExtractFilenameFromPath(this->fileName.GetStr());
461
+	return ExtractFilenameFromPath(this->fileName);
451 462
 }
452 463
 
453 464
 void XSFFile::SaveFile() const
454 465
 {
466
+#if defined(_WIN32) && !defined(_MSC_VER)
467
+	ofstream_wfopen xSF;
468
+#else
455 469
 	std::ofstream xSF;
470
+#endif
456 471
 	xSF.exceptions(std::ofstream::failbit);
457
-#ifdef _MSC_VER
458
-	xSF.open(this->fileName.GetWStrC(), std::ofstream::out | std::ofstream::binary);
472
+#ifdef _WIN32
473
+	xSF.open(ConvertFuncs::StringToWString(this->fileName).c_str(), std::ofstream::out | std::ofstream::binary);
459 474
 #else
460
-	xSF.open(this->fileName.GetStrC(), std::ofstream::out | std::ofstream::binary);
475
+	xSF.open(this->fileName.c_str(), std::ofstream::out | std::ofstream::binary);
461 476
 #endif
462 477
 
463 478
 	xSF.write(reinterpret_cast<const char *>(&this->rawData[0]), this->rawData.size());
Browse code

* Fixes for gcc and clang (while they can compile the code, the DLLs made aren't functional, but oh well).

* [2SF] Used more up-to-date asmjit, despite the ugly looking code.

Naram Qashat authored on 2014/09/17 19:51:45
Showing 1 changed files
... ...
@@ -1,7 +1,7 @@
1 1
 /*
2 2
  * xSF - File structure
3 3
  * By Naram Qashat (CyberBotX) [cyberbotx@cyberbotx.com]
4
- * Last modification on 2013-03-30
4
+ * Last modification on 2014-09-17
5 5
  *
6 6
  * Partially based on the vio*sf framework
7 7
  */
... ...
@@ -64,7 +64,7 @@ XSFFile::XSFFile(const std::string &filename, uint32_t programSizeOffset, uint32
64 64
 	this->ReadXSF(filename, programSizeOffset, programHeaderSize);
65 65
 }
66 66
 
67
-#ifdef _WIN32
67
+#ifdef _MSC_VER
68 68
 XSFFile::XSFFile(const std::wstring &filename) : xSFType(0), hasFile(false), rawData(), reservedSection(), programSection(), tags(), fileName(filename)
69 69
 {
70 70
 	this->ReadXSF(filename, 0, 0, true);
... ...
@@ -88,7 +88,7 @@ void XSFFile::ReadXSF(const std::string &filename, uint32_t programSizeOffset, u
88 88
 	this->ReadXSF(xSF, programSizeOffset, programHeaderSize, readTagsOnly);
89 89
 }
90 90
 
91
-#ifdef _WIN32
91
+#ifdef _MSC_VER
92 92
 void XSFFile::ReadXSF(const std::wstring &filename, uint32_t programSizeOffset, uint32_t programHeaderSize, bool readTagsOnly)
93 93
 {
94 94
 	if (!FileExists(filename))
... ...
@@ -454,7 +454,7 @@ void XSFFile::SaveFile() const
454 454
 {
455 455
 	std::ofstream xSF;
456 456
 	xSF.exceptions(std::ofstream::failbit);
457
-#ifdef _WIN32
457
+#ifdef _MSC_VER
458 458
 	xSF.open(this->fileName.GetWStrC(), std::ofstream::out | std::ofstream::binary);
459 459
 #else
460 460
 	xSF.open(this->fileName.GetStrC(), std::ofstream::out | std::ofstream::binary);
Browse code

Cleanup of some warnings, updating modification dates, using nullptr instead of NULL in some cases.

Naram Qashat authored on 2013/03/30 16:17:42
Showing 1 changed files
... ...
@@ -1,7 +1,7 @@
1 1
 /*
2 2
  * xSF - File structure
3 3
  * By Naram Qashat (CyberBotX) [cyberbotx@cyberbotx.com]
4
- * Last modification on 2013-03-25
4
+ * Last modification on 2013-03-30
5 5
  *
6 6
  * Partially based on the vio*sf framework
7 7
  */
Browse code

Utilized more C++11 constructs. Also attempted to fix issue with the Info Box not wanting to come up anymore if the file doesn't exist.

Naram Qashat authored on 2013/03/30 07:36:38
Showing 1 changed files
... ...
@@ -466,10 +466,10 @@ void XSFFile::SaveFile() const
466 466
 	if (!allTags.empty())
467 467
 	{
468 468
 		xSF.write("[TAG]", 5);
469
-		for (auto curr = allTags.begin(), end = allTags.end(); curr != end; ++curr)
469
+		std::for_each(allTags.begin(), allTags.end(), [&](const std::string &tag)
470 470
 		{
471
-			xSF.write(curr->c_str(), curr->length());
471
+			xSF.write(tag.c_str(), tag.length());
472 472
 			xSF.write("\n", 1);
473
-		}
473
+		});
474 474
 	}
475 475
 }
Browse code

Fixed getting the path of the filename for XSFFile.

Naram Qashat authored on 2013/03/26 06:58:50
Showing 1 changed files
... ...
@@ -447,7 +447,7 @@ String XSFFile::GetFilename() const
447 447
 
448 448
 String XSFFile::GetFilenameWithoutPath() const
449 449
 {
450
-	return ExtractDirectoryFromPath(this->fileName.GetStr());
450
+	return ExtractFilenameFromPath(this->fileName.GetStr());
451 451
 }
452 452
 
453 453
 void XSFFile::SaveFile() const
Browse code

Import actual code.

Naram Qashat authored on 2013/03/26 02:41:19
Showing 1 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1,475 @@
1
+/*
2
+ * xSF - File structure
3
+ * By Naram Qashat (CyberBotX) [cyberbotx@cyberbotx.com]
4
+ * Last modification on 2013-03-25
5
+ *
6
+ * Partially based on the vio*sf framework
7
+ */
8
+
9
+#include <algorithm>
10
+#include <functional>
11
+#include <stdexcept>
12
+#include <zlib.h>
13
+#include "XSFFile.h"
14
+#include "XSFCommon.h"
15
+#include "convert.h"
16
+
17
+static inline void Set32BitsLE(uint32_t input, uint8_t *output)
18
+{
19
+	output[0] = input & 0xFF;
20
+	output[1] = (input >> 8) & 0xFF;
21
+	output[2] = (input >> 16) & 0xFF;
22
+	output[3] = (input >> 24) & 0xFF;
23
+}
24
+
25
+// The whitespace trimming was modified from the following answer on Stack Overflow:
26
+// http://stackoverflow.com/a/217605
27
+
28
+struct IsWhitespace : std::unary_function<char, bool>
29
+{
30
+	bool operator()(const char &x) const
31
+	{
32
+		return x >= 0x01 && x <= 0x20;
33
+	}
34
+};
35
+
36
+static inline std::string LeftTrimWhitespace(const std::string &orig)
37
+{
38
+	auto first_non_space = std::find_if(orig.begin(), orig.end(), std::not1(IsWhitespace()));
39
+	return std::string(first_non_space, orig.end());
40
+}
41
+
42
+static inline std::string RightTrimWhitespace(const std::string &orig)
43
+{
44
+	auto last_non_space = std::find_if(orig.rbegin(), orig.rend(), std::not1(IsWhitespace())).base();
45
+	return std::string(orig.begin(), last_non_space);
46
+}
47
+
48
+static inline std::string TrimWhitespace(const std::string &orig)
49
+{
50
+	return LeftTrimWhitespace(RightTrimWhitespace(orig));
51
+}
52
+
53
+XSFFile::XSFFile() : xSFType(0), hasFile(false), rawData(), reservedSection(), programSection(), tags(), fileName("")
54
+{
55
+}
56
+
57
+XSFFile::XSFFile(const std::string &filename) : xSFType(0), hasFile(false), rawData(), reservedSection(), programSection(), tags(), fileName(filename)
58
+{
59
+	this->ReadXSF(filename, 0, 0, true);
60
+}
61
+
62
+XSFFile::XSFFile(const std::string &filename, uint32_t programSizeOffset, uint32_t programHeaderSize) : xSFType(0), hasFile(false), rawData(), reservedSection(), programSection(), tags(), fileName(filename)
63
+{
64
+	this->ReadXSF(filename, programSizeOffset, programHeaderSize);
65
+}
66
+
67
+#ifdef _WIN32
68
+XSFFile::XSFFile(const std::wstring &filename) : xSFType(0), hasFile(false), rawData(), reservedSection(), programSection(), tags(), fileName(filename)
69
+{
70
+	this->ReadXSF(filename, 0, 0, true);
71
+}
72
+
73
+XSFFile::XSFFile(const std::wstring &filename, uint32_t programSizeOffset, uint32_t programHeaderSize) : xSFType(0), hasFile(false), rawData(), reservedSection(), programSection(), tags(), fileName(filename)
74
+{
75
+	this->ReadXSF(filename, programSizeOffset, programHeaderSize);
76
+}
77
+#endif
78
+
79
+void XSFFile::ReadXSF(const std::string &filename, uint32_t programSizeOffset, uint32_t programHeaderSize, bool readTagsOnly)
80
+{
81
+	if (!FileExists(filename))
82
+		throw std::logic_error("File " + filename + " does not exist.");
83
+
84
+	std::ifstream xSF;
85
+	xSF.exceptions(std::ifstream::failbit | std::ifstream::badbit);
86
+	xSF.open(filename.c_str(), std::ifstream::in | std::ifstream::binary);
87
+
88
+	this->ReadXSF(xSF, programSizeOffset, programHeaderSize, readTagsOnly);
89
+}
90
+
91
+#ifdef _WIN32
92
+void XSFFile::ReadXSF(const std::wstring &filename, uint32_t programSizeOffset, uint32_t programHeaderSize, bool readTagsOnly)
93
+{
94
+	if (!FileExists(filename))
95
+		throw std::logic_error("File " + String(filename).GetAnsi() + " does not exist.");
96
+
97
+	std::ifstream xSF;
98
+	xSF.exceptions(std::ifstream::failbit | std::ifstream::badbit);
99
+	xSF.open(filename.c_str(), std::ifstream::in | std::ifstream::binary);
100
+
101
+	this->ReadXSF(xSF, programSizeOffset, programHeaderSize, readTagsOnly);
102
+}
103
+#endif
104
+
105
+void XSFFile::ReadXSF(std::ifstream &xSF, uint32_t programSizeOffset, uint32_t programHeaderSize, bool readTagsOnly)
106
+{
107
+	xSF.seekg(0, std::ifstream::end);
108
+	auto filesize = xSF.tellg();
109
+	xSF.seekg(0, std::ifstream::beg);
110
+
111
+	if (filesize < 4)
112
+		throw std::runtime_error("File is too small.");
113
+
114
+	char PSFHeader[4];
115
+	xSF.read(PSFHeader, 4);
116
+
117
+	if (PSFHeader[0] != 'P' || PSFHeader[1] != 'S' || PSFHeader[2] != 'F')
118
+		throw std::runtime_error("Not a PSF file.");
119
+
120
+	this->xSFType = PSFHeader[3];
121
+
122
+	this->rawData.resize(4);
123
+	memcpy(&this->rawData[0], PSFHeader, 4);
124
+
125
+	if (filesize < 16)
126
+		throw std::runtime_error("File is too small.");
127
+
128
+	uint32_t reservedSize = Get32BitsLE(xSF), programCompressedSize = Get32BitsLE(xSF);
129
+	this->rawData.resize(reservedSize + programCompressedSize + 16);
130
+	Set32BitsLE(reservedSize, &this->rawData[4]);
131
+	Set32BitsLE(programCompressedSize, &this->rawData[8]);
132
+	xSF.read(reinterpret_cast<char *>(&this->rawData[12]), 4);
133
+
134
+	if (reservedSize)
135
+	{
136
+		if (filesize < reservedSize + 16)
137
+			throw std::runtime_error("File is too small.");
138
+
139
+		if (readTagsOnly)
140
+			xSF.read(reinterpret_cast<char *>(&this->rawData[16]), reservedSize);
141
+		else
142
+		{
143
+			this->reservedSection.resize(reservedSize);
144
+			xSF.read(reinterpret_cast<char *>(&this->reservedSection[0]), reservedSize);
145
+			memcpy(&this->rawData[16], &this->reservedSection[0], reservedSize);
146
+		}
147
+	}
148
+
149
+	if (programCompressedSize)
150
+	{
151
+		if (filesize < reservedSize + programCompressedSize + 16)
152
+			throw std::runtime_error("File is too small.");
153
+
154
+		if (readTagsOnly)
155
+			xSF.read(reinterpret_cast<char *>(&this->rawData[reservedSize + 16]), programCompressedSize);
156
+		else
157
+		{
158
+			auto programSectionCompressed = std::vector<uint8_t>(programCompressedSize);
159
+			xSF.read(reinterpret_cast<char *>(&programSectionCompressed[0]), programCompressedSize);
160
+			memcpy(&this->rawData[reservedSize + 16], &programSectionCompressed[0], programCompressedSize);
161
+
162
+			auto programSectionUncompressed = std::vector<uint8_t>(programHeaderSize);
163
+			unsigned long programUncompressedSize = programHeaderSize;
164
+			uncompress(&programSectionUncompressed[0], &programUncompressedSize, &programSectionCompressed[0], programCompressedSize);
165
+			programUncompressedSize = Get32BitsLE(&programSectionUncompressed[programSizeOffset]) + programHeaderSize;
166
+			this->programSection.resize(programUncompressedSize);
167
+			uncompress(&this->programSection[0], &programUncompressedSize, &programSectionCompressed[0], programCompressedSize);
168
+		}
169
+	}
170
+
171
+	if (xSF.tellg() != filesize && filesize >= reservedSize + programCompressedSize + 21)
172
+	{
173
+		char tagheader[6] = "";
174
+		xSF.read(tagheader, 5);
175
+		if (std::string(tagheader) == "[TAG]")
176
+		{
177
+			auto startOfTags = xSF.tellg();
178
+			unsigned lengthOfTags = static_cast<unsigned>(filesize - startOfTags);
179
+			if (lengthOfTags)
180
+			{
181
+				auto rawtags = std::vector<char>(lengthOfTags);
182
+				xSF.read(&rawtags[0], lengthOfTags);
183
+				std::string name, value;
184
+				bool onName = true;
185
+				for (unsigned x = 0; x < lengthOfTags; ++x)
186
+				{
187
+					char curr = rawtags[x];
188
+					if (curr == 0x0A)
189
+					{
190
+						if (!name.empty() && !value.empty())
191
+						{
192
+							name = TrimWhitespace(name);
193
+							value = TrimWhitespace(value);
194
+							if (this->tags.Exists(name))
195
+								this->tags[name] += "\n" + value;
196
+							else
197
+								this->tags[name] = value;
198
+						}
199
+						name = value = "";
200
+						onName = true;
201
+						continue;
202
+					}
203
+					if (curr == '=')
204
+					{
205
+						onName = false;
206
+						continue;
207
+					}
208
+					if (onName)
209
+						name += curr;
210
+					else
211
+						value += curr;
212
+				}
213
+			}
214
+		}
215
+	}
216
+
217
+	xSF.close();
218
+
219
+	this->hasFile = true;
220
+}
221
+
222
+bool XSFFile::IsValidType(uint8_t type) const
223
+{
224
+	return this->xSFType == type;
225
+}
226
+
227
+void XSFFile::Clear()
228
+{
229
+	this->xSFType = 0;
230
+	this->hasFile = false;
231
+	this->reservedSection.clear();
232
+	this->programSection.clear();
233
+	this->tags.Clear();
234
+}
235
+
236
+bool XSFFile::HasFile() const
237
+{
238
+	return this->hasFile;
239
+}
240
+
241
+std::vector<uint8_t> &XSFFile::GetReservedSection()
242
+{
243
+	return this->reservedSection;
244
+}
245
+
246
+std::vector<uint8_t> XSFFile::GetReservedSection() const
247
+{
248
+	return this->reservedSection;
249
+}
250
+
251
+std::vector<uint8_t> &XSFFile::GetProgramSection()
252
+{
253
+	return this->programSection;
254
+}
255
+
256
+std::vector<uint8_t> XSFFile::GetProgramSection() const
257
+{
258
+	return this->programSection;
259
+}
260
+
261
+const TagList &XSFFile::GetAllTags() const
262
+{
263
+	return this->tags;
264
+}
265
+
266
+void XSFFile::SetAllTags(const TagList &newTags)
267
+{
268
+	this->tags = newTags;
269
+}
270
+
271
+void XSFFile::SetTag(const std::string &name, const String &value)
272
+{
273
+	this->tags[name] = value.GetStr();
274
+}
275
+
276
+bool XSFFile::GetTagExists(const std::string &name) const
277
+{
278
+	return this->tags.Exists(name);
279
+}
280
+
281
+String XSFFile::GetTagValue(const std::string &name) const
282
+{
283
+	return String(this->GetTagExists(name) ? this->tags[name] : "", this->GetTagExists("utf8"));
284
+}
285
+
286
+unsigned long XSFFile::GetLengthMS(unsigned long defaultLength) const
287
+{
288
+	unsigned long length = 0;
289
+	String value = this->GetTagValue("length");
290
+	if (!value.empty())
291
+		length = ConvertFuncs::StringToMS(value.GetAnsi());
292
+	if (!length)
293
+		length = defaultLength;
294
+	return length;
295
+}
296
+
297
+unsigned long XSFFile::GetFadeMS(unsigned long defaultFade) const
298
+{
299
+	unsigned long fade = defaultFade;
300
+	String value = this->GetTagValue("fade");
301
+	if (!value.empty())
302
+		fade = ConvertFuncs::StringToMS(value.GetAnsi());
303
+	return fade;
304
+}
305
+
306
+double XSFFile::GetVolume(VolumeType preferredVolumeType, PeakType preferredPeakType) const
307
+{
308
+	if (preferredVolumeType == VOLUMETYPE_NONE)
309
+		return 1.0;
310
+	String replaygain_album_gain = this->GetTagValue("replaygain_album_gain"), replaygain_album_peak = this->GetTagValue("replaygain_album_peak");
311
+	String replaygain_track_gain = this->GetTagValue("replaygain_track_gain"), replaygain_track_peak = this->GetTagValue("replaygain_track_peak");
312
+	String volume = this->GetTagValue("volume");
313
+	double gain = 0.0;
314
+	bool hadReplayGain = false;
315
+	if (preferredVolumeType == VOLUMETYPE_REPLAYGAIN_ALBUM && !replaygain_album_gain.empty())
316
+	{
317
+		gain = convertTo<double>(replaygain_album_gain.GetAnsi(), false);
318
+		hadReplayGain = true;
319
+	}
320
+	if (!hadReplayGain && preferredVolumeType != VOLUMETYPE_VOLUME && !replaygain_track_gain.empty())
321
+	{
322
+		gain = convertTo<double>(replaygain_track_gain.GetAnsi(), false);
323
+		hadReplayGain = true;
324
+	}
325
+	if (hadReplayGain)
326
+	{
327
+		double vol = std::pow(10.0, gain / 20.0), peak = 1.0;
328
+		if (preferredPeakType == PEAKTYPE_REPLAYGAIN_ALBUM && !replaygain_album_peak.empty())
329
+			peak = convertTo<double>(replaygain_album_peak.GetAnsi(), false);
330
+		else if (preferredPeakType != PEAKTYPE_NONE && !replaygain_track_peak.empty())
331
+			peak = convertTo<double>(replaygain_track_peak.GetAnsi(), false);
332
+		return !fEqual(peak, 1.0) ? std::min(vol, 1.0 / peak) : vol;
333
+	}
334
+	return volume.empty() ? 1.0 : convertTo<double>(volume.GetAnsi(), false);
335
+}
336
+
337
+String XSFFile::FormattedTitleOptionalBlock(const std::wstring &block, bool &hadReplacement, unsigned level) const
338
+{
339
+	String formattedBlock;
340
+	for (size_t x = 0, len = block.length(); x < len; ++x)
341
+	{
342
+		wchar_t c = block[x];
343
+		if (c == L'%')
344
+		{
345
+			size_t origX = x;
346
+			for (++x; x < len; ++x)
347
+				if (block[x] == L'%')
348
+					break;
349
+			if (x != len)
350
+			{
351
+				std::wstring tagname = block.substr(origX + 1, x - origX - 1);
352
+				String value = this->GetTagValue(String(tagname).GetAnsi());
353
+				if (!value.empty())
354
+				{
355
+					formattedBlock += value;
356
+					hadReplacement = true;
357
+				}
358
+			}
359
+			continue;
360
+		}
361
+		if (c == L'[' && level + 1 < 10)
362
+		{
363
+			size_t origX = x;
364
+			unsigned nests = 0;
365
+			for (++x; x < len; ++x)
366
+			{
367
+				if (block[x] == L'[')
368
+					++nests;
369
+				else if (block[x] == L']')
370
+				{
371
+					if (!nests)
372
+						break;
373
+					--nests;
374
+				}
375
+			}
376
+			if (x != len)
377
+			{
378
+				std::wstring innerBlock = block.substr(origX + 1, x - origX - 1);
379
+				bool hadInnerReplacement = false;
380
+				String replacedBlock = this->FormattedTitleOptionalBlock(innerBlock, hadInnerReplacement, level + 1);
381
+				if (hadInnerReplacement)
382
+					formattedBlock += replacedBlock;
383
+			}
384
+			continue;
385
+		}
386
+		formattedBlock += c;
387
+	}
388
+	return formattedBlock;
389
+}
390
+
391
+String XSFFile::GetFormattedTitle(const std::wstring &format) const
392
+{
393
+	String formattedTitle;
394
+	for (size_t x = 0, len = format.length(); x < len; ++x)
395
+	{
396
+		wchar_t c = format[x];
397
+		if (c == L'%')
398
+		{
399
+			size_t origX = x;
400
+			for (++x; x < len; ++x)
401
+				if (format[x] == L'%')
402
+					break;
403
+			if (x != len)
404
+			{
405
+				std::wstring tagname = format.substr(origX + 1, x - origX - 1);
406
+				String value = this->GetTagValue(String(tagname).GetAnsi());
407
+				if (value.empty())
408
+					formattedTitle += "???";
409
+				else
410
+					formattedTitle += value;
411
+			}
412
+		}
413
+		else if (c == L'[')
414
+		{
415
+			size_t origX = x;
416
+			unsigned nests = 0;
417
+			for (++x; x < len; ++x)
418
+			{
419
+				if (format[x] == L'[')
420
+					++nests;
421
+				else if (format[x] == L']')
422
+				{
423
+					if (!nests)
424
+						break;
425
+					--nests;
426
+				}
427
+			}
428
+			if (x != len)
429
+			{
430
+				std::wstring block = format.substr(origX + 1, x - origX - 1);
431
+				bool hadReplacement = false;
432
+				String replacedBlock = this->FormattedTitleOptionalBlock(block, hadReplacement, 1);
433
+				if (hadReplacement)
434
+					formattedTitle += replacedBlock;
435
+			}
436
+		}
437
+		else
438
+			formattedTitle += c;
439
+	}
440
+	return formattedTitle;
441
+}
442
+
443
+String XSFFile::GetFilename() const
444
+{
445
+	return this->fileName;
446
+}
447
+
448
+String XSFFile::GetFilenameWithoutPath() const
449
+{
450
+	return ExtractDirectoryFromPath(this->fileName.GetStr());
451
+}
452
+
453
+void XSFFile::SaveFile() const
454
+{
455
+	std::ofstream xSF;
456
+	xSF.exceptions(std::ofstream::failbit);
457
+#ifdef _WIN32
458
+	xSF.open(this->fileName.GetWStrC(), std::ofstream::out | std::ofstream::binary);
459
+#else
460
+	xSF.open(this->fileName.GetStrC(), std::ofstream::out | std::ofstream::binary);
461
+#endif
462
+
463
+	xSF.write(reinterpret_cast<const char *>(&this->rawData[0]), this->rawData.size());
464
+
465
+	auto allTags = this->tags.GetTags();
466
+	if (!allTags.empty())
467
+	{
468
+		xSF.write("[TAG]", 5);
469
+		for (auto curr = allTags.begin(), end = allTags.end(); curr != end; ++curr)
470
+		{
471
+			xSF.write(curr->c_str(), curr->length());
472
+			xSF.write("\n", 1);
473
+		}
474
+	}
475
+}