From 3e64021400f5ae044bc2317f54d27638e7674108 Mon Sep 17 00:00:00 2001 From: Lioncash Date: Sat, 31 Aug 2019 17:55:50 -0400 Subject: [PATCH] General: Use std::array where applicable Same behavior, but with stronger typing. We can also eliminate usages of magic values in some places. --- include/kabufuda/BlockAllocationTable.hpp | 6 +- include/kabufuda/Card.hpp | 21 ++-- include/kabufuda/Directory.hpp | 7 +- include/kabufuda/File.hpp | 7 +- include/kabufuda/SRAM.hpp | 18 ++-- lib/kabufuda/BlockAllocationTable.cpp | 11 +- lib/kabufuda/Card.cpp | 121 ++++++++++++---------- lib/kabufuda/Directory.cpp | 116 +++++++++++++-------- lib/kabufuda/File.cpp | 11 +- 9 files changed, 176 insertions(+), 142 deletions(-) diff --git a/include/kabufuda/BlockAllocationTable.hpp b/include/kabufuda/BlockAllocationTable.hpp index 309388b..f4ac51d 100644 --- a/include/kabufuda/BlockAllocationTable.hpp +++ b/include/kabufuda/BlockAllocationTable.hpp @@ -1,5 +1,6 @@ #pragma once +#include #include #include "kabufuda/Constants.hpp" @@ -14,9 +15,9 @@ class BlockAllocationTable { uint16_t m_updateCounter; uint16_t m_freeBlocks; uint16_t m_lastAllocated; - uint16_t m_map[0xFFB]; + std::array m_map; }; - uint8_t __raw[BlockSize]; + std::array raw{}; }; #pragma pack(pop) @@ -26,7 +27,6 @@ class BlockAllocationTable { public: explicit BlockAllocationTable(uint32_t blockCount = (uint32_t(ECardSize::Card2043Mb) * MbitToBlocks)); - BlockAllocationTable(uint8_t data[BlockSize]); ~BlockAllocationTable() = default; uint16_t getNextBlock(uint16_t block) const; diff --git a/include/kabufuda/Card.hpp b/include/kabufuda/Card.hpp index 5783092..6b913db 100644 --- a/include/kabufuda/Card.hpp +++ b/include/kabufuda/Card.hpp @@ -1,5 +1,6 @@ #pragma once +#include #include #include @@ -37,8 +38,8 @@ struct CardStat { char x0_fileName[CARD_FILENAME_MAX]; uint32_t x20_length; uint32_t x24_time; /* seconds since 01/01/2000 midnight */ - uint8_t x28_gameName[4]; - uint8_t x2c_company[2]; + std::array x28_gameName; + std::array x2c_company; /* read/write (Set by Card::getStatus/Card::setStatus) */ uint8_t x2e_bannerFormat; @@ -51,7 +52,7 @@ struct CardStat { /* read-only (Set by Card::getStatus) */ uint32_t x3c_offsetBanner; uint32_t x40_offsetBannerTlut; - uint32_t x44_offsetIcon[CARD_ICON_MAX]; + std::array x44_offsetIcon; uint32_t x64_offsetIconTlut; uint32_t x68_offsetData; @@ -79,7 +80,7 @@ class Card { struct CardHeader { union { struct { - uint8_t m_serial[12]; + std::array m_serial; uint64_t m_formatTime; int32_t m_sramBias; uint32_t m_sramLanguage; @@ -87,12 +88,12 @@ class Card { uint16_t m_deviceId; /* 0 for Slot A, 1 for Slot B */ uint16_t m_sizeMb; uint16_t m_encoding; - uint8_t __padding[468]; + std::array padding; uint16_t m_updateCounter; uint16_t m_checksum; uint16_t m_checksumInv; }; - uint8_t __raw[BlockSize]; + std::array raw; }; void _swapEndian(); }; @@ -102,10 +103,10 @@ class Card { SystemString m_filename; AsyncIO m_fileHandle; - Directory m_dirs[2]; - BlockAllocationTable m_bats[2]; - Directory m_tmpDirs[2]; - BlockAllocationTable m_tmpBats[2]; + std::array m_dirs; + std::array m_bats; + std::array m_tmpDirs; + std::array m_tmpBats; uint8_t m_currentDir; uint8_t m_currentBat; diff --git a/include/kabufuda/Directory.hpp b/include/kabufuda/Directory.hpp index 6b8b16d..f73a4de 100644 --- a/include/kabufuda/Directory.hpp +++ b/include/kabufuda/Directory.hpp @@ -1,5 +1,6 @@ #pragma once +#include #include #include "kabufuda/File.hpp" @@ -9,13 +10,13 @@ class Directory { #pragma pack(push, 4) union { struct { - File m_files[MaxFiles]; - uint8_t __padding[0x3a]; + std::array m_files; + std::array padding; uint16_t m_updateCounter; uint16_t m_checksum; uint16_t m_checksumInv; }; - uint8_t __raw[BlockSize]; + std::array raw; }; #pragma pack(pop) diff --git a/include/kabufuda/File.hpp b/include/kabufuda/File.hpp index 9586765..b7071a6 100644 --- a/include/kabufuda/File.hpp +++ b/include/kabufuda/File.hpp @@ -1,5 +1,6 @@ #pragma once +#include #include #include "kabufuda/Constants.hpp" @@ -11,8 +12,8 @@ class File { #pragma pack(push, 4) union { struct { - uint8_t m_game[4]; - uint8_t m_maker[2]; + std::array m_game; + std::array m_maker; uint8_t m_reserved; uint8_t m_bannerFlags; char m_filename[0x20]; @@ -27,7 +28,7 @@ class File { uint16_t m_reserved2; uint32_t m_commentAddr; }; - uint8_t __raw[0x40]; + std::array raw; }; #pragma pack(pop) diff --git a/include/kabufuda/SRAM.hpp b/include/kabufuda/SRAM.hpp index a413e0a..c7ef3ea 100644 --- a/include/kabufuda/SRAM.hpp +++ b/include/kabufuda/SRAM.hpp @@ -1,5 +1,6 @@ #pragma once +#include #include // Modified code taken from libogc @@ -41,7 +42,7 @@ union SRAMFlags { }; union SRAM { - uint8_t p_SRAM[64]; + std::array p_SRAM; struct // Stored configuration value from the system SRAM area { uint16_t checksum; // Holds the block checksum. @@ -55,13 +56,14 @@ union SRAM { SRAMFlags flags; // Device and operations flag // Stored configuration value from the extended SRAM area - uint8_t flash_id[2][12]; // flash_id[2][12] 96bit memorycard unlock flash ID - uint32_t wirelessKbd_id; // Device ID of last connected wireless keyboard - uint16_t wirelessPad_id[4]; // 16-bit device ID of last connected pad. - uint8_t dvderr_code; // last non-recoverable error from DVD interface - uint8_t __padding0; // reserved - uint8_t flashID_chksum[2]; // 8-bit checksum of unlock flash ID - uint32_t __padding1; // padding + using FlashID = std::array, 2>; + FlashID flash_id; // flash_id[2][12] 96bit memorycard unlock flash ID + uint32_t wirelessKbd_id; // Device ID of last connected wireless keyboard + std::array wirelessPad_id; // 16-bit device ID of last connected pad. + uint8_t dvderr_code; // last non-recoverable error from DVD interface + uint8_t __padding0; // reserved + std::array flashID_chksum; // 8-bit checksum of unlock flash ID + uint32_t __padding1; // padding }; }; #pragma pack(pop) diff --git a/lib/kabufuda/BlockAllocationTable.cpp b/lib/kabufuda/BlockAllocationTable.cpp index db8bfdf..2a16951 100644 --- a/lib/kabufuda/BlockAllocationTable.cpp +++ b/lib/kabufuda/BlockAllocationTable.cpp @@ -2,7 +2,6 @@ #include #include -#include #include #include "kabufuda/Util.hpp" @@ -19,23 +18,21 @@ void BlockAllocationTable::swapEndian() { void BlockAllocationTable::updateChecksum() { swapEndian(); - calculateChecksumBE(reinterpret_cast(__raw + 4), 0xFFE, &m_checksum, &m_checksumInv); + calculateChecksumBE(reinterpret_cast(raw.data() + 4), 0xFFE, &m_checksum, &m_checksumInv); swapEndian(); } bool BlockAllocationTable::valid() const { uint16_t ckSum, ckSumInv; const_cast(*this).swapEndian(); - calculateChecksumBE(reinterpret_cast(__raw + 4), 0xFFE, &ckSum, &ckSumInv); + calculateChecksumBE(reinterpret_cast(raw.data() + 4), 0xFFE, &ckSum, &ckSumInv); bool res = (ckSum == m_checksum && ckSumInv == m_checksumInv); const_cast(*this).swapEndian(); return res; } -BlockAllocationTable::BlockAllocationTable(uint32_t blockCount) { - memset(__raw, 0, BlockSize); - m_freeBlocks = uint16_t(blockCount - FSTBlocks); - m_lastAllocated = 4; +BlockAllocationTable::BlockAllocationTable(uint32_t blockCount) +: m_freeBlocks{uint16_t(blockCount - FSTBlocks)}, m_lastAllocated{4} { updateChecksum(); } diff --git a/lib/kabufuda/Card.cpp b/lib/kabufuda/Card.cpp index 201c171..4dd445f 100644 --- a/lib/kabufuda/Card.cpp +++ b/lib/kabufuda/Card.cpp @@ -26,40 +26,36 @@ void Card::CardHeader::_swapEndian() { m_checksumInv = SBig(m_checksumInv); } -Card::Card() { memset(m_ch.__raw, 0xFF, BlockSize); } +Card::Card() { m_ch.raw.fill(0xFF); } Card::Card(Card&& other) { - memmove(m_ch.__raw, other.m_ch.__raw, BlockSize); + m_ch.raw = other.m_ch.raw; m_filename = std::move(other.m_filename); m_fileHandle = std::move(other.m_fileHandle); - m_dirs[0] = std::move(other.m_dirs[0]); - m_dirs[1] = std::move(other.m_dirs[1]); - m_bats[0] = std::move(other.m_bats[0]); - m_bats[1] = std::move(other.m_bats[1]); + m_dirs = std::move(other.m_dirs); + m_bats = std::move(other.m_bats); m_currentDir = other.m_currentDir; m_currentBat = other.m_currentBat; m_maxBlock = other.m_maxBlock; - memmove(m_game, other.m_game, 5); - memmove(m_maker, other.m_maker, 3); + std::copy(std::cbegin(other.m_game), std::cend(other.m_game), std::begin(m_game)); + std::copy(std::cbegin(other.m_maker), std::cend(other.m_maker), std::begin(m_maker)); } Card& Card::operator=(Card&& other) { close(); - memmove(m_ch.__raw, other.m_ch.__raw, BlockSize); + m_ch.raw = other.m_ch.raw; m_filename = std::move(other.m_filename); m_fileHandle = std::move(other.m_fileHandle); - m_dirs[0] = std::move(other.m_dirs[0]); - m_dirs[1] = std::move(other.m_dirs[1]); - m_bats[0] = std::move(other.m_bats[0]); - m_bats[1] = std::move(other.m_bats[1]); + m_dirs = std::move(other.m_dirs); + m_bats = std::move(other.m_bats); m_currentDir = other.m_currentDir; m_currentBat = other.m_currentBat; m_maxBlock = other.m_maxBlock; - memmove(m_game, other.m_game, 5); - memmove(m_maker, other.m_maker, 3); + std::copy(std::cbegin(other.m_game), std::cend(other.m_game), std::begin(m_game)); + std::copy(std::cbegin(other.m_maker), std::cend(other.m_maker), std::begin(m_maker)); return *this; } @@ -109,11 +105,14 @@ ECardResult Card::_pumpOpen() { } Card::Card(const char* game, const char* maker) { - memset(m_ch.__raw, 0xFF, BlockSize); - if (game && strlen(game) == 4) - memcpy(m_game, game, 4); - if (maker && strlen(maker) == 2) - memcpy(m_maker, maker, 2); + m_ch.raw.fill(0xFF); + + if (game != nullptr && std::strlen(game) == 4) { + std::memcpy(m_game, game, 4); + } + if (maker != nullptr && std::strlen(maker) == 2) { + std::memcpy(m_maker, maker, 2); + } } Card::~Card() { close(); } @@ -166,7 +165,7 @@ void Card::_updateDirAndBat(const Directory& dir, const BlockAllocationTable& ba void Card::_updateChecksum() { m_ch._swapEndian(); - calculateChecksumBE(reinterpret_cast(m_ch.__raw), 0xFE, &m_ch.m_checksum, &m_ch.m_checksumInv); + calculateChecksumBE(reinterpret_cast(m_ch.raw.data()), 0xFE, &m_ch.m_checksum, &m_ch.m_checksumInv); m_ch._swapEndian(); } @@ -300,25 +299,28 @@ ECardResult Card::deleteFile(uint32_t fileno) { } ECardResult Card::renameFile(const char* oldName, const char* newName) { - ECardResult openRes = _pumpOpen(); - if (openRes != ECardResult::READY) + const ECardResult openRes = _pumpOpen(); + if (openRes != ECardResult::READY) { return openRes; + } - if (strlen(newName) > 32) + if (std::strlen(newName) > 32) { return ECardResult::NAMETOOLONG; + } Directory dir = m_dirs[m_currentDir]; File* f = dir.getFile(m_game, m_maker, oldName); - if (!f) + if (f == nullptr) { return ECardResult::NOFILE; + } if (File* replF = dir.getFile(m_game, m_maker, newName)) { BlockAllocationTable bat = m_bats[m_currentBat]; _deleteFile(*replF, bat); - strncpy(f->m_filename, newName, 32); + std::strncpy(f->m_filename, newName, 32); _updateDirAndBat(dir, bat); } else { - strncpy(f->m_filename, newName, 32); + std::strncpy(f->m_filename, newName, 32); _updateDirAndBat(dir, m_bats[m_currentBat]); } return ECardResult::READY; @@ -554,11 +556,11 @@ ECardResult Card::getStatus(uint32_t fileNo, CardStat& statOut) const { if (!file || file->m_game[0] == 0xFF) return ECardResult::NOFILE; - strncpy(statOut.x0_fileName, file->m_filename, 32); + std::strncpy(statOut.x0_fileName, file->m_filename, 32); statOut.x20_length = file->m_blockCount * BlockSize; statOut.x24_time = file->m_modifiedTime; - memcpy(statOut.x28_gameName, file->m_game, 4); - memcpy(statOut.x2c_company, file->m_maker, 2); + statOut.x28_gameName = file->m_game; + statOut.x2c_company = file->m_maker; statOut.x2e_bannerFormat = file->m_bannerFlags; statOut.x30_iconAddr = file->m_iconAddress; @@ -569,8 +571,7 @@ ECardResult Card::getStatus(uint32_t fileNo, CardStat& statOut) const { if (file->m_iconAddress == UINT32_MAX) { statOut.x3c_offsetBanner = UINT32_MAX; statOut.x40_offsetBannerTlut = UINT32_MAX; - for (int i = 0; i < CARD_ICON_MAX; ++i) - statOut.x44_offsetIcon[i] = UINT32_MAX; + statOut.x44_offsetIcon.fill(UINT32_MAX); statOut.x64_offsetIconTlut = UINT32_MAX; statOut.x68_offsetData = file->m_commentAddr + 64; } else { @@ -580,11 +581,12 @@ ECardResult Card::getStatus(uint32_t fileNo, CardStat& statOut) const { statOut.x40_offsetBannerTlut = cur; cur += TlutSize(statOut.GetBannerFormat()); bool palette = false; - for (int i = 0; i < CARD_ICON_MAX; ++i) { + for (size_t i = 0; i < statOut.x44_offsetIcon.size(); ++i) { statOut.x44_offsetIcon[i] = cur; - EImageFormat fmt = statOut.GetIconFormat(i); - if (fmt == EImageFormat::C8) + const EImageFormat fmt = statOut.GetIconFormat(int(i)); + if (fmt == EImageFormat::C8) { palette = true; + } cur += IconSize(fmt); } if (palette) { @@ -726,11 +728,14 @@ const uint8_t* Card::getCurrentMaker() const { void Card::getSerial(uint64_t& serial) { m_ch._swapEndian(); - uint32_t serialBuf[8]; - for (uint32_t i = 0; i < 8; i++) - serialBuf[i] = SBig(*reinterpret_cast(m_ch.__raw + (i * 4))); + + std::array serialBuf{}; + for (size_t i = 0; i < serialBuf.size(); i++) { + serialBuf[i] = SBig(*reinterpret_cast(m_ch.raw.data() + (i * 4))); + } serial = uint64_t(serialBuf[0] ^ serialBuf[2] ^ serialBuf[4] ^ serialBuf[6]) << 32 | (serialBuf[1] ^ serialBuf[3] ^ serialBuf[5] ^ serialBuf[7]); + m_ch._swapEndian(); } @@ -747,10 +752,11 @@ void Card::getFreeBlocks(int32_t& bytesNotUsed, int32_t& filesNotUsed) { static std::unique_ptr DummyBlock; void Card::format(ECardSlot id, ECardSize size, EEncoding encoding) { - memset(m_ch.__raw, 0xFF, BlockSize); + m_ch.raw.fill(0xFF); + uint64_t rand = uint64_t(getGCTime()); m_ch.m_formatTime = rand; - for (int i = 0; i < 12; i++) { + for (size_t i = 0; i < m_ch.m_serial.size(); i++) { rand = (((rand * uint64_t(0x41c64e6d)) + uint64_t(0x3039)) >> 16); m_ch.m_serial[i] = uint8_t(g_SRAM.flash_id[uint32_t(id)][i] + uint32_t(rand)); rand = (((rand * uint64_t(0x41c64e6d)) + uint64_t(0x3039)) >> 16); @@ -776,30 +782,31 @@ void Card::format(ECardSlot id, ECardSize size, EEncoding encoding) { m_fileHandle = AsyncIO(m_filename.c_str(), true); if (m_fileHandle) { - uint32_t blockCount = (uint32_t(size) * MbitToBlocks) - 5; + const uint32_t blockCount = (uint32_t(size) * MbitToBlocks) - 5; m_tmpCh = m_ch; m_tmpCh._swapEndian(); m_fileHandle.resizeQueue(5 + blockCount); - m_fileHandle.asyncWrite(0, m_tmpCh.__raw, BlockSize, 0); + m_fileHandle.asyncWrite(0, m_tmpCh.raw.data(), BlockSize, 0); m_tmpDirs[0] = m_dirs[0]; m_tmpDirs[0].swapEndian(); - m_fileHandle.asyncWrite(1, m_tmpDirs[0].__raw, BlockSize, BlockSize * 1); + m_fileHandle.asyncWrite(1, m_tmpDirs[0].raw.data(), BlockSize, BlockSize * 1); m_tmpDirs[1] = m_dirs[1]; m_tmpDirs[1].swapEndian(); - m_fileHandle.asyncWrite(2, m_tmpDirs[1].__raw, BlockSize, BlockSize * 2); + m_fileHandle.asyncWrite(2, m_tmpDirs[1].raw.data(), BlockSize, BlockSize * 2); m_tmpBats[0] = m_bats[0]; m_tmpBats[0].swapEndian(); - m_fileHandle.asyncWrite(3, m_tmpBats[0].__raw, BlockSize, BlockSize * 3); + m_fileHandle.asyncWrite(3, m_tmpBats[0].raw.data(), BlockSize, BlockSize * 3); m_tmpBats[1] = m_bats[1]; m_tmpBats[1].swapEndian(); - m_fileHandle.asyncWrite(4, m_tmpBats[1].__raw, BlockSize, BlockSize * 4); + m_fileHandle.asyncWrite(4, m_tmpBats[1].raw.data(), BlockSize, BlockSize * 4); if (!DummyBlock) { DummyBlock.reset(new uint8_t[BlockSize]); memset(DummyBlock.get(), 0xFF, BlockSize); } - for (uint32_t i = 0; i < blockCount; ++i) + for (uint32_t i = 0; i < blockCount; ++i) { m_fileHandle.asyncWrite(i + 5, DummyBlock.get(), BlockSize, BlockSize * (i + 5)); + } m_dirty = false; } } @@ -821,19 +828,19 @@ void Card::commit() { m_tmpDirs[0] = m_dirs[0]; m_tmpDirs[0].updateChecksum(); m_tmpDirs[0].swapEndian(); - m_fileHandle.asyncWrite(1, m_tmpDirs[0].__raw, BlockSize, BlockSize * 1); + m_fileHandle.asyncWrite(1, m_tmpDirs[0].raw.data(), BlockSize, BlockSize * 1); m_tmpDirs[1] = m_dirs[1]; m_tmpDirs[1].updateChecksum(); m_tmpDirs[1].swapEndian(); - m_fileHandle.asyncWrite(2, m_tmpDirs[1].__raw, BlockSize, BlockSize * 2); + m_fileHandle.asyncWrite(2, m_tmpDirs[1].raw.data(), BlockSize, BlockSize * 2); m_tmpBats[0] = m_bats[0]; m_tmpBats[0].updateChecksum(); m_tmpBats[0].swapEndian(); - m_fileHandle.asyncWrite(3, m_tmpBats[0].__raw, BlockSize, BlockSize * 3); + m_fileHandle.asyncWrite(3, m_tmpBats[0].raw.data(), BlockSize, BlockSize * 3); m_tmpBats[1] = m_bats[1]; m_tmpBats[1].updateChecksum(); m_tmpBats[1].swapEndian(); - m_fileHandle.asyncWrite(4, m_tmpBats[1].__raw, BlockSize, BlockSize * 4); + m_fileHandle.asyncWrite(4, m_tmpBats[1].raw.data(), BlockSize, BlockSize * 4); m_dirty = false; } } @@ -844,15 +851,15 @@ bool Card::open(SystemStringView filepath) { m_fileHandle = AsyncIO(m_filename); if (m_fileHandle) { m_fileHandle.resizeQueue(5); - if (!m_fileHandle.asyncRead(0, m_ch.__raw, BlockSize, 0)) + if (!m_fileHandle.asyncRead(0, m_ch.raw.data(), BlockSize, 0)) return false; - if (!m_fileHandle.asyncRead(1, m_dirs[0].__raw, BlockSize, BlockSize * 1)) + if (!m_fileHandle.asyncRead(1, m_dirs[0].raw.data(), BlockSize, BlockSize * 1)) return false; - if (!m_fileHandle.asyncRead(2, m_dirs[1].__raw, BlockSize, BlockSize * 2)) + if (!m_fileHandle.asyncRead(2, m_dirs[1].raw.data(), BlockSize, BlockSize * 2)) return false; - if (!m_fileHandle.asyncRead(3, m_bats[0].__raw, BlockSize, BlockSize * 3)) + if (!m_fileHandle.asyncRead(3, m_bats[0].raw.data(), BlockSize, BlockSize * 3)) return false; - if (!m_fileHandle.asyncRead(4, m_bats[1].__raw, BlockSize, BlockSize * 4)) + if (!m_fileHandle.asyncRead(4, m_bats[1].raw.data(), BlockSize, BlockSize * 4)) return false; return true; } @@ -882,7 +889,7 @@ ECardResult Card::getError() const { uint16_t ckSum, ckSumInv; const_cast(*this).m_ch._swapEndian(); - calculateChecksumBE(reinterpret_cast(m_ch.__raw), 0xFE, &ckSum, &ckSumInv); + calculateChecksumBE(reinterpret_cast(m_ch.raw.data()), 0xFE, &ckSum, &ckSumInv); bool res = (ckSum == m_ch.m_checksum && ckSumInv == m_ch.m_checksumInv); const_cast(*this).m_ch._swapEndian(); diff --git a/lib/kabufuda/Directory.cpp b/lib/kabufuda/Directory.cpp index 35486c3..436aa1f 100644 --- a/lib/kabufuda/Directory.cpp +++ b/lib/kabufuda/Directory.cpp @@ -16,100 +16,124 @@ void Directory::swapEndian() { void Directory::updateChecksum() { swapEndian(); - calculateChecksumBE(reinterpret_cast(__raw), 0xFFE, &m_checksum, &m_checksumInv); + calculateChecksumBE(reinterpret_cast(raw.data()), 0xFFE, &m_checksum, &m_checksumInv); swapEndian(); } bool Directory::valid() const { uint16_t ckSum, ckSumInv; const_cast(*this).swapEndian(); - calculateChecksumBE(reinterpret_cast(__raw), 0xFFE, &ckSum, &ckSumInv); + calculateChecksumBE(reinterpret_cast(raw.data()), 0xFFE, &ckSum, &ckSumInv); bool res = (ckSum == m_checksum && ckSumInv == m_checksumInv); const_cast(*this).swapEndian(); return res; } Directory::Directory() { - memset(__raw, 0xFF, BlockSize); + raw.fill(0xFF); m_updateCounter = 0; updateChecksum(); } -Directory::Directory(uint8_t data[]) { memcpy(__raw, data, BlockSize); } +Directory::Directory(uint8_t data[]) { std::memcpy(raw.data(), data, BlockSize); } bool Directory::hasFreeFile() const { - for (uint16_t i = 0; i < 127; i++) - if (m_files[i].m_game[0] == 0xFF) - return true; - return false; + return std::any_of(m_files.cbegin(), m_files.cend(), [](const auto& file) { return file.m_game[0] == 0xFF; }); } int32_t Directory::numFreeFiles() const { - int32_t ret = 0; - for (uint16_t i = 0; i < 127; i++) - if (m_files[i].m_game[0] == 0xFF) - ++ret; - return ret; + return int32_t( + std::count_if(m_files.cbegin(), m_files.cend(), [](const auto& file) { return file.m_game[0] == 0xFF; })); } File* Directory::getFirstFreeFile(const char* game, const char* maker, const char* filename) { - for (uint16_t i = 0; i < 127; i++) { - if (m_files[i].m_game[0] == 0xFF) { - File* ret = &m_files[i]; - *ret = File(filename); - if (game && strlen(game) == 4) - memcpy(ret->m_game, game, 4); - if (maker && strlen(maker) == 2) - memcpy(ret->m_maker, maker, 2); - return ret; - } + const auto iter = + std::find_if(m_files.begin(), m_files.end(), [](const auto& file) { return file.m_game[0] == 0xFF; }); + + if (iter == m_files.cend()) { + return nullptr; } - return nullptr; + *iter = File(filename); + if (game != nullptr && std::strlen(game) == iter->m_game.size()) { + std::memcpy(iter->m_game.data(), game, iter->m_game.size()); + } + if (maker != nullptr && std::strlen(maker) == iter->m_maker.size()) { + std::memcpy(iter->m_maker.data(), maker, iter->m_maker.size()); + } + + return &*iter; } File* Directory::getFirstNonFreeFile(uint32_t start, const char* game, const char* maker) { - for (uint16_t i = start; i < 127; i++) { - if (m_files[i].m_game[0] != 0xFF) { - File* ret = &m_files[i]; - if (game && std::strlen(game) == 4 && std::strncmp(reinterpret_cast(ret->m_game), game, 4) != 0) - continue; - if (maker && std::strlen(maker) == 2 && std::strncmp(reinterpret_cast(ret->m_maker), maker, 2) != 0) - continue; - return ret; + const auto iter = std::find_if(m_files.begin(), m_files.end(), [game, maker](const auto& file) { + if (file.m_game[0] == 0xFF) { + return false; } + + const auto* const game_ptr = reinterpret_cast(file.m_game.data()); + const auto game_size = file.m_game.size(); + if (game != nullptr && std::strlen(game) == game_size && std::strncmp(game_ptr, game, game_size) != 0) { + return false; + } + + const auto* const maker_ptr = reinterpret_cast(file.m_maker.data()); + const auto maker_size = file.m_maker.size(); + if (maker != nullptr && std::strlen(maker) == maker_size && std::strncmp(maker_ptr, maker, maker_size) != 0) { + return false; + } + + return true; + }); + + if (iter == m_files.cend()) { + return nullptr; } - return nullptr; + return &*iter; } File* Directory::getFile(const char* game, const char* maker, const char* filename) { - for (uint16_t i = 0; i < 127; i++) { - if (game && strlen(game) == 4 && memcmp(m_files[i].m_game, game, 4)) - continue; - if (maker && strlen(maker) == 2 && memcmp(m_files[i].m_maker, maker, 2)) - continue; - if (!strcmp(m_files[i].m_filename, filename)) - return &m_files[i]; + const auto iter = std::find_if(m_files.begin(), m_files.end(), [=](const auto& file) { + const auto game_size = file.m_game.size(); + if (game != nullptr && std::strlen(game) == game_size && std::memcmp(file.m_game.data(), game, game_size) != 0) { + return false; + } + + const auto maker_size = file.m_maker.size(); + if (maker != nullptr && std::strlen(maker) == maker_size && + std::memcmp(file.m_maker.data(), maker, maker_size) != 0) { + return false; + } + + return std::strcmp(file.m_filename, filename) == 0; + }); + + if (iter == m_files.cend()) { + return nullptr; } - return nullptr; + return &*iter; } File* Directory::getFile(uint32_t idx) { - if (idx >= 127) + if (idx >= m_files.size()) { return nullptr; + } return &m_files[idx]; } int32_t Directory::indexForFile(File* f) { - if (!f) + if (f == nullptr) { return -1; + } - auto it = std::find_if(std::begin(m_files), std::end(m_files), [&f](const File& file) -> bool { return f == &file; }); - if (it == std::end(m_files)) + const auto it = std::find_if(std::cbegin(m_files), std::cend(m_files), [&f](const File& file) { return f == &file; }); + if (it == std::cend(m_files)) { return -1; - return it - std::begin(m_files); + } + + return it - std::cbegin(m_files); } } // namespace kabufuda diff --git a/lib/kabufuda/File.cpp b/lib/kabufuda/File.cpp index 821994f..2afd3ba 100644 --- a/lib/kabufuda/File.cpp +++ b/lib/kabufuda/File.cpp @@ -1,18 +1,19 @@ #include "kabufuda/File.hpp" #include +#include #include "kabufuda/Util.hpp" namespace kabufuda { -File::File() { memset(__raw, 0xFF, 0x40); } +File::File() { raw.fill(0xFF); } -File::File(char data[]) { memcpy(__raw, data, 0x40); } +File::File(char data[]) { std::memcpy(raw.data(), data, raw.size()); } File::File(const char* filename) { - memset(__raw, 0, 0x40); - memset(m_filename, 0, 32); - strncpy(m_filename, filename, 32); + raw.fill(0); + std::memset(m_filename, 0, std::size(m_filename)); + std::strncpy(m_filename, filename, std::size(m_filename)); } void File::swapEndian() { m_modifiedTime = SBig(m_modifiedTime);