another stage of refactoring
CI / Build NRO (push) Successful in 30s
CI / Format check (push) Failing after 33s
CI / Layering check (push) Successful in 1s

This commit is contained in:
2026-05-12 09:59:43 +03:00
parent 6f8ede035f
commit 898e127c1d
45 changed files with 1982 additions and 2663 deletions
+15 -51
View File
@@ -1,59 +1,25 @@
/*
* This file is part of Checkpoint
* Copyright (C) 2017-2021 Bernardo Giordano, FlagBrew
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
* * Requiring preservation of specified reasonable legal notices or
* author attributions in that material or in the Appropriate Legal
* Notices displayed by works containing it.
* * Prohibiting misrepresentation of the origin of that material,
* or requiring that modified versions of such material be marked in
* reasonable ways as different from the original version.
*/
// Copyright (C) 2024-2026 NXST contributors
#pragma once
#include <map>
#include <string.h>
#include <string>
#include <vector>
#include <switch.h>
#define USER_ICON_SIZE 64
// Hash and comparison support for AccountUid as map/unordered_map key.
namespace std {
template <> struct hash<AccountUid> {
size_t operator()(const AccountUid& a) const {
return ((hash<u64>()(a.uid[0]) ^ (hash<u64>()(a.uid[1]) << 1)) >> 1);
}
};
template <> struct hash<AccountUid> {
size_t operator()(const AccountUid& a) const noexcept {
return (hash<u64>()(a.uid[0]) ^ (hash<u64>()(a.uid[1]) << 1)) >> 1;
}
};
} // namespace std
inline bool operator==(const AccountUid& x, const AccountUid& y) {
return x.uid[0] == y.uid[0] && x.uid[1] == y.uid[1];
}
inline bool operator==(const AccountUid& x, u64 y) {
return x.uid[0] == y && x.uid[1] == y;
}
inline bool operator<(const AccountUid& x, const AccountUid& y) {
if (x.uid[0] != y.uid[0])
return x.uid[0] < y.uid[0];
return x.uid[1] < y.uid[1];
return x.uid[0] != y.uid[0] ? x.uid[0] < y.uid[0] : x.uid[1] < y.uid[1];
}
struct User {
@@ -61,12 +27,10 @@ struct User {
std::string name;
};
namespace Account {
Result init(void);
void exit(void);
std::vector<AccountUid> ids(void);
AccountUid selectAccount(void);
std::string username(AccountUid id);
std::string iconPath(AccountUid id);
} // namespace Account
namespace account {
Result init();
void exit();
std::vector<AccountUid> ids();
std::string username(AccountUid id);
std::string iconPath(AccountUid id);
} // namespace account
-61
View File
@@ -1,61 +0,0 @@
/*
* This file is part of Checkpoint
* Copyright (C) 2017-2021 Bernardo Giordano, FlagBrew
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
* * Requiring preservation of specified reasonable legal notices or
* author attributions in that material or in the Appropriate Legal
* Notices displayed by works containing it.
* * Prohibiting misrepresentation of the origin of that material,
* or requiring that modified versions of such material be marked in
* reasonable ways as different from the original version.
*/
#pragma once
#include <algorithm>
#include <arpa/inet.h>
#include <codecvt>
#include <cstdio>
#include <locale>
#include <memory>
#include <netinet/in.h>
#include <stdarg.h>
#include <string.h>
#include <string>
#include <sys/socket.h>
#include <time.h>
#include <unistd.h>
#define ATEXIT(func) atexit((void (*)())func)
namespace DateTime {
std::string timeStr(void);
std::string dateTimeStr(void);
std::string logDateTime(void);
} // namespace DateTime
namespace StringUtils {
bool containsInvalidChar(const std::string& str);
std::string escapeJson(const std::string& s);
std::string format(const std::string fmt_str, ...);
std::string removeForbiddenCharacters(std::string src);
std::string UTF16toUTF8(const std::u16string& src);
void ltrim(std::string& s);
void rtrim(std::string& s);
void trim(std::string& s);
} // namespace StringUtils
char* getConsoleIP(void);
+11 -12
View File
@@ -1,17 +1,16 @@
#pragma once
#include <cstdint>
namespace proto {
constexpr uint16_t TCP_PORT = 8080;
constexpr uint16_t MULTICAST_PORT = 8081;
constexpr char MULTICAST_GROUP[] = "239.0.0.1";
constexpr size_t BUF_SIZE = 65536;
constexpr uint32_t MAX_FILENAME = 4096;
constexpr uint32_t EOF_SENTINEL = 0;
constexpr uint16_t kTcpPort = 8080;
constexpr uint16_t kMulticastPort = 8081;
constexpr char kMulticastGroup[] = "239.0.0.1";
constexpr size_t kBufSize = 65536;
constexpr uint32_t kMaxFilename = 4096;
constexpr uint32_t kEofSentinel = 0;
// Wire layout per file:
// [filename_len : uint32_t LE] — 0 == end-of-stream
// [filename : filename_len bytes]
// [file_size : uint64_t LE]
// [file_data : file_size bytes]
// Wire layout per file:
// [filename_len : uint32_t LE] — 0 == end-of-stream
// [filename : filename_len bytes]
// [file_size : uint64_t LE]
// [file_data : file_size bytes]
} // namespace proto
+83 -83
View File
@@ -4,105 +4,105 @@
namespace nxst {
template <class T, class E = std::string> class Result {
bool ok;
alignas(T) alignas(E) unsigned char storage[sizeof(T) > sizeof(E) ? sizeof(T) : sizeof(E)];
template <class T, class E = std::string> class Result {
bool ok;
alignas(T) alignas(E) unsigned char storage[sizeof(T) > sizeof(E) ? sizeof(T) : sizeof(E)];
Result() = default;
Result() = default;
public:
static Result success(T val) {
Result res;
res.ok = true;
new (res.storage) T(std::move(val));
return res;
}
public:
static Result success(T val) {
Result res;
res.ok = true;
new (res.storage) T(std::move(val));
return res;
}
static Result failure(E err) {
Result res;
res.ok = false;
new (res.storage) E(std::move(err));
return res;
}
static Result failure(E err) {
Result res;
res.ok = false;
new (res.storage) E(std::move(err));
return res;
}
~Result() {
if (ok)
reinterpret_cast<T*>(storage)->~T();
else
reinterpret_cast<E*>(storage)->~E();
}
~Result() {
if (ok)
reinterpret_cast<T*>(storage)->~T();
else
reinterpret_cast<E*>(storage)->~E();
}
Result(const Result& other) : ok(other.ok) {
if (ok)
new (storage) T(*reinterpret_cast<const T*>(other.storage));
else
new (storage) E(*reinterpret_cast<const E*>(other.storage));
}
Result(const Result& other) : ok(other.ok) {
if (ok)
new (storage) T(*reinterpret_cast<const T*>(other.storage));
else
new (storage) E(*reinterpret_cast<const E*>(other.storage));
}
Result(Result&& other) : ok(other.ok) {
if (ok)
new (storage) T(std::move(*reinterpret_cast<T*>(other.storage)));
else
new (storage) E(std::move(*reinterpret_cast<E*>(other.storage)));
}
Result(Result&& other) : ok(other.ok) {
if (ok)
new (storage) T(std::move(*reinterpret_cast<T*>(other.storage)));
else
new (storage) E(std::move(*reinterpret_cast<E*>(other.storage)));
}
Result& operator=(const Result&) = delete;
Result& operator=(const Result&) = delete;
bool isOk() const noexcept {
return ok;
}
const T& value() const {
return *reinterpret_cast<const T*>(storage);
}
const E& error() const {
return *reinterpret_cast<const E*>(storage);
}
};
bool isOk() const noexcept {
return ok;
}
const T& value() const {
return *reinterpret_cast<const T*>(storage);
}
const E& error() const {
return *reinterpret_cast<const E*>(storage);
}
};
// Specialisation for Result<void>
template <class E> class Result<void, E> {
bool ok;
alignas(E) unsigned char storage[sizeof(E)];
// Specialisation for Result<void>
template <class E> class Result<void, E> {
bool ok;
alignas(E) unsigned char storage[sizeof(E)];
Result() = default;
Result() = default;
public:
static Result success() {
Result res;
res.ok = true;
return res;
}
public:
static Result success() {
Result res;
res.ok = true;
return res;
}
static Result failure(E err) {
Result res;
res.ok = false;
new (res.storage) E(std::move(err));
return res;
}
static Result failure(E err) {
Result res;
res.ok = false;
new (res.storage) E(std::move(err));
return res;
}
~Result() {
if (!ok)
reinterpret_cast<E*>(storage)->~E();
}
~Result() {
if (!ok)
reinterpret_cast<E*>(storage)->~E();
}
Result(const Result& other) : ok(other.ok) {
if (!ok)
new (storage) E(*reinterpret_cast<const E*>(other.storage));
}
Result(const Result& other) : ok(other.ok) {
if (!ok)
new (storage) E(*reinterpret_cast<const E*>(other.storage));
}
Result(Result&& other) : ok(other.ok) {
if (!ok)
new (storage) E(std::move(*reinterpret_cast<E*>(other.storage)));
}
Result(Result&& other) : ok(other.ok) {
if (!ok)
new (storage) E(std::move(*reinterpret_cast<E*>(other.storage)));
}
Result& operator=(const Result&) = delete;
Result& operator=(const Result&) = delete;
bool isOk() const noexcept {
return ok;
}
const E& error() const {
return *reinterpret_cast<const E*>(storage);
}
};
bool isOk() const noexcept {
return ok;
}
const E& error() const {
return *reinterpret_cast<const E*>(storage);
}
};
} // namespace nxst
+38 -70
View File
@@ -1,32 +1,5 @@
/*
* This file is part of Checkpoint
* Copyright (C) 2017-2021 Bernardo Giordano, FlagBrew
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
* * Requiring preservation of specified reasonable legal notices or
* author attributions in that material or in the Appropriate Legal
* Notices displayed by works containing it.
* * Prohibiting misrepresentation of the origin of that material,
* or requiring that modified versions of such material be marked in
* reasonable ways as different from the original version.
*/
// Copyright (C) 2024-2026 NXST contributors
#pragma once
#include <algorithm>
#include <stdlib.h>
#include <string>
#include <unordered_map>
#include <utility>
@@ -34,57 +7,52 @@
#include <switch.h>
#include <nxst/domain/account.hpp>
#include <nxst/infra/fs/filesystem.hpp>
#include <nxst/infra/fs/io.hpp>
class Title {
public:
void init(u8 saveDataType, u64 titleid, AccountUid userID, const std::string& name,
void init(u8 save_data_type, u64 title_id, AccountUid uid, const std::string& name,
const std::string& author);
~Title() = default;
std::string author(void);
std::pair<std::string, std::string> displayName(void);
u64 id(void);
std::string name(void);
std::string path(void);
u64 playTimeNanoseconds(void);
std::string playTime(void);
void playTimeNanoseconds(u64 playTimeNanoseconds);
u32 lastPlayedTimestamp(void);
void lastPlayedTimestamp(u32 lastPlayedTimestamp);
std::string fullPath(size_t index);
void refreshDirectories(void);
u64 saveId();
std::string author() const;
std::pair<std::string, std::string> displayName() const;
u64 id() const;
std::string name() const;
std::string path() const;
u64 playTimeNanoseconds() const;
std::string playTime() const;
void playTimeNanoseconds(u64 ns);
u32 lastPlayedTimestamp() const;
void lastPlayedTimestamp(u32 ts);
std::string fullPath(size_t index) const;
void refreshDirectories();
u64 saveId() const;
void saveId(u64 id);
std::vector<std::string> saves(void);
u8 saveDataType(void);
AccountUid userId(void);
std::string userName(void);
std::vector<std::string> saves() const;
u8 saveDataType() const;
AccountUid userId() const;
std::string userName() const;
private:
u64 mId;
u64 mSaveId;
AccountUid mUserId;
std::string mUserName;
std::string mName;
std::string mSafeName;
std::string mAuthor;
std::string mPath;
std::vector<std::string> mSaves;
std::vector<std::string> mFullSavePaths;
u8 mSaveDataType;
std::pair<std::string, std::string> mDisplayName;
u64 mPlayTimeNanoseconds;
u32 mLastPlayedTimestamp;
u64 m_id{0};
u64 m_save_id{0};
AccountUid m_uid{};
std::string m_user_name;
std::string m_name;
std::string m_safe_name;
std::string m_author;
std::string m_path;
std::vector<std::string> m_saves;
std::vector<std::string> m_full_save_paths;
u8 m_save_data_type{0};
std::pair<std::string, std::string> m_display_name;
u64 m_play_time_ns{0};
u32 m_last_played_ts{0};
};
bool areTitlesLoaded();
void loadTitles();
void sortTitles();
void rotateSortMode();
void getTitle(Title& dst, AccountUid uid, size_t i);
size_t getTitleCount(AccountUid uid);
void loadTitles(void);
bool areTitlesLoaded(void);
void sortTitles(void);
void rotateSortMode(void);
void refreshDirectories(u64 id);
std::unordered_map<std::string, std::string> getCompleteTitleList(void);
std::unordered_map<std::string, std::string> getCompleteTitleList();
+16 -45
View File
@@ -1,51 +1,22 @@
/*
* This file is part of Checkpoint
* Copyright (C) 2017-2021 Bernardo Giordano, FlagBrew
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
* * Requiring preservation of specified reasonable legal notices or
* author attributions in that material or in the Appropriate Legal
* Notices displayed by works containing it.
* * Prohibiting misrepresentation of the origin of that material,
* or requiring that modified versions of such material be marked in
* reasonable ways as different from the original version.
*/
// Copyright (C) 2024-2026 NXST contributors
#pragma once
#include <sys/stat.h>
#include <switch.h>
#include <nxst/domain/account.hpp>
#include <nxst/domain/common.hpp>
#include <nxst/infra/fs/io.hpp>
// debug
#include <arpa/inet.h>
#include <sys/errno.h>
#include <sys/socket.h>
void servicesExit(void);
Result servicesInit(void);
HidsysNotificationLedPattern blinkLedPattern(u8 times);
void servicesExit();
Result servicesInit();
void blinkLed(u8 times);
namespace StringUtils {
std::string removeAccents(std::string str);
std::string removeNotAscii(std::string str);
std::u16string UTF8toUTF16(const char* src);
std::string elide(const std::string& s, size_t maxChars);
} // namespace StringUtils
namespace string_utils {
bool containsInvalidChar(const std::string& str);
std::string format(const char* fmt, ...) __attribute__((format(printf, 1, 2)));
std::string removeForbiddenCharacters(std::string src);
std::string UTF16toUTF8(const std::u16string& src);
void ltrim(std::string& s);
void rtrim(std::string& s);
void trim(std::string& s);
std::string removeAccents(std::string str);
std::string removeNotAscii(std::string str);
std::u16string UTF8toUTF16(const char* src);
std::string elide(const std::string& s, size_t max_chars);
} // namespace string_utils