Port to macOS
Signed-off-by: Simon Rozman <simon@rozman.si>
This commit is contained in:
parent
1e993c8c65
commit
83d7fd844d
@ -7,8 +7,8 @@
|
||||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
F48105AD2AAF5FD4004DE682 /* math.hpp in Sources */ = {isa = PBXBuildFile; fileRef = F48105AC2AAF5FD4004DE682 /* math.hpp */; };
|
||||
F4B7FBE02AAF49BC00C6BE9F /* main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F4B7FBDF2AAF49BC00C6BE9F /* main.cpp */; };
|
||||
F4C07F522AB059580044EDC0 /* pch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F4C07F512AB059580044EDC0 /* pch.cpp */; };
|
||||
F4C07F552AB05B5B0044EDC0 /* main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F4C07F542AB05B5B0044EDC0 /* main.cpp */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXCopyFilesBuildPhase section */
|
||||
@ -24,10 +24,17 @@
|
||||
/* End PBXCopyFilesBuildPhase section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
F48105AC2AAF5FD4004DE682 /* math.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = math.hpp; sourceTree = "<group>"; };
|
||||
F48105AE2AAF64C7004DE682 /* common.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = common.hpp; sourceTree = "<group>"; };
|
||||
F4B7FBDC2AAF49BC00C6BE9F /* UnitTests */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = UnitTests; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
F4B7FBDF2AAF49BC00C6BE9F /* main.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = main.cpp; sourceTree = "<group>"; };
|
||||
F4C07F4E2AB059300044EDC0 /* math.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = math.cpp; sourceTree = "<group>"; };
|
||||
F4C07F502AB059580044EDC0 /* pch.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = pch.h; sourceTree = "<group>"; };
|
||||
F4C07F512AB059580044EDC0 /* pch.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = pch.cpp; sourceTree = "<group>"; };
|
||||
F4C07F532AB05A240044EDC0 /* compat.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = compat.hpp; sourceTree = "<group>"; };
|
||||
F4C07F542AB05B5B0044EDC0 /* main.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = main.cpp; sourceTree = "<group>"; };
|
||||
F4C07F562AB08E690044EDC0 /* parser.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = parser.cpp; sourceTree = "<group>"; };
|
||||
F4C07F572AB08E690044EDC0 /* unicode.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = unicode.cpp; sourceTree = "<group>"; };
|
||||
F4C07F582AB08E690044EDC0 /* sgml.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = sgml.cpp; sourceTree = "<group>"; };
|
||||
F4C07F592AB08E690044EDC0 /* ring.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ring.cpp; sourceTree = "<group>"; };
|
||||
F4C07F5A2AB08E690044EDC0 /* stream.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = stream.cpp; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
@ -44,7 +51,16 @@
|
||||
F4B7FBD32AAF49BC00C6BE9F = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
F4B7FBDE2AAF49BC00C6BE9F /* UnitTests */,
|
||||
F4C07F542AB05B5B0044EDC0 /* main.cpp */,
|
||||
F4C07F4E2AB059300044EDC0 /* math.cpp */,
|
||||
F4C07F562AB08E690044EDC0 /* parser.cpp */,
|
||||
F4C07F512AB059580044EDC0 /* pch.cpp */,
|
||||
F4C07F592AB08E690044EDC0 /* ring.cpp */,
|
||||
F4C07F582AB08E690044EDC0 /* sgml.cpp */,
|
||||
F4C07F5A2AB08E690044EDC0 /* stream.cpp */,
|
||||
F4C07F572AB08E690044EDC0 /* unicode.cpp */,
|
||||
F4C07F502AB059580044EDC0 /* pch.h */,
|
||||
F4C07F532AB05A240044EDC0 /* compat.hpp */,
|
||||
F4B7FBDD2AAF49BC00C6BE9F /* Products */,
|
||||
);
|
||||
sourceTree = "<group>";
|
||||
@ -58,16 +74,6 @@
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
F4B7FBDE2AAF49BC00C6BE9F /* UnitTests */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
F48105AE2AAF64C7004DE682 /* common.hpp */,
|
||||
F48105AC2AAF5FD4004DE682 /* math.hpp */,
|
||||
F4B7FBDF2AAF49BC00C6BE9F /* main.cpp */,
|
||||
);
|
||||
path = UnitTests;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXGroup section */
|
||||
|
||||
/* Begin PBXNativeTarget section */
|
||||
@ -125,8 +131,8 @@
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
F4B7FBE02AAF49BC00C6BE9F /* main.cpp in Sources */,
|
||||
F48105AD2AAF5FD4004DE682 /* math.hpp in Sources */,
|
||||
F4C07F552AB05B5B0044EDC0 /* main.cpp in Sources */,
|
||||
F4C07F522AB059580044EDC0 /* pch.cpp in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
@ -184,10 +190,11 @@
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
HEADER_SEARCH_PATHS = ../include;
|
||||
MACOSX_DEPLOYMENT_TARGET = "$(RECOMMENDED_MACOSX_DEPLOYMENT_TARGET)";
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.15;
|
||||
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
|
||||
MTL_FAST_MATH = YES;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
OTHER_LDFLAGS = "-liconv";
|
||||
SDKROOT = macosx;
|
||||
};
|
||||
name = Debug;
|
||||
@ -237,9 +244,10 @@
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
HEADER_SEARCH_PATHS = ../include;
|
||||
MACOSX_DEPLOYMENT_TARGET = "$(RECOMMENDED_MACOSX_DEPLOYMENT_TARGET)";
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.15;
|
||||
MTL_ENABLE_DEBUG_INFO = NO;
|
||||
MTL_FAST_MATH = YES;
|
||||
OTHER_LDFLAGS = "-liconv";
|
||||
SDKROOT = macosx;
|
||||
};
|
||||
name = Release;
|
77
UnitTests/compat.hpp
Normal file
77
UnitTests/compat.hpp
Normal file
@ -0,0 +1,77 @@
|
||||
/*
|
||||
SPDX-License-Identifier: MIT
|
||||
Copyright © 2023 Amebis
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#if defined(_WIN32)
|
||||
#include <CppUnitTest.h>
|
||||
#elif defined(__APPLE__)
|
||||
#include <stdexcept>
|
||||
|
||||
#define TEST_CLASS(name) class name
|
||||
#define TEST_METHOD(name) static void name()
|
||||
|
||||
namespace Assert
|
||||
{
|
||||
inline void IsTrue(bool c)
|
||||
{
|
||||
if (!c)
|
||||
throw std::runtime_error("not true");
|
||||
}
|
||||
|
||||
inline void IsFalse(bool c)
|
||||
{
|
||||
if (c)
|
||||
throw std::runtime_error("not false");
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline void AreEqual(const T& a, const T& b)
|
||||
{
|
||||
if (!(a == b))
|
||||
throw std::runtime_error("not equal");
|
||||
}
|
||||
|
||||
inline void AreEqual(const char* a, const char* b)
|
||||
{
|
||||
if (strcmp(a, b) != 0)
|
||||
throw std::runtime_error("not equal");
|
||||
}
|
||||
|
||||
inline void AreEqual(const wchar_t* a, const wchar_t* b)
|
||||
{
|
||||
if (wcscmp(a, b) != 0)
|
||||
throw std::runtime_error("not equal");
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline void AreNotEqual(const T& a, const T& b)
|
||||
{
|
||||
if (a == b)
|
||||
throw std::runtime_error("equal");
|
||||
}
|
||||
|
||||
inline void AreNotEqual(const char* a, const char* b)
|
||||
{
|
||||
if (strcmp(a, b) == 0)
|
||||
throw std::runtime_error("equal");
|
||||
}
|
||||
|
||||
inline void AreNotEqual(const wchar_t* a, const wchar_t* b)
|
||||
{
|
||||
if (wcscmp(a, b) == 0)
|
||||
throw std::runtime_error("equal");
|
||||
}
|
||||
|
||||
template <class E, typename F>
|
||||
inline void ExpectException(F functor)
|
||||
{
|
||||
try { functor(); }
|
||||
catch (const E&) { return; }
|
||||
catch (...) { throw std::runtime_error("unexpected exception"); }
|
||||
throw std::runtime_error("exception not thrown");
|
||||
}
|
||||
}
|
||||
#endif
|
38
UnitTests/main.cpp
Normal file
38
UnitTests/main.cpp
Normal file
@ -0,0 +1,38 @@
|
||||
/*
|
||||
SPDX-License-Identifier: MIT
|
||||
Copyright © 2023 Amebis
|
||||
*/
|
||||
|
||||
#include "pch.h"
|
||||
#include "math.cpp"
|
||||
#include "parser.cpp"
|
||||
#include "ring.cpp"
|
||||
#include "sgml.cpp"
|
||||
#include "stream.cpp"
|
||||
#include "unicode.cpp"
|
||||
#include <iostream>
|
||||
|
||||
int main(int argc, const char * argv[])
|
||||
{
|
||||
try {
|
||||
UnitTests::math::mul();
|
||||
UnitTests::math::add();
|
||||
UnitTests::parser::wtest();
|
||||
UnitTests::parser::sgml_test();
|
||||
UnitTests::parser::http_test();
|
||||
UnitTests::ring::test();
|
||||
UnitTests::sgml::sgml2wstr();
|
||||
UnitTests::sgml::wstr2sgml();
|
||||
UnitTests::stream::async();
|
||||
UnitTests::stream::replicator();
|
||||
UnitTests::stream::open_close();
|
||||
UnitTests::unicode::str2wstr();
|
||||
UnitTests::unicode::wstr2str();
|
||||
std::cout << "PASS\n";
|
||||
return 0;
|
||||
}
|
||||
catch (const std::exception& ex) {
|
||||
std::cerr << ex.what() << " FAIL\n";
|
||||
return 1;
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
/*
|
||||
/*
|
||||
SPDX-License-Identifier: MIT
|
||||
Copyright © 2023 Amebis
|
||||
*/
|
||||
@ -6,7 +6,9 @@
|
||||
#include "pch.h"
|
||||
|
||||
using namespace std;
|
||||
#ifdef _WIN32
|
||||
using namespace Microsoft::VisualStudio::CppUnitTestFramework;
|
||||
#endif
|
||||
|
||||
namespace UnitTests
|
||||
{
|
@ -1,4 +1,4 @@
|
||||
/*
|
||||
/*
|
||||
SPDX-License-Identifier: MIT
|
||||
Copyright © 2023 Amebis
|
||||
*/
|
||||
@ -8,7 +8,9 @@
|
||||
using namespace std;
|
||||
using namespace stdex;
|
||||
using namespace stdex::parser;
|
||||
#ifdef _WIN32
|
||||
using namespace Microsoft::VisualStudio::CppUnitTestFramework;
|
||||
#endif
|
||||
|
||||
namespace UnitTests
|
||||
{
|
||||
@ -176,6 +178,7 @@ namespace UnitTests
|
||||
|
||||
TEST_METHOD(sgml_test)
|
||||
{
|
||||
std::locale locale_slSI("sl_SI");
|
||||
static const char text[] = "V kožuščku zlobnega mizarja stopiclja fant\nin kliče 1234567890.";
|
||||
|
||||
{
|
||||
@ -194,7 +197,7 @@ namespace UnitTests
|
||||
}
|
||||
|
||||
{
|
||||
sgml_cp p("Ž");
|
||||
sgml_cp p("Ž", SIZE_MAX, false, locale_slSI);
|
||||
Assert::IsFalse(p.match(text, 4));
|
||||
Assert::IsTrue(p.match(text, 4, _countof(text), match_case_insensitive));
|
||||
Assert::AreEqual((size_t)4, p.interval.start);
|
||||
@ -202,7 +205,7 @@ namespace UnitTests
|
||||
}
|
||||
|
||||
{
|
||||
sgml_space_cp p;
|
||||
sgml_space_cp p(false, locale_slSI);
|
||||
Assert::IsFalse(p.match(text));
|
||||
Assert::IsTrue(p.match(text, 1));
|
||||
Assert::AreEqual((size_t)1, p.interval.start);
|
||||
@ -213,7 +216,7 @@ namespace UnitTests
|
||||
}
|
||||
|
||||
{
|
||||
sgml_string_branch p("apple", "orange", "KoŽuŠčKu", nullptr);
|
||||
sgml_string_branch p(locale_slSI, "apple", "orange", "KoŽuŠčKu", nullptr);
|
||||
Assert::IsFalse(p.match(text, 2));
|
||||
Assert::IsTrue(p.match(text, 2, _countof(text), match_case_insensitive));
|
||||
Assert::AreEqual((size_t)2, p.hit_offset);
|
@ -6,6 +6,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdex/base64.hpp>
|
||||
#include <stdex/compat.hpp>
|
||||
#include <stdex/errno.hpp>
|
||||
#include <stdex/exception.hpp>
|
||||
#include <stdex/hex.hpp>
|
||||
@ -16,7 +17,6 @@
|
||||
#include <stdex/parser.hpp>
|
||||
#include <stdex/progress.hpp>
|
||||
#include <stdex/ring.hpp>
|
||||
#include <stdex/sal.hpp>
|
||||
#include <stdex/sgml.hpp>
|
||||
#include <stdex/stream.hpp>
|
||||
#include <stdex/string.hpp>
|
||||
@ -24,7 +24,7 @@
|
||||
#include <stdex/unicode.hpp>
|
||||
#include <stdex/vector_queue.hpp>
|
||||
|
||||
#include <CppUnitTest.h>
|
||||
#include "compat.hpp"
|
||||
|
||||
#include <cstdlib>
|
||||
#include <filesystem>
|
@ -1,4 +1,4 @@
|
||||
/*
|
||||
/*
|
||||
SPDX-License-Identifier: MIT
|
||||
Copyright © 2023 Amebis
|
||||
*/
|
||||
@ -6,7 +6,9 @@
|
||||
#include "pch.h"
|
||||
|
||||
using namespace std;
|
||||
#ifdef _WIN32
|
||||
using namespace Microsoft::VisualStudio::CppUnitTestFramework;
|
||||
#endif
|
||||
|
||||
namespace UnitTests
|
||||
{
|
@ -1,4 +1,4 @@
|
||||
/*
|
||||
/*
|
||||
SPDX-License-Identifier: MIT
|
||||
Copyright © 2023 Amebis
|
||||
*/
|
||||
@ -6,7 +6,9 @@
|
||||
#include "pch.h"
|
||||
|
||||
using namespace std;
|
||||
#ifdef _WIN32
|
||||
using namespace Microsoft::VisualStudio::CppUnitTestFramework;
|
||||
#endif
|
||||
|
||||
namespace UnitTests
|
||||
{
|
||||
@ -38,9 +40,15 @@ namespace UnitTests
|
||||
{ i + 35, j + 12 },
|
||||
{ i + 42, j + 14 },
|
||||
{ i + 53, j + 25 },
|
||||
#ifdef _WIN32 // wchar_t* is UTF-16
|
||||
{ i + 62, j + 27 },
|
||||
{ i + 62, j + 27 },
|
||||
{ i + 71, j + 29 },
|
||||
#else // wchar_t* is UTF-32
|
||||
{ i + 62, j + 26 },
|
||||
{ i + 62, j + 26 },
|
||||
{ i + 71, j + 27 },
|
||||
#endif
|
||||
} == map);
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
/*
|
||||
/*
|
||||
SPDX-License-Identifier: MIT
|
||||
Copyright © 2023 Amebis
|
||||
*/
|
||||
@ -8,7 +8,9 @@
|
||||
using namespace std;
|
||||
using namespace stdex;
|
||||
using namespace stdex::stream;
|
||||
#ifdef _WIN32
|
||||
using namespace Microsoft::VisualStudio::CppUnitTestFramework;
|
||||
#endif
|
||||
|
||||
namespace UnitTests
|
||||
{
|
||||
@ -17,11 +19,11 @@ namespace UnitTests
|
||||
public:
|
||||
TEST_METHOD(async)
|
||||
{
|
||||
constexpr size_t total = 1000;
|
||||
memory_file source(mul(total, sizeof(size_t)));
|
||||
constexpr uint32_t total = 1000;
|
||||
memory_file source(mul(total, sizeof(uint32_t)));
|
||||
{
|
||||
async_writer<70> writer(source);
|
||||
for (size_t i = 0; i < total; ++i) {
|
||||
for (uint32_t i = 0; i < total; ++i) {
|
||||
Assert::IsTrue(writer.ok());
|
||||
writer << i;
|
||||
}
|
||||
@ -29,8 +31,8 @@ namespace UnitTests
|
||||
Assert::AreEqual<stdex::stream::fpos_t>(0, source.seekbeg(0));
|
||||
{
|
||||
async_reader<50> reader(source);
|
||||
size_t x;
|
||||
for (size_t i = 0; i < total; ++i) {
|
||||
uint32_t x;
|
||||
for (uint32_t i = 0; i < total; ++i) {
|
||||
reader >> x;
|
||||
Assert::IsTrue(reader.ok());
|
||||
Assert::AreEqual(i, x);
|
||||
@ -42,9 +44,9 @@ namespace UnitTests
|
||||
|
||||
TEST_METHOD(replicator)
|
||||
{
|
||||
constexpr size_t total = 1000;
|
||||
constexpr uint32_t total = 1000;
|
||||
|
||||
memory_file f1(mul(total, sizeof(size_t)));
|
||||
memory_file f1(mul(total, sizeof(uint32_t)));
|
||||
|
||||
sstring filename2, filename3;
|
||||
filename2 = filename3 = temp_path();
|
||||
@ -65,7 +67,7 @@ namespace UnitTests
|
||||
writer.push_back(&f1);
|
||||
writer.push_back(&f2_buf);
|
||||
writer.push_back(&f3);
|
||||
for (size_t i = 0; i < total; ++i) {
|
||||
for (uint32_t i = 0; i < total; ++i) {
|
||||
Assert::IsTrue(writer.ok());
|
||||
writer << i;
|
||||
}
|
||||
@ -76,8 +78,8 @@ namespace UnitTests
|
||||
f3.seekbeg(0);
|
||||
{
|
||||
buffer f2_buf(f2, 64, 0);
|
||||
size_t x;
|
||||
for (size_t i = 0; i < total; ++i) {
|
||||
uint32_t x;
|
||||
for (uint32_t i = 0; i < total; ++i) {
|
||||
f1 >> x;
|
||||
Assert::IsTrue(f1.ok());
|
||||
Assert::AreEqual(i, x);
|
||||
@ -106,26 +108,26 @@ namespace UnitTests
|
||||
{
|
||||
cached_file dat(invalid_handle, state_t::fail, 4096);
|
||||
const sstring filepath = temp_path();
|
||||
constexpr size_t count = 3;
|
||||
constexpr uint32_t count = 3;
|
||||
sstring filename[count];
|
||||
stdex::stream::fpos_t start[count];
|
||||
for (size_t i = 0; i < count; ++i) {
|
||||
for (uint32_t i = 0; i < count; ++i) {
|
||||
filename[i] = filepath + sprintf(_T("stdex-stream-open_close%zu.tmp"), NULL, i);
|
||||
dat.open(filename[i].c_str(), mode_for_reading | mode_for_writing | share_none | mode_preserve_existing | mode_binary);
|
||||
Assert::IsTrue(dat.ok());
|
||||
start[i] = dat.tell();
|
||||
Assert::AreNotEqual(fpos_max, start[i]);
|
||||
for (size_t j = 0; j < 31 + 11 * i; ++j) {
|
||||
for (uint32_t j = 0; j < 31 + 11 * i; ++j) {
|
||||
dat << j * count + i;
|
||||
Assert::IsTrue(dat.ok());
|
||||
}
|
||||
dat.close();
|
||||
}
|
||||
for (size_t i = 0; i < count; ++i) {
|
||||
for (uint32_t i = 0; i < count; ++i) {
|
||||
dat.open(filename[i].c_str(), mode_for_reading | share_none | mode_binary);
|
||||
Assert::IsTrue(dat.ok());
|
||||
for (;;) {
|
||||
size_t x;
|
||||
uint32_t x;
|
||||
dat >> x;
|
||||
if (!dat.ok())
|
||||
break;
|
||||
@ -133,7 +135,7 @@ namespace UnitTests
|
||||
}
|
||||
}
|
||||
dat.close();
|
||||
for (size_t i = 0; i < count; ++i)
|
||||
for (uint32_t i = 0; i < count; ++i)
|
||||
std::filesystem::remove(filename[i]);
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
/*
|
||||
/*
|
||||
SPDX-License-Identifier: MIT
|
||||
Copyright © 2023 Amebis
|
||||
*/
|
||||
@ -6,7 +6,9 @@
|
||||
#include "pch.h"
|
||||
|
||||
using namespace std;
|
||||
#ifdef _WIN32
|
||||
using namespace Microsoft::VisualStudio::CppUnitTestFramework;
|
||||
#endif
|
||||
|
||||
namespace UnitTests
|
||||
{
|
@ -5,7 +5,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "sal.hpp"
|
||||
#include "compat.hpp"
|
||||
#include <assert.h>
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
@ -14,6 +14,35 @@
|
||||
|
||||
namespace stdex
|
||||
{
|
||||
/// \cond internal
|
||||
static const char base64_enc_lookup[64] = {
|
||||
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
|
||||
'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
|
||||
'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
|
||||
'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'
|
||||
};
|
||||
|
||||
static const uint8_t base64_dec_lookup[256] = {
|
||||
/* 0 1 2 3 4 5 6 7 8 9 A B C D E F */
|
||||
/* 0 */ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
/* 1 */ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
/* 2 */ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 62, 255, 255, 255, 63,
|
||||
/* 3 */ 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 255, 255, 255, 64, 255, 255,
|
||||
/* 4 */ 255, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
|
||||
/* 5 */ 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 255, 255, 255, 255, 255,
|
||||
/* 6 */ 255, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
|
||||
/* 7 */ 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 255, 255, 255, 255, 255,
|
||||
/* 8 */ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
/* 9 */ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
/* A */ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
/* B */ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
/* C */ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
/* D */ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
/* E */ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
/* F */ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255
|
||||
};
|
||||
/// \endcond
|
||||
|
||||
///
|
||||
/// Base64 encoding session
|
||||
///
|
||||
@ -140,17 +169,6 @@ namespace stdex
|
||||
size_t num; ///< Number of bytes used in `buf`
|
||||
};
|
||||
|
||||
|
||||
/// \cond internal
|
||||
static const char base64_enc_lookup[64] = {
|
||||
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
|
||||
'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
|
||||
'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
|
||||
'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'
|
||||
};
|
||||
/// \endcond
|
||||
|
||||
|
||||
///
|
||||
/// Base64 decoding session
|
||||
///
|
||||
@ -256,27 +274,4 @@ namespace stdex
|
||||
uint8_t buf[4]; ///< Internal buffer
|
||||
size_t num; ///< Number of bytes used in `buf`
|
||||
};
|
||||
|
||||
|
||||
/// \cond internal
|
||||
static const uint8_t base64_dec_lookup[256] = {
|
||||
/* 0 1 2 3 4 5 6 7 8 9 A B C D E F */
|
||||
/* 0 */ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
/* 1 */ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
/* 2 */ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 62, 255, 255, 255, 63,
|
||||
/* 3 */ 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 255, 255, 255, 64, 255, 255,
|
||||
/* 4 */ 255, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
|
||||
/* 5 */ 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 255, 255, 255, 255, 255,
|
||||
/* 6 */ 255, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
|
||||
/* 7 */ 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 255, 255, 255, 255, 255,
|
||||
/* 8 */ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
/* 9 */ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
/* A */ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
/* B */ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
/* C */ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
/* D */ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
/* E */ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
/* F */ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255
|
||||
};
|
||||
/// \endcond
|
||||
}
|
||||
|
@ -5,7 +5,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "sal.hpp"
|
||||
#include "compat.hpp"
|
||||
#include "system.hpp"
|
||||
#include "string.hpp"
|
||||
#include <stdint.h>
|
||||
|
@ -1,13 +1,15 @@
|
||||
/*
|
||||
/*
|
||||
SPDX-License-Identifier: MIT
|
||||
Copyright © 2022-2023 Amebis
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stddef.h>
|
||||
#ifdef _WIN32
|
||||
#include <sal.h>
|
||||
#endif
|
||||
#include <type_traits>
|
||||
|
||||
#ifndef _In_
|
||||
#define _In_
|
||||
@ -30,15 +32,24 @@
|
||||
#ifndef _In_z_
|
||||
#define _In_z_
|
||||
#endif
|
||||
#ifndef _In_opt_z_
|
||||
#define _In_opt_z_
|
||||
#endif
|
||||
#ifndef _In_z_count_
|
||||
#define _In_z_count_(p)
|
||||
#endif
|
||||
#ifndef _In_reads_
|
||||
#define _In_reads_(p)
|
||||
#endif
|
||||
#ifndef _In_reads_or_z_
|
||||
#define _In_reads_or_z_(p)
|
||||
#endif
|
||||
#ifndef _In_reads_or_z_opt_
|
||||
#define _In_reads_or_z_opt_(p)
|
||||
#endif
|
||||
#ifndef _In_reads_bytes_opt_
|
||||
#define _In_reads_bytes_opt_(p)
|
||||
#endif
|
||||
#ifndef _Printf_format_string_params_
|
||||
#define _Printf_format_string_params_(n)
|
||||
#endif
|
||||
@ -46,6 +57,12 @@
|
||||
#ifndef _Inout_
|
||||
#define _Inout_
|
||||
#endif
|
||||
#ifndef _Inout_opt_
|
||||
#define _Inout_opt_
|
||||
#endif
|
||||
#ifndef _Inout_cap_
|
||||
#define _Inout_cap_(p)
|
||||
#endif
|
||||
|
||||
#ifndef _Use_decl_annotations_
|
||||
#define _Use_decl_annotations_
|
||||
@ -57,19 +74,47 @@
|
||||
#ifndef _Out_opt_
|
||||
#define _Out_opt_
|
||||
#endif
|
||||
#ifndef _Out_z_cap_
|
||||
#define _Out_z_cap_(p)
|
||||
#endif
|
||||
#ifndef _Out_writes_
|
||||
#define _Out_writes_(p)
|
||||
#endif
|
||||
#ifndef _Out_writes_bytes_
|
||||
#define _Out_writes_bytes_(p)
|
||||
#endif
|
||||
#ifndef _Out_writes_z_
|
||||
#define _Out_writes_z_(p)
|
||||
#endif
|
||||
#ifndef _Out_writes_bytes_to_opt_
|
||||
#define _Out_writes_bytes_to_opt_(p, q)
|
||||
#endif
|
||||
|
||||
#ifndef _Success_
|
||||
#define _Success_(p)
|
||||
#endif
|
||||
#ifndef _Ret_maybenull_z_
|
||||
#define _Ret_maybenull_z_
|
||||
#endif
|
||||
#ifndef _Ret_notnull_
|
||||
#define _Ret_notnull_
|
||||
#endif
|
||||
#ifndef _Ret_z_
|
||||
#define _Ret_z_
|
||||
#endif
|
||||
#ifndef _Must_inspect_result_
|
||||
#define _Must_inspect_result_
|
||||
#endif
|
||||
#ifndef _Check_return_
|
||||
#define _Check_return_
|
||||
#endif
|
||||
#ifndef _Post_maybez_
|
||||
#define _Post_maybez_
|
||||
#endif
|
||||
|
||||
#ifndef _Analysis_assume_
|
||||
#define _Analysis_assume_(p)
|
||||
#endif
|
||||
|
||||
#ifndef _Likely_
|
||||
#if _HAS_CXX20
|
||||
@ -98,3 +143,19 @@
|
||||
#else
|
||||
#define _Unreferenced_(x)
|
||||
#endif
|
||||
|
||||
#ifndef _WIN32
|
||||
template <typename T, size_t N>
|
||||
size_t _countof(T (&arr)[N])
|
||||
{
|
||||
return std::extent<T[N]>::value;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef __APPLE__
|
||||
#define off64_t off_t
|
||||
#define lseek64 lseek
|
||||
#define lockf64 lockf
|
||||
#define ftruncate64 ftruncate
|
||||
#endif
|
||||
|
@ -1,67 +1,87 @@
|
||||
/*
|
||||
/*
|
||||
SPDX-License-Identifier: MIT
|
||||
Copyright © 2023 Amebis
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "sal.hpp"
|
||||
#include "compat.hpp"
|
||||
#include "system.hpp"
|
||||
#include <assert.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
#ifndef LITTLE_ENDIAN
|
||||
#define LITTLE_ENDIAN 1234
|
||||
#endif
|
||||
#ifndef BIG_ENDIAN
|
||||
#define BIG_ENDIAN 4321
|
||||
#endif
|
||||
#ifndef BYTE_ORDER
|
||||
#if defined(_WIN32)
|
||||
#if REG_DWORD == REG_DWORD_LITTLE_ENDIAN
|
||||
#define BYTE_ORDER LITTLE_ENDIAN
|
||||
#elif REG_DWORD == REG_DWORD_BIG_ENDIAN
|
||||
#define BIG_ENDIAN
|
||||
#else
|
||||
#error Unknown endian
|
||||
#define BYTE_ORDER BIG_ENDIAN
|
||||
#endif
|
||||
#elif defined(__APPLE__)
|
||||
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
|
||||
#define BYTE_ORDER LITTLE_ENDIAN
|
||||
#elif __BYTE_ORDER == __ORDER_BIG_ENDIAN__
|
||||
#define BYTE_ORDER BIG_ENDIAN
|
||||
#endif
|
||||
#else
|
||||
#include <endian.h>
|
||||
#if __BYTE_ORDER == __LITTLE_ENDIAN
|
||||
#define BYTE_ORDER LITTLE_ENDIAN
|
||||
#elif __BYTE_ORDER == __BIG_ENDIAN
|
||||
#define BIG_ENDIAN
|
||||
#else
|
||||
#define BYTE_ORDER BIG_ENDIAN
|
||||
#endif
|
||||
#endif
|
||||
#ifndef BYTE_ORDER
|
||||
#error Unknown endian
|
||||
#endif
|
||||
#endif
|
||||
|
||||
namespace stdex
|
||||
{
|
||||
inline uint8_t byteswap(_In_ const uint8_t value)
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
inline uint16_t byteswap(_In_ const uint16_t value)
|
||||
{
|
||||
#if _MSC_VER >= 1300
|
||||
#if _MSC_VER >= 1300
|
||||
return _byteswap_ushort(value);
|
||||
#elif defined(_MSC_VER)
|
||||
#elif defined(_MSC_VER)
|
||||
uint16_t t = (value & 0x00ff) << 8;
|
||||
t |= (value) >> 8;
|
||||
return t;
|
||||
#else
|
||||
#else
|
||||
return __builtin_bswap16(value);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
inline uint32_t byteswap(_In_ const uint32_t value)
|
||||
{
|
||||
#if _MSC_VER >= 1300
|
||||
#if _MSC_VER >= 1300
|
||||
return _byteswap_ulong(value);
|
||||
#elif defined(_MSC_VER)
|
||||
#elif defined(_MSC_VER)
|
||||
uint32_t t = (value & 0x000000ff) << 24;
|
||||
t |= (value & 0x0000ff00) << 8;
|
||||
t |= (value & 0x00ff0000) >> 8;
|
||||
t |= (value) >> 24;
|
||||
return t;
|
||||
#else
|
||||
#else
|
||||
return __builtin_bswap32(value);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
inline uint64_t byteswap(_In_ const uint64_t value)
|
||||
{
|
||||
#if _MSC_VER >= 1300
|
||||
#if _MSC_VER >= 1300
|
||||
return _byteswap_uint64(value);
|
||||
#elif defined(_MSC_VER)
|
||||
#elif defined(_MSC_VER)
|
||||
uint64_t t = (value & 0x00000000000000ff) << 56;
|
||||
t |= (value & 0x000000000000ff00) << 40;
|
||||
t |= (value & 0x0000000000ff0000) << 24;
|
||||
@ -71,25 +91,34 @@ namespace stdex
|
||||
t |= (value & 0x00ff000000000000) >> 40;
|
||||
t |= (value) >> 56;
|
||||
return t;
|
||||
#else
|
||||
#else
|
||||
return __builtin_bswap64(value);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
inline int16_t byteswap(_In_ const int16_t value) { return byteswap((uint16_t)value); }
|
||||
inline int32_t byteswap(_In_ const int32_t value) { return byteswap((uint32_t)value); }
|
||||
inline int64_t byteswap(_In_ const int64_t value) { return byteswap((uint64_t)value); }
|
||||
inline int8_t byteswap(_In_ const char value) { return byteswap(static_cast<uint8_t>(value)); }
|
||||
inline int8_t byteswap(_In_ const int8_t value) { return byteswap(static_cast<uint8_t>(value)); }
|
||||
inline int16_t byteswap(_In_ const int16_t value) { return byteswap(static_cast<uint16_t>(value)); }
|
||||
inline int32_t byteswap(_In_ const int32_t value) { return byteswap(static_cast<uint32_t>(value)); }
|
||||
inline int64_t byteswap(_In_ const int64_t value) { return byteswap(static_cast<uint64_t>(value)); }
|
||||
inline float byteswap(_In_ const float value) { return byteswap(*reinterpret_cast<const uint32_t*>(&value)); }
|
||||
inline double byteswap(_In_ const double value) { return byteswap(*reinterpret_cast<const uint64_t*>(&value)); }
|
||||
|
||||
inline void byteswap(_Inout_ uint8_t* value) { assert(value); *value = byteswap(*value); }
|
||||
inline void byteswap(_Inout_ uint16_t* value) { assert(value); *value = byteswap(*value); }
|
||||
inline void byteswap(_Inout_ uint32_t* value) { assert(value); *value = byteswap(*value); }
|
||||
inline void byteswap(_Inout_ uint64_t* value) { assert(value); *value = byteswap(*value); }
|
||||
|
||||
inline void byteswap(_Inout_ int16_t* value) { byteswap((uint16_t*)value); }
|
||||
inline void byteswap(_Inout_ int32_t* value) { byteswap((uint32_t*)value); }
|
||||
inline void byteswap(_Inout_ int64_t* value) { byteswap((uint64_t*)value); }
|
||||
inline void byteswap(_Inout_ char* value) { byteswap(reinterpret_cast<uint8_t*>(value)); }
|
||||
inline void byteswap(_Inout_ int8_t* value) { byteswap(reinterpret_cast<uint8_t*>(value)); }
|
||||
inline void byteswap(_Inout_ int16_t* value) { byteswap(reinterpret_cast<uint16_t*>(value)); }
|
||||
inline void byteswap(_Inout_ int32_t* value) { byteswap(reinterpret_cast<uint32_t*>(value)); }
|
||||
inline void byteswap(_Inout_ int64_t* value) { byteswap(reinterpret_cast<uint64_t*>(value)); }
|
||||
inline void byteswap(_Inout_ float* value) { byteswap(reinterpret_cast<uint32_t*>(value)); }
|
||||
inline void byteswap(_Inout_ double* value) { byteswap(reinterpret_cast<uint64_t*>(value)); }
|
||||
}
|
||||
|
||||
#ifdef BIG_ENDIAN
|
||||
#if BYTE_ORDER == BIG_ENDIAN
|
||||
#define LE2HE(x) stdex::byteswap(x)
|
||||
#define BE2HE(x) (x)
|
||||
#define HE2LE(x) stdex::byteswap(x)
|
||||
|
@ -5,7 +5,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "sal.hpp"
|
||||
#include "compat.hpp"
|
||||
#include <stdexcept>
|
||||
#include <cstring>
|
||||
|
||||
|
@ -1,11 +1,11 @@
|
||||
/*
|
||||
/*
|
||||
SPDX-License-Identifier: MIT
|
||||
Copyright © 2023 Amebis
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "sal.hpp"
|
||||
#include "compat.hpp"
|
||||
#include <exception>
|
||||
|
||||
namespace stdex
|
||||
@ -13,7 +13,7 @@ namespace stdex
|
||||
///
|
||||
/// User cancelled exception
|
||||
///
|
||||
class user_cancelled : public std::exception
|
||||
class user_cancelled : public std::runtime_error
|
||||
{
|
||||
public:
|
||||
///
|
||||
@ -21,8 +21,8 @@ namespace stdex
|
||||
///
|
||||
/// \param[in] msg Error message
|
||||
///
|
||||
user_cancelled(_In_opt_z_ const char *msg = nullptr) : exception(msg)
|
||||
user_cancelled(_In_opt_z_ const char *msg = nullptr) : runtime_error(msg)
|
||||
{
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -5,7 +5,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "sal.hpp"
|
||||
#include "compat.hpp"
|
||||
#include <assert.h>
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
|
@ -5,7 +5,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "sal.hpp"
|
||||
#include "compat.hpp"
|
||||
#include "stream.hpp"
|
||||
#include <ios>
|
||||
#include <istream>
|
||||
|
@ -1,11 +1,11 @@
|
||||
/*
|
||||
/*
|
||||
SPDX-License-Identifier: MIT
|
||||
Copyright © 2023 Amebis
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "sal.hpp"
|
||||
#include "compat.hpp"
|
||||
#include <vector>
|
||||
|
||||
namespace stdex
|
||||
@ -78,7 +78,7 @@ namespace stdex
|
||||
/// Adds two intervals by components
|
||||
///
|
||||
/// \param[in] a First interval
|
||||
/// \param[in] a Second interval
|
||||
/// \param[in] b Second interval
|
||||
///
|
||||
/// \returns Resulting interval
|
||||
///
|
||||
@ -137,7 +137,7 @@ inline stdex::interval<T> operator++(_Inout_ stdex::interval<T>& i, int) // Post
|
||||
/// Subtracts two intervals by components
|
||||
///
|
||||
/// \param[in] a First interval
|
||||
/// \param[in] a Second interval
|
||||
/// \param[in] b Second interval
|
||||
///
|
||||
/// \returns Resulting interval
|
||||
///
|
||||
|
@ -5,7 +5,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "sal.hpp"
|
||||
#include "compat.hpp"
|
||||
#include <vector>
|
||||
|
||||
namespace stdex
|
||||
|
@ -5,7 +5,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "sal.hpp"
|
||||
#include "compat.hpp"
|
||||
#include "system.hpp"
|
||||
#include <stdexcept>
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/*
|
||||
/*
|
||||
SPDX-License-Identifier: MIT
|
||||
Copyright © 2023 Amebis
|
||||
*/
|
||||
@ -19,7 +19,7 @@ namespace stdex
|
||||
template <class T2, std::enable_if_t<std::is_convertible_v<T2*, T*>, int> = 0>
|
||||
inline no_delete(const no_delete<T2>&) noexcept {}
|
||||
|
||||
inline void operator()(T* p) const noexcept { p; }
|
||||
inline void operator()(T* p) const noexcept { _Unreferenced_(p); }
|
||||
};
|
||||
|
||||
///
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,11 +1,11 @@
|
||||
/*
|
||||
/*
|
||||
SPDX-License-Identifier: MIT
|
||||
Copyright © 2023 Amebis
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "sal.hpp"
|
||||
#include "compat.hpp"
|
||||
#include "interval.hpp"
|
||||
#include <chrono>
|
||||
|
||||
@ -25,7 +25,7 @@ namespace stdex
|
||||
///
|
||||
virtual void set_text(_In_z_ const char* msg)
|
||||
{
|
||||
msg;
|
||||
_Unreferenced_(msg);
|
||||
}
|
||||
|
||||
///
|
||||
@ -56,7 +56,7 @@ namespace stdex
|
||||
///
|
||||
virtual void show(_In_ bool show = true)
|
||||
{
|
||||
show;
|
||||
_Unreferenced_(show);
|
||||
}
|
||||
|
||||
///
|
||||
@ -168,7 +168,7 @@ namespace stdex
|
||||
///
|
||||
inline progress<T>* detach()
|
||||
{
|
||||
progress* k = m_host;
|
||||
progress<T>* k = m_host;
|
||||
m_host = NULL;
|
||||
return k;
|
||||
}
|
||||
@ -258,7 +258,7 @@ namespace stdex
|
||||
}
|
||||
|
||||
protected:
|
||||
progress* m_host;
|
||||
progress<T>* m_host;
|
||||
interval<T> m_local, m_global, m_section;
|
||||
};
|
||||
|
||||
@ -281,10 +281,10 @@ namespace stdex
|
||||
|
||||
~progress_switcher()
|
||||
{
|
||||
m_host_ref = detach();
|
||||
m_host_ref = this->detach();
|
||||
}
|
||||
|
||||
protected:
|
||||
progress<T>*& m_host_ref;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -5,7 +5,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "sal.hpp"
|
||||
#include "compat.hpp"
|
||||
#include <assert.h>
|
||||
#include <condition_variable>
|
||||
#include <mutex>
|
||||
|
@ -1,12 +1,12 @@
|
||||
/*
|
||||
/*
|
||||
SPDX-License-Identifier: MIT
|
||||
Copyright © 2023 Amebis
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "compat.hpp"
|
||||
#include "mapping.hpp"
|
||||
#include "sal.hpp"
|
||||
#include "sgml_unicode.hpp"
|
||||
#include "string.hpp"
|
||||
#include <assert.h>
|
||||
@ -173,7 +173,8 @@ namespace stdex
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline _Deprecated_("Use stdex::sgml2wstrcat") void sgml2wstr(
|
||||
_Deprecated_("Use stdex::sgml2wstrcat")
|
||||
inline void sgml2wstr(
|
||||
_Inout_ std::wstring& dst,
|
||||
_In_reads_or_z_opt_(count_src) const T* src, _In_ size_t count_src,
|
||||
_In_ int skip = 0,
|
||||
@ -192,8 +193,6 @@ namespace stdex
|
||||
/// \param[in] offset Logical starting offset of source and destination strings. Unused when map parameter is nullptr.
|
||||
/// \param[in,out] map The vector to append index mapping between source and destination string to.
|
||||
///
|
||||
/// \return Unicode string
|
||||
///
|
||||
template <class T>
|
||||
inline void sgml2wstrcat(
|
||||
_Inout_ std::wstring& dst,
|
||||
@ -206,7 +205,8 @@ namespace stdex
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline _Deprecated_("Use stdex::sgml2wstrcat") void sgml2wstr(
|
||||
_Deprecated_("Use stdex::sgml2wstrcat")
|
||||
inline void sgml2wstr(
|
||||
_Inout_ std::wstring& dst,
|
||||
_In_ const std::basic_string<T>& src,
|
||||
_In_ int skip = 0,
|
||||
@ -324,7 +324,8 @@ namespace stdex
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline _Deprecated_("Use stdex::sgml2wstrcat") size_t sgml2wstr(
|
||||
_Deprecated_("Use stdex::sgml2wstrcat")
|
||||
inline size_t sgml2wstr(
|
||||
_Inout_cap_(count_dst) wchar_t* dst, _In_ size_t count_dst,
|
||||
_In_reads_or_z_opt_(count_src) const T* src, _In_ size_t count_src,
|
||||
_In_ int skip = 0,
|
||||
@ -582,7 +583,8 @@ namespace stdex
|
||||
}
|
||||
}
|
||||
|
||||
inline _Deprecated_("Use stdex::wstr2sgmlcat") void wstr2sgml(
|
||||
_Deprecated_("Use stdex::wstr2sgmlcat")
|
||||
inline void wstr2sgml(
|
||||
_Inout_ std::string& dst,
|
||||
_In_reads_or_z_opt_(count_src) const wchar_t* src, _In_ size_t count_src,
|
||||
_In_ size_t what = 0)
|
||||
@ -605,7 +607,8 @@ namespace stdex
|
||||
wstr2sgmlcat(dst, src.c_str(), src.size(), what);
|
||||
}
|
||||
|
||||
inline _Deprecated_("Use stdex::wstr2sgmlcat") void wstr2sgml(
|
||||
_Deprecated_("Use stdex::wstr2sgmlcat")
|
||||
inline void wstr2sgml(
|
||||
_Inout_ std::string& dst,
|
||||
_In_ const std::wstring& src,
|
||||
_In_ size_t what = 0)
|
||||
@ -745,7 +748,8 @@ namespace stdex
|
||||
return j;
|
||||
}
|
||||
|
||||
inline _Deprecated_("Use stdex::wstr2sgmlcat") size_t wstr2sgml(
|
||||
_Deprecated_("Use stdex::wstr2sgmlcat")
|
||||
inline size_t wstr2sgml(
|
||||
_Inout_cap_(count_dst) char* dst, _In_ size_t count_dst,
|
||||
_In_reads_or_z_opt_(count_src) const wchar_t* src, _In_ size_t count_src,
|
||||
_In_ size_t what = 0)
|
||||
|
@ -1,15 +1,15 @@
|
||||
/*
|
||||
/*
|
||||
SPDX-License-Identifier: MIT
|
||||
Copyright © 2023 Amebis
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "compat.hpp"
|
||||
#include "endian.hpp"
|
||||
#include "interval.hpp"
|
||||
#include "math.hpp"
|
||||
#include "ring.hpp"
|
||||
#include "sal.hpp"
|
||||
#include "string.hpp"
|
||||
#include "system.hpp"
|
||||
#include "unicode.hpp"
|
||||
@ -19,6 +19,10 @@
|
||||
#if defined(_WIN32)
|
||||
#include <asptlb.h>
|
||||
#include <objidl.h>
|
||||
#else
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#endif
|
||||
#include <chrono>
|
||||
#include <condition_variable>
|
||||
@ -254,7 +258,7 @@ namespace stdex
|
||||
return *this;
|
||||
}
|
||||
if (read_array(&data, sizeof(T), 1) == 1)
|
||||
LE2HE(&data);
|
||||
(void)LE2HE(&data);
|
||||
else {
|
||||
data = 0;
|
||||
if (ok())
|
||||
@ -279,7 +283,7 @@ namespace stdex
|
||||
{
|
||||
if (!ok()) _Unlikely_
|
||||
return *this;
|
||||
#ifdef BIG_ENDIAN
|
||||
#if BYTE_ORDER == BIG_ENDIAN
|
||||
T data_le = HE2LE(data);
|
||||
write(&data_le, sizeof(T));
|
||||
#else
|
||||
@ -630,10 +634,6 @@ namespace stdex
|
||||
inline basic& operator <<(_In_ const uint32_t data) { return write_data(data); }
|
||||
inline basic& operator >>(_Out_ uint64_t& data) { return read_data(data); }
|
||||
inline basic& operator <<(_In_ const uint64_t data) { return write_data(data); }
|
||||
#if defined(_WIN64) && defined(_NATIVE_SIZE_T_DEFINED)
|
||||
inline basic& operator >>(_Out_ size_t& data) { return read_data(data); }
|
||||
inline basic& operator <<(_In_ const size_t data) { return write_data(data); }
|
||||
#endif
|
||||
inline basic& operator >>(_Out_ float& data) { return read_data(data); }
|
||||
inline basic& operator <<(_In_ const float data) { return write_data(data); }
|
||||
inline basic& operator >>(_Out_ double& data) { return read_data(data); }
|
||||
@ -683,10 +683,11 @@ namespace stdex
|
||||
};
|
||||
|
||||
#if _HAS_CXX20
|
||||
using time_point = std::chrono::time_point<std::chrono::file_clock>;
|
||||
using clock = std::chrono::file_clock;
|
||||
#else
|
||||
using time_point = std::chrono::time_point<std::chrono::system_clock>;
|
||||
using clock = std::chrono::system_clock;
|
||||
#endif
|
||||
using time_point = std::chrono::time_point<clock>;
|
||||
|
||||
///
|
||||
/// Basic seekable stream operations
|
||||
@ -755,7 +756,7 @@ namespace stdex
|
||||
{
|
||||
_Unreferenced_(offset);
|
||||
_Unreferenced_(length);
|
||||
throw std::exception("not implemented");
|
||||
throw std::domain_error("not implemented");
|
||||
}
|
||||
|
||||
///
|
||||
@ -765,7 +766,7 @@ namespace stdex
|
||||
{
|
||||
_Unreferenced_(offset);
|
||||
_Unreferenced_(length);
|
||||
throw std::exception("not implemented");
|
||||
throw std::domain_error("not implemented");
|
||||
}
|
||||
|
||||
///
|
||||
@ -809,7 +810,7 @@ namespace stdex
|
||||
virtual void set_ctime(time_point date)
|
||||
{
|
||||
_Unreferenced_(date);
|
||||
throw std::exception("not implemented");
|
||||
throw std::domain_error("not implemented");
|
||||
}
|
||||
|
||||
///
|
||||
@ -818,7 +819,7 @@ namespace stdex
|
||||
virtual void set_atime(time_point date)
|
||||
{
|
||||
_Unreferenced_(date);
|
||||
throw std::exception("not implemented");
|
||||
throw std::domain_error("not implemented");
|
||||
}
|
||||
|
||||
///
|
||||
@ -827,7 +828,7 @@ namespace stdex
|
||||
virtual void set_mtime(time_point date)
|
||||
{
|
||||
_Unreferenced_(date);
|
||||
throw std::exception("not implemented");
|
||||
throw std::domain_error("not implemented");
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
@ -855,7 +856,7 @@ namespace stdex
|
||||
///
|
||||
/// \param[in] default_charset Fallback charset to return when no BOM detected.
|
||||
///
|
||||
charset_id read_charset(_In_ charset_id default_charset = charset_id::default)
|
||||
charset_id read_charset(_In_ charset_id default_charset = charset_id::system)
|
||||
{
|
||||
if (seek(0) != 0)
|
||||
throw std::runtime_error("failed to seek");
|
||||
@ -1057,6 +1058,7 @@ namespace stdex
|
||||
case op_t::flush:
|
||||
w.source->flush();
|
||||
break;
|
||||
case op_t::noop:;
|
||||
}
|
||||
w.op = op_t::noop;
|
||||
lk.unlock();
|
||||
@ -2096,8 +2098,7 @@ namespace stdex
|
||||
}
|
||||
if (!succeeded) _Unlikely_
|
||||
#else
|
||||
ssize_t num_read = static_cast<ssize_t>(std::min<size_t>(to_read, block_size));
|
||||
num_read = read(m_h, data, num_read);
|
||||
ssize_t num_read = ::read(m_h, data, static_cast<ssize_t>(std::min<size_t>(to_read, block_size)));
|
||||
if (num_read < 0) _Unlikely_
|
||||
#endif
|
||||
{
|
||||
@ -2149,7 +2150,7 @@ namespace stdex
|
||||
return length - to_write;
|
||||
}
|
||||
#else
|
||||
ssize_t num_written = write(m_h, data, static_cast<ssize_t>(std::min<size_t>(to_write, block_size)));
|
||||
ssize_t num_written = ::write(m_h, data, static_cast<ssize_t>(std::min<size_t>(to_write, block_size)));
|
||||
if (num_written < 0) _Unlikely_ {
|
||||
m_state = state_t::fail;
|
||||
return length - to_write;
|
||||
@ -2487,13 +2488,18 @@ namespace stdex
|
||||
m_h = CreateFile(filename, dwDesiredAccess, dwShareMode, &sa, dwCreationDisposition, dwFlagsAndAttributes, nullptr);
|
||||
#else
|
||||
int flags = 0;
|
||||
if (mode & mode_for_reading) flags |= O_RDONLY;
|
||||
if (mode & mode_for_writing) flags |= O_WRONLY;
|
||||
switch (mode & (mode_for_reading | mode_for_writing)) {
|
||||
case mode_for_reading: flags |= O_RDONLY; break;
|
||||
case mode_for_writing: flags |= O_WRONLY; break;
|
||||
case mode_for_reading | mode_for_writing: flags |= O_RDWR; break;
|
||||
}
|
||||
if (mode & mode_create) flags |= mode & mode_preserve_existing ? O_CREAT : (O_CREAT | O_EXCL);
|
||||
if (mode & hint_write_thru) flags |= O_DSYNC;
|
||||
#ifndef __APPLE__
|
||||
if (mode & hint_no_buffering) flags |= O_RSYNC;
|
||||
#endif
|
||||
|
||||
m_h = open(filename, flags, DEFFILEMODE);
|
||||
m_h = ::open(filename, flags, DEFFILEMODE);
|
||||
#endif
|
||||
if (m_h != invalid_handle) {
|
||||
m_state = state_t::ok;
|
||||
@ -2515,7 +2521,7 @@ namespace stdex
|
||||
return li.QuadPart;
|
||||
}
|
||||
#else
|
||||
off64_t result = lseek64(m_h, offset, how);
|
||||
off64_t result = lseek64(m_h, offset, static_cast<int>(how));
|
||||
if (result >= 0) {
|
||||
m_state = state_t::ok;
|
||||
return result;
|
||||
@ -2667,8 +2673,8 @@ namespace stdex
|
||||
return ft2tp(ft);
|
||||
#else
|
||||
struct stat buf;
|
||||
if (fstat(m_h, &buf) >= 0);
|
||||
return time_point::from_time_t(buf.st_atim);
|
||||
if (fstat(m_h, &buf) >= 0)
|
||||
return clock::from_time_t(buf.st_atime);
|
||||
#endif
|
||||
return time_point::min();
|
||||
}
|
||||
@ -2682,7 +2688,7 @@ namespace stdex
|
||||
#else
|
||||
struct stat buf;
|
||||
if (fstat(m_h, &buf) >= 0)
|
||||
return time_point::from_time_t(buf.st_mtim);
|
||||
return clock::from_time_t(buf.st_mtime);
|
||||
#endif
|
||||
return time_point::min();
|
||||
}
|
||||
@ -2708,9 +2714,10 @@ namespace stdex
|
||||
if (SetFileTime(m_h, nullptr, &ft, nullptr))
|
||||
return;
|
||||
#else
|
||||
struct timespec ts[2];
|
||||
ts[0].tv_sec = date;
|
||||
ts[1].tv_nsec = UTIME_OMIT;
|
||||
struct timespec ts[2] = {
|
||||
{ date.time_since_epoch().count(), 0 },
|
||||
{ 0, UTIME_OMIT },
|
||||
};
|
||||
if (futimens(m_h, ts) >= 0)
|
||||
return;
|
||||
#endif
|
||||
@ -2725,9 +2732,10 @@ namespace stdex
|
||||
if (SetFileTime(m_h, nullptr, nullptr, &ft))
|
||||
return;
|
||||
#else
|
||||
struct timespec ts[2];
|
||||
ts[0].tv_nsec = UTIME_OMIT;
|
||||
ts[1].tv_sec = date;
|
||||
struct timespec ts[2] = {
|
||||
{ 0, UTIME_OMIT },
|
||||
{ date.time_since_epoch().count(), 0 },
|
||||
};
|
||||
if (futimens(m_h, ts) >= 0)
|
||||
return;
|
||||
#endif
|
||||
@ -2773,7 +2781,6 @@ namespace stdex
|
||||
///
|
||||
/// \param[in] filename Filename
|
||||
/// \param[in] mode Bitwise combination of mode_t flags
|
||||
/// \param[in] cache_size Size of the cache block
|
||||
///
|
||||
void open(_In_z_ const schar_t* filename, _In_ int mode)
|
||||
{
|
||||
@ -3077,7 +3084,7 @@ namespace stdex
|
||||
if (end_offset <= m_size) {
|
||||
uint32_t num_chars = LE2HE(*reinterpret_cast<uint32_t*>(m_data + m_offset));
|
||||
m_offset = end_offset;
|
||||
end_offset = stdex::add(m_offset + stdex::mul(num_chars, sizeof(_Elem)));
|
||||
end_offset = stdex::add(m_offset, stdex::mul(num_chars, sizeof(_Elem)));
|
||||
_Elem* start = reinterpret_cast<_Elem*>(m_data + m_offset);
|
||||
if (end_offset <= m_size) {
|
||||
data.assign(start, start + num_chars);
|
||||
@ -3208,7 +3215,7 @@ namespace stdex
|
||||
if (!ok()) _Unlikely_
|
||||
return *this;
|
||||
}
|
||||
auto p = tok.m_podatki + m_offset;
|
||||
auto p = m_data + m_offset;
|
||||
*reinterpret_cast<uint32_t*>(p) = HE2LE((uint32_t)num_chars);
|
||||
memcpy(p + sizeof(uint32_t), data, size_chars);
|
||||
m_offset = end_offset;
|
||||
@ -3384,9 +3391,6 @@ namespace stdex
|
||||
inline void set(_In_ fpos_t offset, _In_ const uint16_t data) { set<uint16_t>(offset, data); }
|
||||
inline void set(_In_ fpos_t offset, _In_ const uint32_t data) { set<uint32_t>(offset, data); }
|
||||
inline void set(_In_ fpos_t offset, _In_ const uint64_t data) { set<uint64_t>(offset, data); }
|
||||
#if defined(_WIN64) && defined(_NATIVE_SIZE_T_DEFINED)
|
||||
inline void set(_In_ fpos_t offset, _In_ const size_t data) { set<size_t>(offset, data); }
|
||||
#endif
|
||||
inline void set(_In_ fpos_t offset, _In_ const float data) { set<float>(offset, data); }
|
||||
inline void set(_In_ fpos_t offset, _In_ const double data) { set<double>(offset, data); }
|
||||
inline void set(_In_ fpos_t offset, _In_ const char data) { set<char>(offset, data); }
|
||||
@ -3421,9 +3425,6 @@ namespace stdex
|
||||
inline void get(_In_ fpos_t offset, _Out_ uint16_t & data) { get<uint16_t>(offset, data); }
|
||||
inline void get(_In_ fpos_t offset, _Out_ uint32_t & data) { get<uint32_t>(offset, data); }
|
||||
inline void get(_In_ fpos_t offset, _Out_ uint64_t & data) { get<uint64_t>(offset, data); }
|
||||
#if defined(_WIN64) && defined(_NATIVE_SIZE_T_DEFINED)
|
||||
inline void get(_In_ fpos_t offset, _Out_ size_t & data) { get<size_t>(offset, data); }
|
||||
#endif
|
||||
inline void get(_In_ fpos_t offset, _Out_ float& data) { get<float>(offset, data); }
|
||||
inline void get(_In_ fpos_t offset, _Out_ double& data) { get<double>(offset, data); }
|
||||
inline void get(_In_ fpos_t offset, _Out_ char& data) { get<char>(offset, data); }
|
||||
@ -3447,10 +3448,6 @@ namespace stdex
|
||||
inline memory_file& operator >>(_Out_ uint32_t & data) { return read_data(data); }
|
||||
inline memory_file& operator <<(_In_ const uint64_t data) { return write_data(data); }
|
||||
inline memory_file& operator >>(_Out_ uint64_t & data) { return read_data(data); }
|
||||
#if defined(_WIN64) && defined(_NATIVE_SIZE_T_DEFINED)
|
||||
inline memory_file& operator <<(_In_ const size_t data) { return write_data(data); }
|
||||
inline memory_file& operator >>(_Out_ size_t & data) { return read_data(data); }
|
||||
#endif
|
||||
inline memory_file& operator <<(_In_ const float data) { return write_data(data); }
|
||||
inline memory_file& operator >>(_Out_ float& data) { return read_data(data); }
|
||||
inline memory_file& operator <<(_In_ const double data) { return write_data(data); }
|
||||
|
@ -1,16 +1,22 @@
|
||||
/*
|
||||
/*
|
||||
SPDX-License-Identifier: MIT
|
||||
Copyright © 2016-2023 Amebis
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "sal.hpp"
|
||||
#include "compat.hpp"
|
||||
#include <assert.h>
|
||||
#include <ctype.h>
|
||||
#include <locale.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#ifdef __APPLE__
|
||||
#include <xlocale.h>
|
||||
#endif
|
||||
#include <locale>
|
||||
#include <memory>
|
||||
#include <stdexcept>
|
||||
|
||||
@ -36,19 +42,35 @@ namespace stdex
|
||||
///
|
||||
void operator()(_In_ locale_t locale) const
|
||||
{
|
||||
#ifdef _WIN32
|
||||
free_locale(locale);
|
||||
#else
|
||||
freelocale(locale);
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
///
|
||||
/// locale_t helper class to free_locale when going out of scope
|
||||
///
|
||||
#if defined(_WIN32)
|
||||
using locale = std::unique_ptr<__crt_locale_pointers, free_locale_delete>;
|
||||
#elif defined(__APPLE__)
|
||||
using locale = std::unique_ptr<struct _xlocale, free_locale_delete>;
|
||||
#else
|
||||
using locale = std::unique_ptr<struct __locale_struct, free_locale_delete>;
|
||||
#endif
|
||||
|
||||
///
|
||||
/// Reusable C locale
|
||||
///
|
||||
#if defined(_WIN32)
|
||||
static locale locale_C(_create_locale(LC_ALL, "C"));
|
||||
#elif defined(__APPLE__)
|
||||
static locale locale_C(newlocale(LC_ALL_MASK, "C", LC_GLOBAL_LOCALE));
|
||||
#else
|
||||
#error TODO
|
||||
#endif
|
||||
|
||||
///
|
||||
/// UTF-16 code unit
|
||||
@ -124,10 +146,10 @@ namespace stdex
|
||||
inline bool iscombining(_In_ char32_t chr)
|
||||
{
|
||||
return
|
||||
0x0300 <= chr && chr < 0x0370 ||
|
||||
0x1dc0 <= chr && chr < 0x1e00 ||
|
||||
0x20d0 <= chr && chr < 0x2100 ||
|
||||
0xfe20 <= chr && chr < 0xfe30;
|
||||
(0x0300 <= chr && chr < 0x0370) ||
|
||||
(0x1dc0 <= chr && chr < 0x1e00) ||
|
||||
(0x20d0 <= chr && chr < 0x2100) ||
|
||||
(0xfe20 <= chr && chr < 0xfe30);
|
||||
}
|
||||
|
||||
///
|
||||
@ -151,7 +173,7 @@ namespace stdex
|
||||
inline size_t islbreak(_In_reads_or_z_opt_(count) const T* chr, _In_ size_t count)
|
||||
{
|
||||
_Analysis_assume_(chr || !count);
|
||||
if (count >= 2 && (chr[0] == '\r' && chr[1] == '\n' || chr[0] == '\n' && chr[1] == '\r'))
|
||||
if (count >= 2 && ((chr[0] == '\r' && chr[1] == '\n') || (chr[0] == '\n' && chr[1] == '\r')))
|
||||
return 2;
|
||||
if (count > 1 && (chr[0] == '\n' || chr[0] == '\r'))
|
||||
return 1;
|
||||
@ -811,7 +833,7 @@ namespace stdex
|
||||
goto error;
|
||||
|
||||
if (value < max_ui_pre1 || // Multiplication nor addition will not overflow.
|
||||
value == max_ui_pre1 && digit <= max_ui_pre2) // Small digits will not overflow.
|
||||
(value == max_ui_pre1 && digit <= max_ui_pre2)) // Small digits will not overflow.
|
||||
value = value * (T_bin)radix + digit;
|
||||
else {
|
||||
// Overflow!
|
||||
@ -1060,7 +1082,7 @@ namespace stdex
|
||||
#pragma warning(suppress: 4996)
|
||||
r = _vsnprintf_l(str, capacity, format, locale, arg);
|
||||
#else
|
||||
r = vsnprintf(str, capacity, format, arg);
|
||||
r = ::vsnprintf(str, capacity, format, arg);
|
||||
#endif
|
||||
if (r == -1 && strnlen(str, capacity) == capacity) {
|
||||
// Buffer overrun. Estimate buffer size for the next iteration.
|
||||
@ -1206,4 +1228,4 @@ namespace stdex
|
||||
va_end(arg);
|
||||
return str;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -12,9 +12,11 @@
|
||||
#include <oaidl.h>
|
||||
#include <tchar.h>
|
||||
#else
|
||||
#define _LARGEFILE64_SOURCE
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#include "sal.hpp"
|
||||
#include "compat.hpp"
|
||||
#include <assert.h>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
|
@ -1,14 +1,19 @@
|
||||
/*
|
||||
/*
|
||||
SPDX-License-Identifier: MIT
|
||||
Copyright © 2023 Amebis
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "sal.hpp"
|
||||
#include "compat.hpp"
|
||||
#include "endian.hpp"
|
||||
#include "math.hpp"
|
||||
#include "system.hpp"
|
||||
#include <assert.h>
|
||||
#include <stdint.h>
|
||||
#ifndef _WIN32
|
||||
#include <iconv.h>
|
||||
#endif
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
@ -16,28 +21,87 @@ namespace stdex
|
||||
{
|
||||
enum class charset_id : uint16_t {
|
||||
#ifdef _WIN32
|
||||
default = CP_ACP,
|
||||
system = CP_ACP,
|
||||
utf8 = CP_UTF8,
|
||||
utf16 = 1200 /*CP_WINUNICODE*/,
|
||||
#else
|
||||
default = 0,
|
||||
system = 0,
|
||||
utf8,
|
||||
utf16,
|
||||
utf32,
|
||||
#endif
|
||||
};
|
||||
|
||||
#ifndef _WIN32
|
||||
///
|
||||
/// Convert string to Unicode (UTF-16 on Windows) and append to string
|
||||
/// Unicode converter context
|
||||
///
|
||||
template <typename T_from, typename T_to>
|
||||
class iconverter
|
||||
{
|
||||
public:
|
||||
iconverter(_In_ charset_id from, _In_ charset_id to)
|
||||
{
|
||||
m_handle = iconv_open(to_encoding(to), to_encoding(from));
|
||||
if (m_handle == (iconv_t)-1)
|
||||
throw std::runtime_error("iconv_open failed");
|
||||
}
|
||||
|
||||
~iconverter()
|
||||
{
|
||||
iconv_close(m_handle);
|
||||
}
|
||||
|
||||
void convert(_Inout_ std::basic_string<T_to> &dst, _In_reads_or_z_opt_(count) const T_from* src, _In_ size_t count_src) const
|
||||
{
|
||||
T_to buf[0x100];
|
||||
count_src = stdex::strnlen(src, count_src);
|
||||
size_t src_size = stdex::mul(sizeof(T_from), count_src);
|
||||
do {
|
||||
T_to* output = &buf[0];
|
||||
size_t output_size = sizeof(buf);
|
||||
errno = 0;
|
||||
iconv(m_handle, (char**)&src, &src_size, (char**)&output, &output_size);
|
||||
if (errno)
|
||||
throw std::runtime_error("iconv failed");
|
||||
dst.insert(dst.end(), buf, (T_to*)((char*)buf + sizeof(buf) - output_size));
|
||||
} while (src_size);
|
||||
}
|
||||
|
||||
protected:
|
||||
static const char* to_encoding(_In_ charset_id charset)
|
||||
{
|
||||
switch (charset) {
|
||||
case charset_id::system:
|
||||
case charset_id::utf8: return "UTF-8";
|
||||
#if BYTE_ORDER == BIG_ENDIAN
|
||||
case charset_id::utf16: return "UTF-16BE";
|
||||
case charset_id::utf32: return "UTF-32BE";
|
||||
#else
|
||||
case charset_id::utf16: return "UTF-16LE";
|
||||
case charset_id::utf32: return "UTF-32LE";
|
||||
#endif
|
||||
default: throw std::invalid_argument("unsupported charset");
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
iconv_t m_handle;
|
||||
};
|
||||
#endif
|
||||
|
||||
///
|
||||
/// Convert string to Unicode (UTF-16 on Windows, UTF-32 elsewhere)) and append to string
|
||||
///
|
||||
/// \param[in,out] dst String to append Unicode to
|
||||
/// \param[in] src String
|
||||
/// \param[in] count_src String character count limit
|
||||
/// \param[in] charset Charset (stdex::charset_id::default - system default)
|
||||
///
|
||||
/// \return Unicode string
|
||||
/// \param[in] charset Charset (stdex::charset_id::system - system default)
|
||||
///
|
||||
inline void strcat(
|
||||
_Inout_ std::wstring& dst,
|
||||
_In_reads_or_z_opt_(count_src) const char* src, _In_ size_t count_src,
|
||||
_In_ charset_id charset = charset_id::default)
|
||||
_In_ charset_id charset = charset_id::system)
|
||||
{
|
||||
assert(src || !count_src);
|
||||
#ifdef _WIN32
|
||||
@ -59,14 +123,15 @@ namespace stdex
|
||||
dst.append(szBuffer.get(), count_src != SIZE_MAX ? wcsnlen(szBuffer.get(), cch) : (size_t)cch - 1);
|
||||
}
|
||||
#else
|
||||
throw std::exception("not implemented");
|
||||
iconverter<char, wchar_t>(charset, charset_id::utf32).convert(dst, src, count_src);
|
||||
#endif
|
||||
}
|
||||
|
||||
inline _Deprecated_("Use stdex::strcat") void str2wstr(
|
||||
_Deprecated_("Use stdex::strcat")
|
||||
inline void str2wstr(
|
||||
_Inout_ std::wstring& dst,
|
||||
_In_reads_or_z_opt_(count_src) const char* src, _In_ size_t count_src,
|
||||
_In_ charset_id charset = charset_id::default)
|
||||
_In_ charset_id charset = charset_id::system)
|
||||
{
|
||||
strcat(dst, src, count_src, charset);
|
||||
}
|
||||
@ -76,22 +141,21 @@ namespace stdex
|
||||
///
|
||||
/// \param[in,out] dst String to append Unicode to
|
||||
/// \param[in] src String
|
||||
/// \param[in] charset Charset (stdex::charset_id::default - system default)
|
||||
///
|
||||
/// \return Unicode string
|
||||
/// \param[in] charset Charset (stdex::charset_id::system - system default)
|
||||
///
|
||||
inline void strcat(
|
||||
_Inout_ std::wstring& dst,
|
||||
_In_ const std::string& src,
|
||||
_In_ charset_id charset = charset_id::default)
|
||||
_In_ charset_id charset = charset_id::system)
|
||||
{
|
||||
strcat(dst, src.data(), src.size(), charset);
|
||||
}
|
||||
|
||||
inline _Deprecated_("Use stdex::strcat") void str2wstr(
|
||||
_Deprecated_("Use stdex::strcat")
|
||||
inline void str2wstr(
|
||||
_Inout_ std::wstring& dst,
|
||||
_In_ const std::string& src,
|
||||
_In_ charset_id charset = charset_id::default)
|
||||
_In_ charset_id charset = charset_id::system)
|
||||
{
|
||||
strcat(dst, src, charset);
|
||||
}
|
||||
@ -102,14 +166,12 @@ namespace stdex
|
||||
/// \param[in,out] dst String to write Unicode to
|
||||
/// \param[in] src String
|
||||
/// \param[in] count_src String character count limit
|
||||
/// \param[in] charset Charset (stdex::charset_id::default - system default)
|
||||
///
|
||||
/// \return Unicode string
|
||||
/// \param[in] charset Charset (stdex::charset_id::system - system default)
|
||||
///
|
||||
inline void strcpy(
|
||||
_Inout_ std::wstring& dst,
|
||||
_In_reads_or_z_opt_(count_src) const char* src, _In_ size_t count_src,
|
||||
_In_ charset_id charset = charset_id::default)
|
||||
_In_ charset_id charset = charset_id::system)
|
||||
{
|
||||
dst.clear();
|
||||
strcat(dst, src, count_src, charset);
|
||||
@ -120,14 +182,12 @@ namespace stdex
|
||||
///
|
||||
/// \param[in,out] dst String to write Unicode to
|
||||
/// \param[in] src String
|
||||
/// \param[in] charset Charset (stdex::charset_id::default - system default)
|
||||
///
|
||||
/// \return Unicode string
|
||||
/// \param[in] charset Charset (stdex::charset_id::system - system default)
|
||||
///
|
||||
inline void strcpy(
|
||||
_Inout_ std::wstring& dst,
|
||||
_In_ const std::string& src,
|
||||
_In_ charset_id charset = charset_id::default)
|
||||
_In_ charset_id charset = charset_id::system)
|
||||
{
|
||||
strcpy(dst, src.data(), src.size(), charset);
|
||||
}
|
||||
@ -136,13 +196,13 @@ namespace stdex
|
||||
/// Convert string to Unicode string (UTF-16 on Windows)
|
||||
///
|
||||
/// \param[in] src String. Must be zero-terminated.
|
||||
/// \param[in] charset Charset (stdex::charset_id::default - system default)
|
||||
/// \param[in] charset Charset (stdex::charset_id::system - system default)
|
||||
///
|
||||
/// \return Unicode string
|
||||
///
|
||||
inline std::wstring str2wstr(
|
||||
_In_z_ const char* src,
|
||||
_In_ charset_id charset = charset_id::default)
|
||||
_In_ charset_id charset = charset_id::system)
|
||||
{
|
||||
std::wstring dst;
|
||||
strcat(dst, src, SIZE_MAX, charset);
|
||||
@ -154,13 +214,13 @@ namespace stdex
|
||||
///
|
||||
/// \param[in] src String
|
||||
/// \param[in] count_src String character count limit
|
||||
/// \param[in] charset Charset (stdex::charset_id::default - system default)
|
||||
/// \param[in] charset Charset (stdex::charset_id::system - system default)
|
||||
///
|
||||
/// \return Unicode string
|
||||
///
|
||||
inline std::wstring str2wstr(
|
||||
_In_reads_or_z_opt_(count_src) const char* src, _In_ size_t count_src,
|
||||
_In_ charset_id charset = charset_id::default)
|
||||
_In_ charset_id charset = charset_id::system)
|
||||
{
|
||||
std::wstring dst;
|
||||
strcat(dst, src, count_src, charset);
|
||||
@ -171,29 +231,29 @@ namespace stdex
|
||||
/// Convert string to Unicode string (UTF-16 on Windows)
|
||||
///
|
||||
/// \param[in] src String
|
||||
/// \param[in] charset Charset (stdex::charset_id::default - system default)
|
||||
/// \param[in] charset Charset (stdex::charset_id::system - system default)
|
||||
///
|
||||
/// \return Unicode string
|
||||
///
|
||||
inline std::wstring str2wstr(
|
||||
_In_ const std::string& src,
|
||||
_In_ charset_id charset = charset_id::default)
|
||||
_In_ charset_id charset = charset_id::system)
|
||||
{
|
||||
return str2wstr(src.c_str(), src.size(), charset);
|
||||
}
|
||||
|
||||
///
|
||||
/// Convert Unicode string (UTF-16 on Windows) to SGML and append to string
|
||||
/// Convert Unicode string (UTF-16 on Windows, UTF-32 elsewhere) to SGML and append to string
|
||||
///
|
||||
/// \param[in,out] dst String to append SGML to
|
||||
/// \param[in] src Unicode string
|
||||
/// \param[in] count_src Unicode string character count limit
|
||||
/// \param[in] charset Charset (stdex::charset_id::default - system default)
|
||||
/// \param[in] charset Charset (stdex::charset_id::system - system default)
|
||||
///
|
||||
inline void strcat(
|
||||
_Inout_ std::string& dst,
|
||||
_In_reads_or_z_opt_(count_src) const wchar_t* src, _In_ size_t count_src,
|
||||
_In_ charset_id charset = charset_id::default)
|
||||
_In_ charset_id charset = charset_id::system)
|
||||
{
|
||||
assert(src || !count_src);
|
||||
#ifdef _WIN32
|
||||
@ -216,14 +276,15 @@ namespace stdex
|
||||
dst.append(szBuffer.get(), count_src != SIZE_MAX ? strnlen(szBuffer.get(), cch) : (size_t)cch - 1);
|
||||
}
|
||||
#else
|
||||
throw std::exception("not implemented");
|
||||
iconverter<wchar_t, char>(charset_id::utf32, charset).convert(dst, src, count_src);
|
||||
#endif
|
||||
}
|
||||
|
||||
inline _Deprecated_("Use stdex::strcat") void wstr2str(
|
||||
_Deprecated_("Use stdex::strcat")
|
||||
inline void wstr2str(
|
||||
_Inout_ std::string& dst,
|
||||
_In_reads_or_z_opt_(count_src) const wchar_t* src, _In_ size_t count_src,
|
||||
_In_ charset_id charset = charset_id::default)
|
||||
_In_ charset_id charset = charset_id::system)
|
||||
{
|
||||
strcat(dst, src, count_src, charset);
|
||||
}
|
||||
@ -233,20 +294,21 @@ namespace stdex
|
||||
///
|
||||
/// \param[in,out] dst String to append SGML to
|
||||
/// \param[in] src Unicode string
|
||||
/// \param[in] charset Charset (stdex::charset_id::default - system default)
|
||||
/// \param[in] charset Charset (stdex::charset_id::system - system default)
|
||||
///
|
||||
inline void strcat(
|
||||
_Inout_ std::string& dst,
|
||||
_In_ const std::wstring& src,
|
||||
_In_ charset_id charset = charset_id::default)
|
||||
_In_ charset_id charset = charset_id::system)
|
||||
{
|
||||
strcat(dst, src.c_str(), src.size(), charset);
|
||||
}
|
||||
|
||||
inline _Deprecated_("Use stdex::strcat") void wstr2str(
|
||||
_Deprecated_("Use stdex::strcat")
|
||||
inline void wstr2str(
|
||||
_Inout_ std::string& dst,
|
||||
_In_ const std::wstring& src,
|
||||
_In_ charset_id charset = charset_id::default)
|
||||
_In_ charset_id charset = charset_id::system)
|
||||
{
|
||||
strcat(dst, src, charset);
|
||||
}
|
||||
@ -257,12 +319,12 @@ namespace stdex
|
||||
/// \param[in,out] dst String to write SGML to
|
||||
/// \param[in] src Unicode string
|
||||
/// \param[in] count_src Unicode string character count limit
|
||||
/// \param[in] charset Charset (stdex::charset_id::default - system default)
|
||||
/// \param[in] charset Charset (stdex::charset_id::system - system default)
|
||||
///
|
||||
inline void strcpy(
|
||||
_Inout_ std::string& dst,
|
||||
_In_reads_or_z_opt_(count_src) const wchar_t* src, _In_ size_t count_src,
|
||||
_In_ charset_id charset = charset_id::default)
|
||||
_In_ charset_id charset = charset_id::system)
|
||||
{
|
||||
dst.clear();
|
||||
strcat(dst, src, count_src, charset);
|
||||
@ -273,12 +335,12 @@ namespace stdex
|
||||
///
|
||||
/// \param[in,out] dst String to write SGML to
|
||||
/// \param[in] src Unicode string
|
||||
/// \param[in] charset Charset (stdex::charset_id::default - system default)
|
||||
/// \param[in] charset Charset (stdex::charset_id::system - system default)
|
||||
///
|
||||
inline void strcpy(
|
||||
_Inout_ std::string& dst,
|
||||
_In_ const std::wstring& src,
|
||||
_In_ charset_id charset = charset_id::default)
|
||||
_In_ charset_id charset = charset_id::system)
|
||||
{
|
||||
strcpy(dst, src.data(), src.size(), charset);
|
||||
}
|
||||
@ -287,13 +349,13 @@ namespace stdex
|
||||
/// Convert Unicode string (UTF-16 on Windows) to string
|
||||
///
|
||||
/// \param[in] src Unicode string. Must be zero-terminated.
|
||||
/// \param[in] charset Charset (stdex::charset_id::default - system default)
|
||||
/// \param[in] charset Charset (stdex::charset_id::system - system default)
|
||||
///
|
||||
/// \return String
|
||||
///
|
||||
inline std::string wstr2str(
|
||||
_In_z_ const wchar_t* src,
|
||||
_In_ charset_id charset = charset_id::default)
|
||||
_In_ charset_id charset = charset_id::system)
|
||||
{
|
||||
std::string dst;
|
||||
strcat(dst, src, SIZE_MAX, charset);
|
||||
@ -305,13 +367,13 @@ namespace stdex
|
||||
///
|
||||
/// \param[in] src Unicode string
|
||||
/// \param[in] count_src Unicode string character count limit
|
||||
/// \param[in] charset Charset (stdex::charset_id::default - system default)
|
||||
/// \param[in] charset Charset (stdex::charset_id::system - system default)
|
||||
///
|
||||
/// \return String
|
||||
///
|
||||
inline std::string wstr2str(
|
||||
_In_reads_or_z_opt_(count_src) const wchar_t* src, _In_ size_t count_src,
|
||||
_In_ charset_id charset = charset_id::default)
|
||||
_In_ charset_id charset = charset_id::system)
|
||||
{
|
||||
std::string dst;
|
||||
strcat(dst, src, count_src, charset);
|
||||
@ -322,14 +384,14 @@ namespace stdex
|
||||
/// Convert Unicode string (UTF-16 on Windows) to string
|
||||
///
|
||||
/// \param[in] src Unicode string
|
||||
/// \param[in] charset Charset (stdex::charset_id::default - system default)
|
||||
/// \param[in] charset Charset (stdex::charset_id::system - system default)
|
||||
///
|
||||
/// \return String
|
||||
///
|
||||
inline std::string wstr2str(
|
||||
_In_ const std::wstring& src,
|
||||
_In_ charset_id charset = charset_id::default)
|
||||
_In_ charset_id charset = charset_id::system)
|
||||
{
|
||||
return wstr2str(src.c_str(), src.size(), charset);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -5,7 +5,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "sal.hpp"
|
||||
#include "compat.hpp"
|
||||
|
||||
namespace stdex
|
||||
{
|
||||
|
@ -1,18 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdexcept>
|
||||
|
||||
template <class T>
|
||||
void are_equal(const T& a, const T& b)
|
||||
{
|
||||
if (!(a == b))
|
||||
throw std::runtime_error("values are not equal");
|
||||
}
|
||||
|
||||
template <class E, typename F>
|
||||
void expect_exception(F functor)
|
||||
{
|
||||
try { functor(); }
|
||||
catch (const E&) { return; }
|
||||
throw std::runtime_error("exception expected");
|
||||
}
|
@ -1,16 +0,0 @@
|
||||
#include "math.hpp"
|
||||
#include <iostream>
|
||||
|
||||
int main(int argc, const char * argv[])
|
||||
{
|
||||
try {
|
||||
UnitTests::math::mul();
|
||||
UnitTests::math::add();
|
||||
std::cout << "PASS\n";
|
||||
return 0;
|
||||
}
|
||||
catch (const std::exception& ex) {
|
||||
std::cerr << ex.what() << " FAIL\n";
|
||||
return 1;
|
||||
}
|
||||
}
|
@ -1,39 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "common.hpp"
|
||||
#include <stdex/math.hpp>
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace UnitTests
|
||||
{
|
||||
class math
|
||||
{
|
||||
public:
|
||||
static void mul()
|
||||
{
|
||||
are_equal<size_t>(10, stdex::mul(2, 5));
|
||||
are_equal<size_t>(10, stdex::mul(5, 2));
|
||||
are_equal<size_t>(0, stdex::mul(0, 10));
|
||||
are_equal<size_t>(0, stdex::mul(10, 0));
|
||||
are_equal<size_t>(0, stdex::mul(SIZE_MAX, 0));
|
||||
are_equal<size_t>(0, stdex::mul(0, SIZE_MAX));
|
||||
are_equal<size_t>(SIZE_MAX, stdex::mul(SIZE_MAX, 1));
|
||||
are_equal<size_t>(SIZE_MAX, stdex::mul(1, SIZE_MAX));
|
||||
expect_exception<std::invalid_argument>([] { stdex::mul(SIZE_MAX, 2); });
|
||||
expect_exception<std::invalid_argument>([] { stdex::mul(2, SIZE_MAX); });
|
||||
}
|
||||
|
||||
static void add()
|
||||
{
|
||||
are_equal<size_t>(7, stdex::add(2, 5));
|
||||
are_equal<size_t>(7, stdex::add(5, 2));
|
||||
are_equal<size_t>(10, stdex::add(0, 10));
|
||||
are_equal<size_t>(10, stdex::add(10, 0));
|
||||
are_equal<size_t>(SIZE_MAX, stdex::add(SIZE_MAX, 0));
|
||||
are_equal<size_t>(SIZE_MAX, stdex::add(0, SIZE_MAX));
|
||||
expect_exception<std::invalid_argument>([] { stdex::add(SIZE_MAX, 1); });
|
||||
expect_exception<std::invalid_argument>([] { stdex::add(1, SIZE_MAX); });
|
||||
}
|
||||
};
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user