diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..6098e1f --- /dev/null +++ b/.clang-format @@ -0,0 +1,41 @@ +--- +# We'll use defaults from the LLVM style, but with 4 columns indentation. +BasedOnStyle: LLVM +IndentWidth: 2 +--- +Language: Cpp +DeriveLineEnding: false +UseCRLF: true +DerivePointerAlignment: false +PointerAlignment: Left +AlignConsecutiveAssignments: true +AllowShortFunctionsOnASingleLine: Inline +AllowShortIfStatementsOnASingleLine: Never +AllowShortLambdasOnASingleLine: Empty +AlwaysBreakTemplateDeclarations: Yes +AccessModifierOffset: -2 +AlignTrailingComments: true +SpacesBeforeTrailingComments: 2 +NamespaceIndentation: Inner +MaxEmptyLinesToKeep: 1 +BreakBeforeBraces: Custom +BraceWrapping: + AfterCaseLabel: false + AfterClass: true + AfterControlStatement: false + AfterEnum: true + AfterFunction: true + AfterNamespace: true + AfterStruct: true + AfterUnion: true + AfterExternBlock: true + BeforeCatch: false + BeforeElse: false + BeforeLambdaBody: false + BeforeWhile: false + IndentBraces: false + SplitEmptyFunction: false + SplitEmptyRecord: false + SplitEmptyNamespace: true +ColumnLimit: 88 +ForEachMacros: ['Q_FOREACH', 'foreach'] diff --git a/src/game_starfield_en.ts b/src/game_starfield_en.ts index 25f56fc..df8298c 100644 --- a/src/game_starfield_en.ts +++ b/src/game_starfield_en.ts @@ -4,12 +4,12 @@ GameStarfield - + Starfield Support Plugin - + Adds support for the game Starfield. diff --git a/src/gamestarfield.cpp b/src/gamestarfield.cpp index 1adddb0..b6aaf2e 100644 --- a/src/gamestarfield.cpp +++ b/src/gamestarfield.cpp @@ -1,19 +1,19 @@ #include "gamestarfield.h" +#include "starfieldbsainvalidation.h" #include "starfielddataarchives.h" -#include "starfieldscriptextender.h" -#include "starfieldunmanagedmods.h" +#include "starfieldgameplugins.h" #include "starfieldmoddatachecker.h" #include "starfieldmoddatacontent.h" -#include "starfieldgameplugins.h" #include "starfieldsavegame.h" -#include "starfieldbsainvalidation.h" +#include "starfieldscriptextender.h" +#include "starfieldunmanagedmods.h" -#include +#include "versioninfo.h" #include #include #include -#include "versioninfo.h" +#include #include #include @@ -30,11 +30,9 @@ using namespace MOBase; -GameStarfield::GameStarfield() -{ -} +GameStarfield::GameStarfield() {} -bool GameStarfield::init(IOrganizer *moInfo) +bool GameStarfield::init(IOrganizer* moInfo) { if (!GameGamebryo::init(moInfo)) { return false; @@ -42,13 +40,15 @@ bool GameStarfield::init(IOrganizer *moInfo) registerFeature(new StarfieldScriptExtender(this)); registerFeature(new StarfieldDataArchives(myGamesPath())); - registerFeature(new GamebryoLocalSavegames(myGamesPath(), "StarfieldCustom.ini")); + registerFeature( + new GamebryoLocalSavegames(myGamesPath(), "StarfieldCustom.ini")); registerFeature(new StarfieldModDataChecker(this)); registerFeature(new StarfieldModDataContent(this)); registerFeature(new GamebryoSaveGameInfo(this)); registerFeature(new StarfieldGamePlugins(moInfo)); registerFeature(new StarfieldUnmangedMods(this)); - registerFeature(new StarfieldBSAInvalidation(feature(), this)); + registerFeature( + new StarfieldBSAInvalidation(feature(), this)); return true; } @@ -60,23 +60,25 @@ QString GameStarfield::gameName() const void GameStarfield::detectGame() { - m_GamePath = identifyGamePath(); + m_GamePath = identifyGamePath(); m_MyGamesPath = determineMyGamesPath("Starfield"); } QString GameStarfield::identifyGamePath() const { QString path = "Software\\Valve\\Steam"; - QString steamLocation = findInRegistry(HKEY_CURRENT_USER, path.toStdWString().c_str(), L"SteamPath"); + QString steamLocation = + findInRegistry(HKEY_CURRENT_USER, path.toStdWString().c_str(), L"SteamPath"); if (!steamLocation.isEmpty()) { QString steamLibraryLocation; - QString steamLibraries(steamLocation + "\\" + "config" + "\\" + "libraryfolders.vdf"); + QString steamLibraries(steamLocation + "\\" + "config" + "\\" + + "libraryfolders.vdf"); if (QFile(steamLibraries).exists()) { std::ifstream file(steamLibraries.toStdString()); auto root = tyti::vdf::read(file); for (auto child : root.childs) { - tyti::vdf::object *library = child.second.get(); - auto apps = library->childs["apps"]; + tyti::vdf::object* library = child.second.get(); + auto apps = library->childs["apps"]; if (apps->attribs.contains(steamAPPId().toStdString())) { steamLibraryLocation = QString::fromStdString(library->attribs["path"]); break; @@ -84,8 +86,10 @@ QString GameStarfield::identifyGamePath() const } } if (!steamLibraryLocation.isEmpty()) { - QString gameLocation = steamLibraryLocation + "\\" + "steamapps" + "\\" + "common" + "\\" + "Starfield"; - if (QDir(gameLocation).exists() && QFile(gameLocation + "\\" + "Starfield.exe").exists()) + QString gameLocation = steamLibraryLocation + "\\" + "steamapps" + "\\" + + "common" + "\\" + "Starfield"; + if (QDir(gameLocation).exists() && + QFile(gameLocation + "\\" + "Starfield.exe").exists()) return gameLocation; } } @@ -110,9 +114,9 @@ QMap GameStarfield::secondaryDataDirectories() const QList GameStarfield::executables() const { return QList() - << ExecutableInfo("SFSE", findInGameFolder(feature()->loaderName())) - << ExecutableInfo("Starfield", findInGameFolder(binaryName())) - ; + << ExecutableInfo("SFSE", + findInGameFolder(feature()->loaderName())) + << ExecutableInfo("Starfield", findInGameFolder(binaryName())); } QList GameStarfield::executableForcedLoads() const @@ -130,7 +134,6 @@ QString GameStarfield::localizedName() const return tr("Starfield Support Plugin"); } - QString GameStarfield::author() const { return "Silarn"; @@ -151,16 +154,17 @@ QList GameStarfield::settings() const return QList(); } -void GameStarfield::initializeProfile(const QDir &path, ProfileSettings settings) const +void GameStarfield::initializeProfile(const QDir& path, ProfileSettings settings) const { if (settings.testFlag(IPluginGame::MODS)) { copyToProfile(localAppFolder() + "/Starfield", path, "plugins.txt"); } if (settings.testFlag(IPluginGame::CONFIGURATION)) { - if (settings.testFlag(IPluginGame::PREFER_DEFAULTS) - || !QFileInfo(myGamesPath() + "/Starfield.ini").exists()) { - copyToProfile(gameDirectory().absolutePath(), path, "StarfieldDefault.ini", "Starfield.ini"); + if (settings.testFlag(IPluginGame::PREFER_DEFAULTS) || + !QFileInfo(myGamesPath() + "/Starfield.ini").exists()) { + copyToProfile(gameDirectory().absolutePath(), path, "StarfieldDefault.ini", + "Starfield.ini"); } else { copyToProfile(myGamesPath(), path, "Starfield.ini"); } @@ -180,7 +184,8 @@ QString GameStarfield::savegameSEExtension() const return "sfse"; } -std::shared_ptr GameStarfield::makeSaveGame(QString filePath) const +std::shared_ptr +GameStarfield::makeSaveGame(QString filePath) const { return std::make_shared(filePath, this); } @@ -190,8 +195,10 @@ QString GameStarfield::steamAPPId() const return "1716740"; } -QStringList GameStarfield::primaryPlugins() const { - QStringList plugins = { "Starfield.esm", "Constellation.esm", "OldMars.esm", "BlueprintShips-Starfield.esm" }; +QStringList GameStarfield::primaryPlugins() const +{ + QStringList plugins = {"Starfield.esm", "Constellation.esm", "OldMars.esm", + "BlueprintShips-Starfield.esm"}; plugins.append(CCPlugins()); @@ -200,7 +207,7 @@ QStringList GameStarfield::primaryPlugins() const { QStringList GameStarfield::gameVariants() const { - return { "Regular" }; + return {"Regular"}; } QString GameStarfield::gameShortName() const @@ -215,7 +222,7 @@ QString GameStarfield::gameNexusName() const QStringList GameStarfield::iniFiles() const { - return { "Starfield.ini", "StarfieldPrefs.ini", "StarfieldCustom.ini" }; + return {"Starfield.ini", "StarfieldPrefs.ini", "StarfieldCustom.ini"}; } QStringList GameStarfield::DLCPlugins() const @@ -228,7 +235,9 @@ QStringList GameStarfield::CCPlugins() const QStringList plugins = {}; QFile file(gameDirectory().absoluteFilePath("Starfield.ccc")); if (file.open(QIODevice::ReadOnly)) { - ON_BLOCK_EXIT([&file]() { file.close(); }); + ON_BLOCK_EXIT([&file]() { + file.close(); + }); if (file.size() == 0) { return plugins; diff --git a/src/gamestarfield.h b/src/gamestarfield.h index 1c36add..4b04d7f 100644 --- a/src/gamestarfield.h +++ b/src/gamestarfield.h @@ -1,7 +1,6 @@ #ifndef GAMESTARFIELD_H #define GAMESTARFIELD_H - #include "gamegamebryo.h" #include @@ -14,20 +13,20 @@ class GameStarfield : public GameGamebryo Q_PLUGIN_METADATA(IID "org.modorganizer.GameStarfield" FILE "gamestarfield.json") public: - GameStarfield(); - virtual bool init(MOBase::IOrganizer *moInfo) override; - -public: // IPluginGame interface + virtual bool init(MOBase::IOrganizer* moInfo) override; +public: // IPluginGame interface virtual QString gameName() const override; virtual void detectGame() override; virtual QDir dataDirectory() const override; virtual QMap secondaryDataDirectories() const override; virtual QList executables() const override; - virtual QList executableForcedLoads() const override; - virtual void initializeProfile(const QDir &path, ProfileSettings settings) const override; + virtual QList + executableForcedLoads() const override; + virtual void initializeProfile(const QDir& path, + ProfileSettings settings) const override; virtual QString steamAPPId() const override; virtual QStringList primaryPlugins() const override; virtual QStringList gameVariants() const override; @@ -40,8 +39,7 @@ public: // IPluginGame interface virtual int nexusModOrganizerID() const override; virtual int nexusGameID() const override; -public: // IPlugin interface - +public: // IPlugin interface virtual QString name() const override; virtual QString localizedName() const override; virtual QString author() const override; @@ -50,12 +48,10 @@ public: // IPlugin interface virtual QList settings() const override; protected: - virtual QString identifyGamePath() const override; std::shared_ptr makeSaveGame(QString filePath) const override; QString savegameExtension() const override; QString savegameSEExtension() const override; - }; -#endif // GAMEStarfield_H +#endif // GAMEStarfield_H diff --git a/src/starfieldbsainvalidation.cpp b/src/starfieldbsainvalidation.cpp index cb091b9..a0c2d10 100644 --- a/src/starfieldbsainvalidation.cpp +++ b/src/starfieldbsainvalidation.cpp @@ -3,15 +3,16 @@ #include "dummybsa.h" #include "iplugingame.h" #include "iprofile.h" +#include "registry.h" #include #include -#include "registry.h" -StarfieldBSAInvalidation::StarfieldBSAInvalidation(DataArchives *dataArchives, MOBase::IPluginGame const *game) - : GamebryoBSAInvalidation(dataArchives, "StarfieldCustom.ini", game) +StarfieldBSAInvalidation::StarfieldBSAInvalidation(DataArchives* dataArchives, + MOBase::IPluginGame const* game) + : GamebryoBSAInvalidation(dataArchives, "StarfieldCustom.ini", game) { m_IniFileName = "StarfieldCustom.ini"; - m_Game = game; + m_Game = game; } bool StarfieldBSAInvalidation::isInvalidationBSA(const QString& bsaName) @@ -31,28 +32,34 @@ unsigned long StarfieldBSAInvalidation::bsaVersion() const bool StarfieldBSAInvalidation::prepareProfile(MOBase::IProfile* profile) { - bool dirty = false; - QString basePath - = profile->localSettingsEnabled() - ? profile->absolutePath() - : m_Game->documentsDirectory().absolutePath(); + bool dirty = false; + QString basePath = profile->localSettingsEnabled() + ? profile->absolutePath() + : m_Game->documentsDirectory().absolutePath(); QString iniFilePath = basePath + "/" + m_IniFileName; WCHAR setting[MAX_PATH]; if (profile->invalidationActive(nullptr)) { // write bInvalidateOlderFiles = 1, if needed - if (!::GetPrivateProfileStringW(L"Archive", L"bInvalidateOlderFiles", L"0", setting, MAX_PATH, iniFilePath.toStdWString().c_str()) - || wcstol(setting, nullptr, 10) != 1) { + if (!::GetPrivateProfileStringW(L"Archive", L"bInvalidateOlderFiles", L"0", setting, + MAX_PATH, iniFilePath.toStdWString().c_str()) || + wcstol(setting, nullptr, 10) != 1) { dirty = true; - if (!MOBase::WriteRegistryValue(L"Archive", L"bInvalidateOlderFiles", L"1", iniFilePath.toStdWString().c_str())) { - qWarning("failed to override data directory in \"%s\"", qUtf8Printable(m_IniFileName)); + if (!MOBase::WriteRegistryValue(L"Archive", L"bInvalidateOlderFiles", L"1", + iniFilePath.toStdWString().c_str())) { + qWarning("failed to override data directory in \"%s\"", + qUtf8Printable(m_IniFileName)); } } - if (!::GetPrivateProfileStringW(L"Archive", L"sResourceDataDirsFinal", L"STRINGS\\", setting, MAX_PATH, iniFilePath.toStdWString().c_str()) - || wcscmp(setting, L"") != 0) { + if (!::GetPrivateProfileStringW(L"Archive", L"sResourceDataDirsFinal", L"STRINGS\\", + setting, MAX_PATH, + iniFilePath.toStdWString().c_str()) || + wcscmp(setting, L"") != 0) { dirty = true; - if (!MOBase::WriteRegistryValue(L"Archive", L"sResourceDataDirsFinal", L"", iniFilePath.toStdWString().c_str())) { - qWarning("failed to override data directory in \"%s\"", qUtf8Printable(m_IniFileName)); + if (!MOBase::WriteRegistryValue(L"Archive", L"sResourceDataDirsFinal", L"", + iniFilePath.toStdWString().c_str())) { + qWarning("failed to override data directory in \"%s\"", + qUtf8Printable(m_IniFileName)); } } } diff --git a/src/starfieldbsainvalidation.h b/src/starfieldbsainvalidation.h index b530634..36d3637 100644 --- a/src/starfieldbsainvalidation.h +++ b/src/starfieldbsainvalidation.h @@ -1,36 +1,32 @@ #ifndef STARFIELDBSAINVALIDATION_H #define STARFIELDBSAINVALIDATION_H - -#include -#include #include "gamebryobsainvalidation.h" #include "starfielddataarchives.h" +#include +#include #include -namespace MOBase { - class IPluginGame; +namespace MOBase +{ +class IPluginGame; } class StarfieldBSAInvalidation : public GamebryoBSAInvalidation { public: - - StarfieldBSAInvalidation(DataArchives *dataArchives, MOBase::IPluginGame const *game); + StarfieldBSAInvalidation(DataArchives* dataArchives, MOBase::IPluginGame const* game); virtual bool isInvalidationBSA(const QString& bsaName) override; virtual bool prepareProfile(MOBase::IProfile* profile) override; private: - virtual QString invalidationBSAName() const override; virtual unsigned long bsaVersion() const override; private: - QString m_IniFileName; MOBase::IPluginGame const* m_Game; - }; -#endif // STARFIELDBSAINVALIDATION_H +#endif // STARFIELDBSAINVALIDATION_H diff --git a/src/starfielddataarchives.cpp b/src/starfielddataarchives.cpp index f90d19b..713ede1 100644 --- a/src/starfielddataarchives.cpp +++ b/src/starfielddataarchives.cpp @@ -3,75 +3,77 @@ #include "iprofile.h" #include -StarfieldDataArchives::StarfieldDataArchives(const QDir &myGamesDir) : - GamebryoDataArchives(myGamesDir) +StarfieldDataArchives::StarfieldDataArchives(const QDir& myGamesDir) + : GamebryoDataArchives(myGamesDir) {} QStringList StarfieldDataArchives::vanillaArchives() const { - return { "Starfield - Animations.ba2" - , "Starfield - DensityMaps.ba2" - , "Starfield - FaceAnimation01.ba2" - , "Starfield - FaceAnimation02.ba2" - , "Starfield - FaceAnimation03.ba2" - , "Starfield - FaceAnimation04.ba2" - , "Starfield - FaceAnimationPatch.ba2" - , "Starfield - FaceMeshes.ba2" - , "Starfield - GeneratedTextures.ba2" - , "Starfield - Interface.ba2" - , "Starfield - Localization.ba2" - , "Starfield - LODMeshes.ba2" - , "Starfield - LODMeshesPatch.ba2" - , "Starfield - LODTextures.ba2" - , "Starfield - Materials.ba2" - , "Starfield - Meshes01.ba2" - , "Starfield - Meshes02.ba2" - , "Starfield - MeshesPatch.ba2" - , "Starfield - Misc.ba2" - , "Starfield - Particles.ba2" - , "Starfield - ParticlesTestData.ba2" - , "Starfield - PlanetData.ba2" - , "Starfield - Shaders.ba2" - , "Starfield - ShadersBeta.ba2" - , "Starfield - Terrain01.ba2" - , "Starfield - Terrain02.ba2" - , "Starfield - Terrain03.ba2" - , "Starfield - Terrain04.ba2" - , "Starfield - TerrainPatch.ba2" - , "Starfield - Textures01.ba2" - , "Starfield - Textures02.ba2" - , "Starfield - Textures03.ba2" - , "Starfield - Textures04.ba2" - , "Starfield - Textures05.ba2" - , "Starfield - Textures06.ba2" - , "Starfield - Textures07.ba2" - , "Starfield - Textures08.ba2" - , "Starfield - Textures09.ba2" - , "Starfield - Textures10.ba2" - , "Starfield - Textures11.ba2" - , "Starfield - TexturesPatch.ba2" - , "Starfield - Voices01.ba2" - , "Starfield - Voices02.ba2" - , "Starfield - VoicesPatch.ba2" - , "Starfield - WwiseSounds01.ba2" - , "Starfield - WwiseSounds02.ba2" - , "Starfield - WwiseSounds03.ba2" - , "Starfield - WwiseSounds04.ba2" - , "Starfield - WwiseSounds05.ba2" - , "Starfield - WwiseSoundsPatch.ba2" - , "Constellation - Localization.ba2" - , "Constellation - Textures.ba2" - , "OldMars - Localization.ba2" - , "OldMars - Textures.ba2" - , "BlueprintShips-Starfield - Localization.ba2" }; + return {"Starfield - Animations.ba2", + "Starfield - DensityMaps.ba2", + "Starfield - FaceAnimation01.ba2", + "Starfield - FaceAnimation02.ba2", + "Starfield - FaceAnimation03.ba2", + "Starfield - FaceAnimation04.ba2", + "Starfield - FaceAnimationPatch.ba2", + "Starfield - FaceMeshes.ba2", + "Starfield - GeneratedTextures.ba2", + "Starfield - Interface.ba2", + "Starfield - Localization.ba2", + "Starfield - LODMeshes.ba2", + "Starfield - LODMeshesPatch.ba2", + "Starfield - LODTextures.ba2", + "Starfield - Materials.ba2", + "Starfield - Meshes01.ba2", + "Starfield - Meshes02.ba2", + "Starfield - MeshesPatch.ba2", + "Starfield - Misc.ba2", + "Starfield - Particles.ba2", + "Starfield - ParticlesTestData.ba2", + "Starfield - PlanetData.ba2", + "Starfield - Shaders.ba2", + "Starfield - ShadersBeta.ba2", + "Starfield - Terrain01.ba2", + "Starfield - Terrain02.ba2", + "Starfield - Terrain03.ba2", + "Starfield - Terrain04.ba2", + "Starfield - TerrainPatch.ba2", + "Starfield - Textures01.ba2", + "Starfield - Textures02.ba2", + "Starfield - Textures03.ba2", + "Starfield - Textures04.ba2", + "Starfield - Textures05.ba2", + "Starfield - Textures06.ba2", + "Starfield - Textures07.ba2", + "Starfield - Textures08.ba2", + "Starfield - Textures09.ba2", + "Starfield - Textures10.ba2", + "Starfield - Textures11.ba2", + "Starfield - TexturesPatch.ba2", + "Starfield - Voices01.ba2", + "Starfield - Voices02.ba2", + "Starfield - VoicesPatch.ba2", + "Starfield - WwiseSounds01.ba2", + "Starfield - WwiseSounds02.ba2", + "Starfield - WwiseSounds03.ba2", + "Starfield - WwiseSounds04.ba2", + "Starfield - WwiseSounds05.ba2", + "Starfield - WwiseSoundsPatch.ba2", + "Constellation - Localization.ba2", + "Constellation - Textures.ba2", + "OldMars - Localization.ba2", + "OldMars - Textures.ba2", + "BlueprintShips-Starfield - Localization.ba2"}; } - -QStringList StarfieldDataArchives::archives(const MOBase::IProfile *profile) const +QStringList StarfieldDataArchives::archives(const MOBase::IProfile* profile) const { QStringList result; - QString iniFile = profile->localSettingsEnabled() ? QDir(profile->absolutePath()).absoluteFilePath("Starfield.ini") : m_LocalGameDir.absoluteFilePath("Starfield.ini"); + QString iniFile = + profile->localSettingsEnabled() + ? QDir(profile->absolutePath()).absoluteFilePath("Starfield.ini") + : m_LocalGameDir.absoluteFilePath("Starfield.ini"); result.append(getArchivesFromKey(iniFile, "SResourceArchiveList")); result.append(getArchivesFromKey(iniFile, "sResourceIndexFileList")); result.append(getArchivesFromKey(iniFile, "SResourceArchiveMemoryCacheList")); @@ -81,11 +83,15 @@ QStringList StarfieldDataArchives::archives(const MOBase::IProfile *profile) con return result; } -void StarfieldDataArchives::writeArchiveList(MOBase::IProfile *profile, const QStringList &before) +void StarfieldDataArchives::writeArchiveList(MOBase::IProfile* profile, + const QStringList& before) { QString list = before.join(", "); - QString iniFile = profile->localSettingsEnabled() ? QDir(profile->absolutePath()).absoluteFilePath("Starfield.ini") : m_LocalGameDir.absoluteFilePath("Starfield.ini"); + QString iniFile = + profile->localSettingsEnabled() + ? QDir(profile->absolutePath()).absoluteFilePath("Starfield.ini") + : m_LocalGameDir.absoluteFilePath("Starfield.ini"); if (list.length() > 255) { int splitIdx = list.lastIndexOf(",", 256); setArchivesToKey(iniFile, "SResourceArchiveList", list.mid(0, splitIdx)); diff --git a/src/starfielddataarchives.h b/src/starfielddataarchives.h index 7738085..613127f 100644 --- a/src/starfielddataarchives.h +++ b/src/starfielddataarchives.h @@ -3,27 +3,27 @@ #include "gamebryodataarchives.h" -namespace MOBase { class IProfile; } +namespace MOBase +{ +class IProfile; +} -#include #include +#include class StarfieldDataArchives : public GamebryoDataArchives { public: - - StarfieldDataArchives(const QDir &myGamesDir); + StarfieldDataArchives(const QDir& myGamesDir); public: - virtual QStringList vanillaArchives() const override; - virtual QStringList archives(const MOBase::IProfile *profile) const override; + virtual QStringList archives(const MOBase::IProfile* profile) const override; private: - - virtual void writeArchiveList(MOBase::IProfile *profile, const QStringList &before) override; - + virtual void writeArchiveList(MOBase::IProfile* profile, + const QStringList& before) override; }; -#endif // STARFIELDDATAARCHIVES_H +#endif // STARFIELDDATAARCHIVES_H diff --git a/src/starfieldgameplugins.cpp b/src/starfieldgameplugins.cpp index 204b4cd..b346e87 100644 --- a/src/starfieldgameplugins.cpp +++ b/src/starfieldgameplugins.cpp @@ -2,11 +2,11 @@ using namespace MOBase; -StarfieldGamePlugins::StarfieldGamePlugins(MOBase::IOrganizer* organizer) : CreationGamePlugins(organizer) -{ -} +StarfieldGamePlugins::StarfieldGamePlugins(MOBase::IOrganizer* organizer) + : CreationGamePlugins(organizer) +{} bool StarfieldGamePlugins::overridePluginsAreSupported() { - return true; + return true; } \ No newline at end of file diff --git a/src/starfieldgameplugins.h b/src/starfieldgameplugins.h index 1f298be..1f21bd5 100644 --- a/src/starfieldgameplugins.h +++ b/src/starfieldgameplugins.h @@ -10,13 +10,10 @@ class StarfieldGamePlugins : public CreationGamePlugins { public: - - StarfieldGamePlugins(MOBase::IOrganizer* organizer); + StarfieldGamePlugins(MOBase::IOrganizer* organizer); protected: - - virtual bool overridePluginsAreSupported() override; - + virtual bool overridePluginsAreSupported() override; }; -#endif // _STARFIELDGAMEPLUGINS_H \ No newline at end of file +#endif // _STARFIELDGAMEPLUGINS_H \ No newline at end of file diff --git a/src/starfieldmoddatachecker.h b/src/starfieldmoddatachecker.h index 31136c6..1fa1c5e 100644 --- a/src/starfieldmoddatachecker.h +++ b/src/starfieldmoddatachecker.h @@ -9,20 +9,21 @@ public: using GamebryoModDataChecker::GamebryoModDataChecker; protected: - virtual const FileNameSet& possibleFolderNames() const override { + virtual const FileNameSet& possibleFolderNames() const override + { static FileNameSet result{ - "interface", "meshes", "music", "scripts", "sound", "strings", "textures", - "trees", "video", "materials", "sfse", "distantlod", "asi", "Tools", "MCM", - "distantland", "mits", "dllplugins", "CalienteTools", "shadersfx", "aaf" - }; + "interface", "meshes", "music", "scripts", "sound", "strings", + "textures", "trees", "video", "materials", "sfse", "distantlod", + "asi", "Tools", "MCM", "distantland", "mits", "dllplugins", + "CalienteTools", "shadersfx", "aaf"}; return result; } - virtual const FileNameSet& possibleFileExtensions() const override { - static FileNameSet result{ - "esp", "esm", "esl", "ba2", "modgroups", "ini", "csg", "cdx" - }; + virtual const FileNameSet& possibleFileExtensions() const override + { + static FileNameSet result{"esp", "esm", "esl", "ba2", + "modgroups", "ini", "csg", "cdx"}; return result; } }; -#endif // STARFIELD_MODATACHECKER_H +#endif // STARFIELD_MODATACHECKER_H diff --git a/src/starfieldmoddatacontent.h b/src/starfieldmoddatacontent.h index 1e6930b..325c64f 100644 --- a/src/starfieldmoddatacontent.h +++ b/src/starfieldmoddatacontent.h @@ -4,15 +4,17 @@ #include #include -class StarfieldModDataContent : public GamebryoModDataContent { +class StarfieldModDataContent : public GamebryoModDataContent +{ protected: - enum StarfieldContent { + enum StarfieldContent + { CONTENT_MATERIAL = CONTENT_NEXT_VALUE }; public: - StarfieldModDataContent(GameGamebryo const* gamePlugin) : - GamebryoModDataContent(gamePlugin) + StarfieldModDataContent(GameGamebryo const* gamePlugin) + : GamebryoModDataContent(gamePlugin) { m_Enabled[CONTENT_SKYPROC] = false; } @@ -20,22 +22,23 @@ public: std::vector getAllContents() const override { auto contents = GamebryoModDataContent::getAllContents(); - contents.push_back(Content(CONTENT_MATERIAL, "Materials", ":/MO/gui/content/material")); + contents.push_back( + Content(CONTENT_MATERIAL, "Materials", ":/MO/gui/content/material")); return contents; } - std::vector getContentsFor( - std::shared_ptr fileTree) const override + std::vector + getContentsFor(std::shared_ptr fileTree) const override { auto contents = GamebryoModDataContent::getContentsFor(fileTree); for (auto e : *fileTree) { if (e->compare("materials") == 0) { contents.push_back(CONTENT_MATERIAL); - break; // Early break if you have nothing else to check. + break; // Early break if you have nothing else to check. } } return contents; } }; -#endif // STARFIELD_MODDATACONTENT_H \ No newline at end of file +#endif // STARFIELD_MODDATACONTENT_H \ No newline at end of file diff --git a/src/starfieldsavegame.cpp b/src/starfieldsavegame.cpp index f15729c..f5a2710 100644 --- a/src/starfieldsavegame.cpp +++ b/src/starfieldsavegame.cpp @@ -4,114 +4,110 @@ #include "gamestarfield.h" -StarfieldSaveGame::StarfieldSaveGame(QString const &fileName, GameStarfield const* game) : - GamebryoSaveGame(fileName, game, true) +StarfieldSaveGame::StarfieldSaveGame(QString const& fileName, GameStarfield const* game) + : GamebryoSaveGame(fileName, game, true) { FileWrapper file(getFilepath(), "BCPS"); getData(file); FILETIME creationTime; - fetchInformationFields(file, m_SaveNumber, m_PCName, m_PCLevel, m_PCLocation, creationTime); + fetchInformationFields(file, m_SaveNumber, m_PCName, m_PCLevel, m_PCLocation, + creationTime); file.closeCompressedData(); file.close(); - //A file time is a 64-bit value that represents the number of 100-nanosecond - //intervals that have elapsed since 12:00 A.M. January 1, 1601 Coordinated Universal Time (UTC). - //So we need to convert that to something useful + // A file time is a 64-bit value that represents the number of 100-nanosecond + // intervals that have elapsed since 12:00 A.M. January 1, 1601 Coordinated Universal + // Time (UTC). So we need to convert that to something useful SYSTEMTIME ctime; ::FileTimeToSystemTime(&creationTime, &ctime); setCreationTime(ctime); } -void StarfieldSaveGame::getData( - FileWrapper& file) const +void StarfieldSaveGame::getData(FileWrapper& file) const { - file.skip(); // header version - file.skip(); // zip start location - file.skip(); // unknown - file.setCompressionType(1); - file.openCompressedData(); // long = start, long = size - // double - // float - // long - // long - // short - return; + file.skip(); // header version + file.skip(); // zip start location + file.skip(); // unknown + file.setCompressionType(1); + file.openCompressedData(); // long = start, long = size + // double + // float + // long + // long + // short + return; } void StarfieldSaveGame::fetchInformationFields( - FileWrapper& file, - unsigned long& saveNumber, - QString& playerName, - unsigned short& playerLevel, - QString& playerLocation, - FILETIME& creationTime) const + FileWrapper& file, unsigned long& saveNumber, QString& playerName, + unsigned short& playerLevel, QString& playerLocation, FILETIME& creationTime) const { - char fileID[12]; // SFS_SAVEGAME + char fileID[12]; // SFS_SAVEGAME unsigned int headerSize; unsigned int version; unsigned char unknown; - //file.read(fileID, 12); + // file.read(fileID, 12); headerSize = file.readInt(12); - version = file.readInt(); - unknown = file.readChar(); + version = file.readInt(); + unknown = file.readChar(); saveNumber = file.readInt(); file.read(playerName); unsigned int temp; - temp = file.readInt(); + temp = file.readInt(); playerLevel = static_cast(temp); file.read(playerLocation); QString ignore; - file.read(ignore); // playtime as ascii hh.mm.ss - file.read(ignore); // race name (i.e. BretonRace) + file.read(ignore); // playtime as ascii hh.mm.ss + file.read(ignore); // race name (i.e. BretonRace) unsigned short gender; - gender = file.readShort(); // Player gender (0 = male) + gender = file.readShort(); // Player gender (0 = male) float experience, experienceRequired; - experience = file.readFloat(); + experience = file.readFloat(); experienceRequired = file.readFloat(); - unsigned long long time = file.readLong(); - creationTime.dwLowDateTime = (DWORD)time; + unsigned long long time = file.readLong(); + creationTime.dwLowDateTime = (DWORD)time; creationTime.dwHighDateTime = time >> 32; } std::unique_ptr StarfieldSaveGame::fetchDataFields() const { - FileWrapper file(getFilepath(), "BCPS"); //10bytes + FileWrapper file(getFilepath(), "BCPS"); // 10bytes - getData(file); - FILETIME creationTime; + getData(file); + FILETIME creationTime; - { - QString dummyName, dummyLocation; - unsigned short dummyLevel; - unsigned long dummySaveNumber; - FILETIME dummyTime; + { + QString dummyName, dummyLocation; + unsigned short dummyLevel; + unsigned long dummySaveNumber; + FILETIME dummyTime; - fetchInformationFields(file, dummySaveNumber, dummyName, dummyLevel, - dummyLocation, dummyTime); - } + fetchInformationFields(file, dummySaveNumber, dummyName, dummyLevel, dummyLocation, + dummyTime); + } - QString ignore; - std::unique_ptr fields = std::make_unique(); + QString ignore; + std::unique_ptr fields = std::make_unique(); - //fields->Screenshot = file.readImage(384, true); + // fields->Screenshot = file.readImage(384, true); - uint8_t saveGameVersion = file.readChar(12); - file.read(ignore); // game version - file.read(ignore); // game version again? - file.readInt(); // plugin info size + uint8_t saveGameVersion = file.readChar(12); + file.read(ignore); // game version + file.read(ignore); // game version again? + file.readInt(); // plugin info size - fields->Plugins = file.readPlugins(); - if (saveGameVersion >= 82) { - fields->LightPlugins = file.readLightPlugins(); - } - file.closeCompressedData(); - file.close(); + fields->Plugins = file.readPlugins(); + if (saveGameVersion >= 82) { + fields->LightPlugins = file.readLightPlugins(); + } + file.closeCompressedData(); + file.close(); - return fields; + return fields; } diff --git a/src/starfieldsavegame.h b/src/starfieldsavegame.h index a4159f1..d8189bf 100644 --- a/src/starfieldsavegame.h +++ b/src/starfieldsavegame.h @@ -11,25 +11,17 @@ class GameStarfield; class StarfieldSaveGame : public GamebryoSaveGame { public: - StarfieldSaveGame(QString const &fileName, GameStarfield const* game); + StarfieldSaveGame(QString const& fileName, GameStarfield const* game); protected: - // Fetch easy-to-access information. - void getData( - FileWrapper& file - ) const; + void getData(FileWrapper& file) const; - void fetchInformationFields( - FileWrapper& file, - unsigned long& saveNumber, - QString& playerName, - unsigned short& playerLevel, - QString& playerLocation, - FILETIME& creationTime - ) const; + void fetchInformationFields(FileWrapper& file, unsigned long& saveNumber, + QString& playerName, unsigned short& playerLevel, + QString& playerLocation, FILETIME& creationTime) const; std::unique_ptr fetchDataFields() const override; }; -#endif // STARFIELDSAVEGAME_H +#endif // STARFIELDSAVEGAME_H diff --git a/src/starfieldscriptextender.cpp b/src/starfieldscriptextender.cpp index 25ebcf9..15cf6cd 100644 --- a/src/starfieldscriptextender.cpp +++ b/src/starfieldscriptextender.cpp @@ -3,10 +3,9 @@ #include #include -StarfieldScriptExtender::StarfieldScriptExtender(GameGamebryo const *game) : - GamebryoScriptExtender(game) -{ -} +StarfieldScriptExtender::StarfieldScriptExtender(GameGamebryo const* game) + : GamebryoScriptExtender(game) +{} QString StarfieldScriptExtender::BinaryName() const { diff --git a/src/starfieldscriptextender.h b/src/starfieldscriptextender.h index fa29317..b7c27f1 100644 --- a/src/starfieldscriptextender.h +++ b/src/starfieldscriptextender.h @@ -8,11 +8,10 @@ class GameGamebryo; class StarfieldScriptExtender : public GamebryoScriptExtender { public: - StarfieldScriptExtender(GameGamebryo const *game); + StarfieldScriptExtender(GameGamebryo const* game); virtual QString BinaryName() const override; virtual QString PluginPath() const override; - }; -#endif // STARFIELDSCRIPTEXTENDER_H +#endif // STARFIELDSCRIPTEXTENDER_H diff --git a/src/starfieldunmanagedmods.cpp b/src/starfieldunmanagedmods.cpp index ce7dcbb..6b42b22 100644 --- a/src/starfieldunmanagedmods.cpp +++ b/src/starfieldunmanagedmods.cpp @@ -1,27 +1,26 @@ #include "starfieldunmanagedmods.h" - -StarfieldUnmangedMods::StarfieldUnmangedMods(const GameGamebryo *game) - : GamebryoUnmangedMods(game) +StarfieldUnmangedMods::StarfieldUnmangedMods(const GameGamebryo* game) + : GamebryoUnmangedMods(game) {} -StarfieldUnmangedMods::~StarfieldUnmangedMods() -{} +StarfieldUnmangedMods::~StarfieldUnmangedMods() {} -QStringList StarfieldUnmangedMods::mods(bool onlyOfficial) const { +QStringList StarfieldUnmangedMods::mods(bool onlyOfficial) const +{ QStringList result; - QStringList pluginList = game()->primaryPlugins(); + QStringList pluginList = game()->primaryPlugins(); QStringList otherPlugins = game()->DLCPlugins(); otherPlugins.append(game()->CCPlugins()); for (QString plugin : otherPlugins) { pluginList.removeAll(plugin); } QDir dataDir(game()->dataDirectory()); - for (const QString &fileName : dataDir.entryList({ "*.esp", "*.esl", "*.esm" })) { + for (const QString& fileName : dataDir.entryList({"*.esp", "*.esl", "*.esm"})) { if (!pluginList.contains(fileName, Qt::CaseInsensitive)) { if (!onlyOfficial || pluginList.contains(fileName, Qt::CaseInsensitive)) { - result.append(fileName.chopped(4)); // trims the extension off + result.append(fileName.chopped(4)); // trims the extension off } } } @@ -29,17 +28,18 @@ QStringList StarfieldUnmangedMods::mods(bool onlyOfficial) const { return result; } -QStringList StarfieldUnmangedMods::secondaryFiles(const QString &modName) const { +QStringList StarfieldUnmangedMods::secondaryFiles(const QString& modName) const +{ // file extension in FO4 is .ba2 instead of bsa QStringList archives; QDir dataDir = game()->dataDirectory(); - for (const QString &archiveName : dataDir.entryList({modName + "*.ba2"})) { + for (const QString& archiveName : dataDir.entryList({modName + "*.ba2"})) { archives.append(dataDir.absoluteFilePath(archiveName)); } return archives; } -QString StarfieldUnmangedMods::displayName(const QString &modName) const +QString StarfieldUnmangedMods::displayName(const QString& modName) const { // unlike in earlier games, in fallout 4 the file name doesn't correspond to // the public name diff --git a/src/starfieldunmanagedmods.h b/src/starfieldunmanagedmods.h index bea9be8..3b9f2e2 100644 --- a/src/starfieldunmanagedmods.h +++ b/src/starfieldunmanagedmods.h @@ -1,21 +1,18 @@ #ifndef STARFIELDUNMANAGEDMODS_H #define STARFIELDUNMANAGEDMODS_H - #include "gamebryounmanagedmods.h" #include - -class StarfieldUnmangedMods : public GamebryoUnmangedMods { +class StarfieldUnmangedMods : public GamebryoUnmangedMods +{ public: - StarfieldUnmangedMods(const GameGamebryo *game); + StarfieldUnmangedMods(const GameGamebryo* game); ~StarfieldUnmangedMods(); virtual QStringList mods(bool onlyOfficial) const override; - virtual QStringList secondaryFiles(const QString &modName) const override; - virtual QString displayName(const QString &modName) const override; + virtual QStringList secondaryFiles(const QString& modName) const override; + virtual QString displayName(const QString& modName) const override; }; - - -#endif // STARFIELDUNMANAGEDMODS_H +#endif // STARFIELDUNMANAGEDMODS_H diff --git a/src/vdf_parser.h b/src/vdf_parser.h index 415e49f..771ba82 100644 --- a/src/vdf_parser.h +++ b/src/vdf_parser.h @@ -1,50 +1,50 @@ -//MIT License +// MIT License // -//Copyright(c) 2016 Matthias Moeller +// Copyright(c) 2016 Matthias Moeller // -//Permission is hereby granted, free of charge, to any person obtaining a copy -//of this software and associated documentation files(the "Software"), to deal -//in the Software without restriction, including without limitation the rights -//to use, copy, modify, merge, publish, distribute, sublicense, and / or sell -//copies of the Software, and to permit persons to whom the Software is -//furnished to do so, subject to the following conditions : +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files(the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions : // -//The above copyright notice and this permission notice shall be included in all -//copies or substantial portions of the Software. +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. // -//THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -//IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -//FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE -//AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -//LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -//OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -//SOFTWARE. +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. #ifndef __TYTI_STEAM_VDF_PARSER_H__ #define __TYTI_STEAM_VDF_PARSER_H__ -#include -#include -#include -#include -#include -#include -#include #include -#include +#include #include +#include +#include +#include +#include +#include +#include +#include -#include #include +#include -//for wstring support +// for wstring support #include #include // internal #include -//VS < 2015 has only partial C++11 support +// VS < 2015 has only partial C++11 support #if defined(_MSC_VER) && _MSC_VER < 1900 #ifndef CONSTEXPR #define CONSTEXPR @@ -68,651 +68,660 @@ namespace tyti { - namespace vdf +namespace vdf +{ + namespace detail + { + /////////////////////////////////////////////////////////////////////////// + // Helper functions selecting the right encoding (char/wchar_T) + /////////////////////////////////////////////////////////////////////////// + + template + struct literal_macro_help { - namespace detail - { - /////////////////////////////////////////////////////////////////////////// - // Helper functions selecting the right encoding (char/wchar_T) - /////////////////////////////////////////////////////////////////////////// + static CONSTEXPR const char* result(const char* c, const wchar_t*) NOEXCEPT + { + return c; + } + static CONSTEXPR const char result(const char c, const wchar_t) NOEXCEPT + { + return c; + } + }; - template - struct literal_macro_help - { - static CONSTEXPR const char* result(const char* c, const wchar_t*) NOEXCEPT - { - return c; - } - static CONSTEXPR const char result(const char c, const wchar_t) NOEXCEPT - { - return c; - } - }; - - template <> - struct literal_macro_help - { - static CONSTEXPR const wchar_t* result(const char*, const wchar_t* wc) NOEXCEPT - { - return wc; - } - static CONSTEXPR const wchar_t result(const char, const wchar_t wc) NOEXCEPT - { - return wc; - } - }; + template <> + struct literal_macro_help + { + static CONSTEXPR const wchar_t* result(const char*, const wchar_t* wc) NOEXCEPT + { + return wc; + } + static CONSTEXPR const wchar_t result(const char, const wchar_t wc) NOEXCEPT + { + return wc; + } + }; #define TYTI_L(type, text) vdf::detail::literal_macro_help::result(text, L##text) - inline std::string string_converter(const std::string& w) NOEXCEPT - { - return w; - } + inline std::string string_converter(const std::string& w) NOEXCEPT + { + return w; + } - // utility wrapper to adapt locale-bound facets for wstring/wbuffer convert - // from cppreference - template - struct deletable_facet : Facet - { - template - deletable_facet(Args &&... args) : Facet(std::forward(args)...) {} - ~deletable_facet() {} - }; + // utility wrapper to adapt locale-bound facets for wstring/wbuffer convert + // from cppreference + template + struct deletable_facet : Facet + { + template + deletable_facet(Args&&... args) : Facet(std::forward(args)...) + {} + ~deletable_facet() {} + }; - inline std::string string_converter(const std::wstring& w) //todo: use us-locale - { - std::wstring_convert>> conv1; - return conv1.to_bytes(w); - } + inline std::string string_converter(const std::wstring& w) // todo: use us-locale + { + std::wstring_convert>> + conv1; + return conv1.to_bytes(w); + } - /////////////////////////////////////////////////////////////////////////// - // Writer helper functions - /////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////// + // Writer helper functions + /////////////////////////////////////////////////////////////////////////// - template - class tabs - { - const size_t t; + template + class tabs + { + const size_t t; - public: - explicit CONSTEXPR tabs(size_t i) NOEXCEPT : t(i) {} - std::basic_string print() const { return std::basic_string(t, TYTI_L(charT, '\t')); } - inline CONSTEXPR tabs operator+(size_t i) const NOEXCEPT - { - return tabs(t + i); - } - }; + public: + explicit CONSTEXPR tabs(size_t i) NOEXCEPT : t(i) {} + std::basic_string print() const + { + return std::basic_string(t, TYTI_L(charT, '\t')); + } + inline CONSTEXPR tabs operator+(size_t i) const NOEXCEPT { return tabs(t + i); } + }; - template - oStreamT& operator<<(oStreamT& s, const tabs t) - { - s << t.print(); - return s; - } - } // end namespace detail + template + oStreamT& operator<<(oStreamT& s, const tabs t) + { + s << t.print(); + return s; + } + } // end namespace detail - /////////////////////////////////////////////////////////////////////////// - // Interface - /////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////// + // Interface + /////////////////////////////////////////////////////////////////////////// - /// custom objects and their corresponding write functions + /// custom objects and their corresponding write functions - /// basic object node. Every object has a name and can contains attributes saved as key_value pairs or childrens - template - struct basic_object - { - typedef CharT char_type; - std::basic_string name; - std::unordered_map, std::basic_string> attribs; - std::unordered_map, std::shared_ptr>> childs; + /// basic object node. Every object has a name and can contains attributes saved as + /// key_value pairs or childrens + template + struct basic_object + { + typedef CharT char_type; + std::basic_string name; + std::unordered_map, std::basic_string> + attribs; + std::unordered_map, + std::shared_ptr>> + childs; - void add_attribute(std::basic_string key, std::basic_string value) - { - attribs.emplace(std::move(key), std::move(value)); - } - void add_child(std::unique_ptr> child) - { - std::shared_ptr> obj{ child.release() }; - childs.emplace(obj->name, obj); - } - void set_name(std::basic_string n) - { - name = std::move(n); - } - }; + void add_attribute(std::basic_string key, + std::basic_string value) + { + attribs.emplace(std::move(key), std::move(value)); + } + void add_child(std::unique_ptr> child) + { + std::shared_ptr> obj{child.release()}; + childs.emplace(obj->name, obj); + } + void set_name(std::basic_string n) { name = std::move(n); } + }; - template - struct basic_multikey_object - { - typedef CharT char_type; - std::basic_string name; - std::unordered_multimap, std::basic_string> attribs; - std::unordered_multimap, std::shared_ptr>> childs; + template + struct basic_multikey_object + { + typedef CharT char_type; + std::basic_string name; + std::unordered_multimap, std::basic_string> + attribs; + std::unordered_multimap, + std::shared_ptr>> + childs; - void add_attribute(std::basic_string key, std::basic_string value) - { - attribs.emplace(std::move(key), std::move(value)); - } - void add_child(std::unique_ptr> child) - { - std::shared_ptr> obj{ child.release() }; - childs.emplace(obj->name, obj); - } - void set_name(std::basic_string n) - { - name = std::move(n); - } - }; + void add_attribute(std::basic_string key, + std::basic_string value) + { + attribs.emplace(std::move(key), std::move(value)); + } + void add_child(std::unique_ptr> child) + { + std::shared_ptr> obj{child.release()}; + childs.emplace(obj->name, obj); + } + void set_name(std::basic_string n) { name = std::move(n); } + }; - typedef basic_object object; - typedef basic_object wobject; - typedef basic_multikey_object multikey_object; - typedef basic_multikey_object wmultikey_object; + typedef basic_object object; + typedef basic_object wobject; + typedef basic_multikey_object multikey_object; + typedef basic_multikey_object wmultikey_object; - struct Options - { - bool strip_escape_symbols; - bool ignore_all_platform_conditionals; - bool ignore_includes; + struct Options + { + bool strip_escape_symbols; + bool ignore_all_platform_conditionals; + bool ignore_includes; - Options() : strip_escape_symbols(true), ignore_all_platform_conditionals(false), ignore_includes(false) {} - }; + Options() + : strip_escape_symbols(true), ignore_all_platform_conditionals(false), + ignore_includes(false) + {} + }; - //forward decls - //forward decl - template - OutputT read(iStreamT& inStream, const Options& opt = Options{}); + // forward decls + // forward decl + template + OutputT read(iStreamT& inStream, const Options& opt = Options{}); - /** \brief writes given object tree in vdf format to given stream. - Output is prettyfied, using tabs - */ - template - void write(oStreamT& s, const T& r, - const detail::tabs tab = detail::tabs(0)) - { - typedef typename oStreamT::char_type charT; - using namespace detail; - s << tab << TYTI_L(charT, '"') << r.name << TYTI_L(charT, "\"\n") << tab << TYTI_L(charT, "{\n"); - for (const auto& i : r.attribs) - s << tab + 1 << TYTI_L(charT, '"') << i.first << TYTI_L(charT, "\"\t\t\"") << i.second << TYTI_L(charT, "\"\n"); - for (const auto& i : r.childs) - if (i.second) - write(s, *i.second, tab + 1); - s << tab << TYTI_L(charT, "}\n"); - } + /** \brief writes given object tree in vdf format to given stream. + Output is prettyfied, using tabs + */ + template + void write(oStreamT& s, const T& r, + const detail::tabs tab = + detail::tabs(0)) + { + typedef typename oStreamT::char_type charT; + using namespace detail; + s << tab << TYTI_L(charT, '"') << r.name << TYTI_L(charT, "\"\n") << tab + << TYTI_L(charT, "{\n"); + for (const auto& i : r.attribs) + s << tab + 1 << TYTI_L(charT, '"') << i.first << TYTI_L(charT, "\"\t\t\"") + << i.second << TYTI_L(charT, "\"\n"); + for (const auto& i : r.childs) + if (i.second) + write(s, *i.second, tab + 1); + s << tab << TYTI_L(charT, "}\n"); + } - namespace detail - { - template - std::basic_string read_file(iStreamT& inStream) - { - // cache the file - typedef typename iStreamT::char_type charT; - std::basic_string str; - inStream.seekg(0, std::ios::end); - str.resize(static_cast(inStream.tellg())); - if (str.empty()) - return str; + namespace detail + { + template + std::basic_string read_file(iStreamT& inStream) + { + // cache the file + typedef typename iStreamT::char_type charT; + std::basic_string str; + inStream.seekg(0, std::ios::end); + str.resize(static_cast(inStream.tellg())); + if (str.empty()) + return str; - inStream.seekg(0, std::ios::beg); - inStream.read(&str[0], str.size()); - return str; - } + inStream.seekg(0, std::ios::beg); + inStream.read(&str[0], str.size()); + return str; + } - /** \brief Read VDF formatted sequences defined by the range [first, last). - If the file is mailformatted, parser will try to read it until it can. - @param first begin iterator - @param end end iterator - @param exclude_files list of files which cant be included anymore. - prevents circular includes + /** \brief Read VDF formatted sequences defined by the range [first, last). + If the file is mailformatted, parser will try to read it until it can. + @param first begin iterator + @param end end iterator + @param exclude_files list of files which cant be included anymore. + prevents circular includes - can thow: - - "std::runtime_error" if a parsing error occured - - "std::bad_alloc" if not enough memory coup be allocated - */ - template - std::vector> read_internal(IterT first, const IterT last, - std::unordered_set::value_type>>& exclude_files, - const Options& opt) - { - static_assert(std::is_default_constructible::value, - "Output Type must be default constructible (provide constructor without arguments)"); - static_assert(std::is_move_constructible::value, + can thow: + - "std::runtime_error" if a parsing error occured + - "std::bad_alloc" if not enough memory coup be allocated + */ + template + std::vector> + read_internal(IterT first, const IterT last, + std::unordered_set::value_type>>& exclude_files, + const Options& opt) + { + static_assert(std::is_default_constructible::value, + "Output Type must be default constructible (provide constructor " + "without arguments)"); + static_assert(std::is_move_constructible::value, "Output Type must be move constructible"); - typedef typename std::iterator_traits::value_type charT; + typedef typename std::iterator_traits::value_type charT; - const std::basic_string comment_end_str = TYTI_L(charT, "*/"); - const std::basic_string whitespaces = TYTI_L(charT, " \n\v\f\r\t"); + const std::basic_string comment_end_str = TYTI_L(charT, "*/"); + const std::basic_string whitespaces = TYTI_L(charT, " \n\v\f\r\t"); #ifdef WIN32 - std::function&)> is_platform_str = [](const std::basic_string& in) { - return in == TYTI_L(charT, "$WIN32") || in == TYTI_L(charT, "$WINDOWS"); - }; + std::function&)> is_platform_str = + [](const std::basic_string& in) { + return in == TYTI_L(charT, "$WIN32") || in == TYTI_L(charT, "$WINDOWS"); + }; #elif __APPLE__ - // WIN32 stands for pc in general - std::function&)> is_platform_str = [](const std::basic_string& in) { - return in == TYTI_L(charT, "$WIN32") || in == TYTI_L(charT, "$POSIX") || in == TYTI_L(charT, "$OSX"); - }; + // WIN32 stands for pc in general + std::function&)> is_platform_str = + [](const std::basic_string& in) { + return in == TYTI_L(charT, "$WIN32") || in == TYTI_L(charT, "$POSIX") || + in == TYTI_L(charT, "$OSX"); + }; #elif __linux__ - // WIN32 stands for pc in general - std::function&)> is_platform_str = [](const std::basic_string& in) { - return in == TYTI_L(charT, "$WIN32") || in == TYTI_L(charT, "$POSIX") || in == TYTI_L(charT, "$LINUX"); - }; + // WIN32 stands for pc in general + std::function&)> is_platform_str = + [](const std::basic_string& in) { + return in == TYTI_L(charT, "$WIN32") || in == TYTI_L(charT, "$POSIX") || + in == TYTI_L(charT, "$LINUX"); + }; #else - std::function&)> is_platform_str = [](const std::basic_string& in) { - return false; - }; + std::function&)> is_platform_str = + [](const std::basic_string& in) { + return false; + }; #endif - if (opt.ignore_all_platform_conditionals) - is_platform_str = [](const std::basic_string&) { - return false; - }; + if (opt.ignore_all_platform_conditionals) + is_platform_str = [](const std::basic_string&) { + return false; + }; - // function for skipping a comment block - // iter: iterator poition to the position after a '/' - auto skip_comments = [&comment_end_str](IterT iter, const IterT& last) -> IterT { - ++iter; - if (iter != last) - { - if (*iter == TYTI_L(charT, '/')) - { - // line comment, skip whole line - iter = std::find(iter + 1, last, TYTI_L(charT, '\n')); - } + // function for skipping a comment block + // iter: iterator poition to the position after a '/' + auto skip_comments = [&comment_end_str](IterT iter, const IterT& last) -> IterT { + ++iter; + if (iter != last) { + if (*iter == TYTI_L(charT, '/')) { + // line comment, skip whole line + iter = std::find(iter + 1, last, TYTI_L(charT, '\n')); + } - if (*iter == '*') - { - // block comment, skip until next occurance of "*\" - iter = std::search(iter + 1, last, std::begin(comment_end_str), std::end(comment_end_str)); - iter += 2; - } - } - return iter; - }; + if (*iter == '*') { + // block comment, skip until next occurance of "*\" + iter = std::search(iter + 1, last, std::begin(comment_end_str), + std::end(comment_end_str)); + iter += 2; + } + } + return iter; + }; - auto end_quote = [](IterT iter, const IterT& last) -> IterT { - const auto begin = iter; - auto last_esc = iter; - do - { - ++iter; - iter = std::find(iter, last, TYTI_L(charT, '\"')); - if (iter == last) - break; + auto end_quote = [](IterT iter, const IterT& last) -> IterT { + const auto begin = iter; + auto last_esc = iter; + do { + ++iter; + iter = std::find(iter, last, TYTI_L(charT, '\"')); + if (iter == last) + break; - last_esc = std::prev(iter); - while (last_esc != begin && *last_esc == '\\') - --last_esc; - } while (!(std::distance(last_esc, iter) % 2)); - if (iter == last) - throw std::runtime_error{ "quote was opened but not closed." }; - return iter; - }; + last_esc = std::prev(iter); + while (last_esc != begin && *last_esc == '\\') + --last_esc; + } while (!(std::distance(last_esc, iter) % 2)); + if (iter == last) + throw std::runtime_error{"quote was opened but not closed."}; + return iter; + }; - auto end_word = [&whitespaces](IterT iter, const IterT& last) -> IterT { - const auto begin = iter; - auto last_esc = iter; - do - { - ++iter; - iter = std::find_first_of(iter, last, std::begin(whitespaces), std::end(whitespaces)); - if (iter == last) - break; + auto end_word = [&whitespaces](IterT iter, const IterT& last) -> IterT { + const auto begin = iter; + auto last_esc = iter; + do { + ++iter; + iter = std::find_first_of(iter, last, std::begin(whitespaces), + std::end(whitespaces)); + if (iter == last) + break; - last_esc = std::prev(iter); - while (last_esc != begin && *last_esc == '\\') - --last_esc; - } while (!(std::distance(last_esc, iter) % 2)); - //if (iter == last) - // throw std::runtime_error{ "word wasnt properly ended" }; - return iter; - }; + last_esc = std::prev(iter); + while (last_esc != begin && *last_esc == '\\') + --last_esc; + } while (!(std::distance(last_esc, iter) % 2)); + // if (iter == last) + // throw std::runtime_error{ "word wasnt properly ended" }; + return iter; + }; - auto skip_whitespaces = [&whitespaces](IterT iter, const IterT& last) -> IterT { - iter = std::find_if_not(iter, last, [&whitespaces](charT c) { - // return true if whitespace - return std::any_of(std::begin(whitespaces), std::end(whitespaces), [c](charT pc) { return pc == c; }); - }); - return iter; - }; + auto skip_whitespaces = [&whitespaces](IterT iter, const IterT& last) -> IterT { + iter = std::find_if_not(iter, last, [&whitespaces](charT c) { + // return true if whitespace + return std::any_of(std::begin(whitespaces), std::end(whitespaces), + [c](charT pc) { + return pc == c; + }); + }); + return iter; + }; - std::function&)> strip_escape_symbols = [](std::basic_string& s) { - auto quote_searcher = [&s](size_t pos) { return s.find(TYTI_L(charT, "\\\""), pos); }; - auto p = quote_searcher(0); - while (p != s.npos) - { - s.replace(p, 2, TYTI_L(charT, "\"")); - p = quote_searcher(p); - } - auto searcher = [&s](size_t pos) { return s.find(TYTI_L(charT, "\\\\"), pos); }; - p = searcher(0); - while (p != s.npos) - { - s.replace(p, 2, TYTI_L(charT, "\\")); - p = searcher(p); - } - }; + std::function&)> strip_escape_symbols = + [](std::basic_string& s) { + auto quote_searcher = [&s](size_t pos) { + return s.find(TYTI_L(charT, "\\\""), pos); + }; + auto p = quote_searcher(0); + while (p != s.npos) { + s.replace(p, 2, TYTI_L(charT, "\"")); + p = quote_searcher(p); + } + auto searcher = [&s](size_t pos) { + return s.find(TYTI_L(charT, "\\\\"), pos); + }; + p = searcher(0); + while (p != s.npos) { + s.replace(p, 2, TYTI_L(charT, "\\")); + p = searcher(p); + } + }; - if (!opt.strip_escape_symbols) - strip_escape_symbols = [](std::basic_string&) {}; + if (!opt.strip_escape_symbols) + strip_escape_symbols = [](std::basic_string&) {}; - auto conditional_fullfilled = [&skip_whitespaces, &is_platform_str](IterT& iter, const IterT& last) { - iter = skip_whitespaces(iter, last); - if (*iter == '[') - { - ++iter; - const auto end = std::find(iter, last, ']'); - const bool negate = *iter == '!'; - if (negate) - ++iter; - auto conditional = std::basic_string(iter, end); + auto conditional_fullfilled = [&skip_whitespaces, + &is_platform_str](IterT& iter, const IterT& last) { + iter = skip_whitespaces(iter, last); + if (*iter == '[') { + ++iter; + const auto end = std::find(iter, last, ']'); + const bool negate = *iter == '!'; + if (negate) + ++iter; + auto conditional = std::basic_string(iter, end); - const bool is_platform = is_platform_str(conditional); - iter = end + 1; + const bool is_platform = is_platform_str(conditional); + iter = end + 1; - return static_cast(is_platform ^ negate); - } - return true; - }; + return static_cast(is_platform ^ negate); + } + return true; + }; - //read header - // first, quoted name - std::unique_ptr curObj = nullptr; - std::vector> roots; - std::stack> lvls; - auto curIter = first; + // read header + // first, quoted name + std::unique_ptr curObj = nullptr; + std::vector> roots; + std::stack> lvls; + auto curIter = first; - while (curIter != last && *curIter != '\0') - { - //find first starting attrib/child, or ending - curIter = skip_whitespaces(curIter, last); - if (curIter == last || *curIter == '\0') - break; - if (*curIter == TYTI_L(charT, '/')) - { - curIter = skip_comments(curIter, last); - } - else if (*curIter != TYTI_L(charT, '}')) - { + while (curIter != last && *curIter != '\0') { + // find first starting attrib/child, or ending + curIter = skip_whitespaces(curIter, last); + if (curIter == last || *curIter == '\0') + break; + if (*curIter == TYTI_L(charT, '/')) { + curIter = skip_comments(curIter, last); + } else if (*curIter != TYTI_L(charT, '}')) { - // get key - const auto keyEnd = (*curIter == TYTI_L(charT, '\"')) ? end_quote(curIter, last) : end_word(curIter, last); - if (*curIter == TYTI_L(charT, '\"')) - ++curIter; - std::basic_string key(curIter, keyEnd); - strip_escape_symbols(key); - curIter = keyEnd + ((*keyEnd == TYTI_L(charT, '\"')) ? 1 : 0); + // get key + const auto keyEnd = (*curIter == TYTI_L(charT, '\"')) + ? end_quote(curIter, last) + : end_word(curIter, last); + if (*curIter == TYTI_L(charT, '\"')) + ++curIter; + std::basic_string key(curIter, keyEnd); + strip_escape_symbols(key); + curIter = keyEnd + ((*keyEnd == TYTI_L(charT, '\"')) ? 1 : 0); - curIter = skip_whitespaces(curIter, last); + curIter = skip_whitespaces(curIter, last); - auto conditional = conditional_fullfilled(curIter, last); - if (!conditional) - continue; + auto conditional = conditional_fullfilled(curIter, last); + if (!conditional) + continue; - while (*curIter == TYTI_L(charT, '/')) - { + while (*curIter == TYTI_L(charT, '/')) { - curIter = skip_comments(curIter, last); - if (curIter == last || *curIter == '}') - throw std::runtime_error{ "key declared, but no value" }; - curIter = skip_whitespaces(curIter, last); - if (curIter == last || *curIter == '}') - throw std::runtime_error{ "key declared, but no value" }; - } - // get value - if (*curIter != '{') - { - const auto valueEnd = (*curIter == TYTI_L(charT, '\"')) ? end_quote(curIter, last) : end_word(curIter, last); - if (*curIter == TYTI_L(charT, '\"')) - ++curIter; + curIter = skip_comments(curIter, last); + if (curIter == last || *curIter == '}') + throw std::runtime_error{"key declared, but no value"}; + curIter = skip_whitespaces(curIter, last); + if (curIter == last || *curIter == '}') + throw std::runtime_error{"key declared, but no value"}; + } + // get value + if (*curIter != '{') { + const auto valueEnd = (*curIter == TYTI_L(charT, '\"')) + ? end_quote(curIter, last) + : end_word(curIter, last); + if (*curIter == TYTI_L(charT, '\"')) + ++curIter; - auto value = std::basic_string(curIter, valueEnd); - strip_escape_symbols(value); - curIter = valueEnd + ((*valueEnd == TYTI_L(charT, '\"')) ? 1 : 0); + auto value = std::basic_string(curIter, valueEnd); + strip_escape_symbols(value); + curIter = valueEnd + ((*valueEnd == TYTI_L(charT, '\"')) ? 1 : 0); - auto conditional = conditional_fullfilled(curIter, last); - if (!conditional) - continue; + auto conditional = conditional_fullfilled(curIter, last); + if (!conditional) + continue; - // process value - if (key != TYTI_L(charT, "#include") && key != TYTI_L(charT, "#base")) - { - if (curObj) - { - curObj->add_attribute(std::move(key), std::move(value)); - } - else - { - throw std::runtime_error{ "unexpected key without object" }; - } - } - else - { - if (!opt.ignore_includes && exclude_files.find(value) == exclude_files.end()) - { - exclude_files.insert(value); - std::basic_ifstream i(detail::string_converter(value)); - auto str = read_file(i); - auto file_objs = read_internal(str.begin(), str.end(), exclude_files, opt); - for (auto& n : file_objs) - { - if (curObj) - curObj->add_child(std::move(n)); - else - roots.push_back(std::move(n)); - } - exclude_files.erase(value); - } - } - } - else if (*curIter == '{') - { - if (curObj) - lvls.push(std::move(curObj)); - curObj = std::make_unique(); - curObj->set_name(std::move(key)); - ++curIter; - } - } - //end of new object - else if (curObj && *curIter == TYTI_L(charT, '}')) - { - if (!lvls.empty()) - { - //get object before - std::unique_ptr prev{ std::move(lvls.top()) }; - lvls.pop(); - - // add finished obj to obj before and release it from processing - prev->add_child(std::move(curObj)); - curObj = std::move(prev); - } - else - { - roots.push_back(std::move(curObj)); - curObj.reset(); - } - ++curIter; - } - else - { - throw std::runtime_error{ "unexpected '}'" }; - } + // process value + if (key != TYTI_L(charT, "#include") && key != TYTI_L(charT, "#base")) { + if (curObj) { + curObj->add_attribute(std::move(key), std::move(value)); + } else { + throw std::runtime_error{"unexpected key without object"}; + } + } else { + if (!opt.ignore_includes && + exclude_files.find(value) == exclude_files.end()) { + exclude_files.insert(value); + std::basic_ifstream i(detail::string_converter(value)); + auto str = read_file(i); + auto file_objs = + read_internal(str.begin(), str.end(), exclude_files, opt); + for (auto& n : file_objs) { + if (curObj) + curObj->add_child(std::move(n)); + else + roots.push_back(std::move(n)); } - if (curObj != nullptr || !lvls.empty()) - { - throw std::runtime_error{ "object is not closed with '}'" }; - } - - return roots; + exclude_files.erase(value); + } } - - } // namespace detail - - /** \brief Read VDF formatted sequences defined by the range [first, last). - If the file is mailformatted, parser will try to read it until it can. - @param first begin iterator - @param end end iterator - - can thow: - - "std::runtime_error" if a parsing error occured - - "std::bad_alloc" if not enough memory coup be allocated - */ - template - OutputT read(IterT first, const IterT last, const Options& opt = Options{}) - { - auto exclude_files = std::unordered_set::value_type>>{}; - auto roots = detail::read_internal(first, last, exclude_files, opt); - - OutputT result; - if (roots.size() > 1) - { - for (auto& i : roots) - result.add_child(std::move(i)); - } - else if (roots.size() == 1) - result = std::move(*roots[0]); - - return result; + } else if (*curIter == '{') { + if (curObj) + lvls.push(std::move(curObj)); + curObj = std::make_unique(); + curObj->set_name(std::move(key)); + ++curIter; + } } + // end of new object + else if (curObj && *curIter == TYTI_L(charT, '}')) { + if (!lvls.empty()) { + // get object before + std::unique_ptr prev{std::move(lvls.top())}; + lvls.pop(); - /** \brief Read VDF formatted sequences defined by the range [first, last). - If the file is mailformatted, parser will try to read it until it can. - @param first begin iterator - @param end end iterator - @param ec output bool. 0 if ok, otherwise, holds an system error code - - Possible error codes: - std::errc::protocol_error: file is mailformatted - std::errc::not_enough_memory: not enough space - std::errc::invalid_argument: iterators throws e.g. out of range - */ - template - OutputT read(IterT first, IterT last, std::error_code& ec, const Options& opt = Options{}) NOEXCEPT - - { - ec.clear(); - OutputT r{}; - try - { - r = read(first, last, opt); - } - catch (std::runtime_error&) - { - ec = std::make_error_code(std::errc::protocol_error); - } - catch (std::bad_alloc&) - { - ec = std::make_error_code(std::errc::not_enough_memory); - } - catch (...) - { - ec = std::make_error_code(std::errc::invalid_argument); - } - return r; + // add finished obj to obj before and release it from processing + prev->add_child(std::move(curObj)); + curObj = std::move(prev); + } else { + roots.push_back(std::move(curObj)); + curObj.reset(); + } + ++curIter; + } else { + throw std::runtime_error{"unexpected '}'"}; } + } + if (curObj != nullptr || !lvls.empty()) { + throw std::runtime_error{"object is not closed with '}'"}; + } - /** \brief Read VDF formatted sequences defined by the range [first, last). - If the file is mailformatted, parser will try to read it until it can. - @param first begin iterator - @param end end iterator - @param ok output bool. true, if parser successed, false, if parser failed - */ - template - OutputT read(IterT first, const IterT last, bool* ok, const Options& opt = Options{}) NOEXCEPT - { - std::error_code ec; - auto r = read(first, last, ec, opt); - if (ok) - *ok = !ec; - return r; - } + return roots; + } - template - inline auto read(IterT first, const IterT last, bool* ok, const Options& opt = Options{}) NOEXCEPT -> basic_object::value_type> - { - return read::value_type>>(first, last, ok, opt); - } + } // namespace detail - template - inline auto read(IterT first, IterT last, std::error_code& ec, const Options& opt = Options{}) NOEXCEPT - -> basic_object::value_type> - { - return read::value_type>>(first, last, ec, opt); - } + /** \brief Read VDF formatted sequences defined by the range [first, last). + If the file is mailformatted, parser will try to read it until it can. + @param first begin iterator + @param end end iterator - template - inline auto read(IterT first, const IterT last, const Options& opt = Options{}) - -> basic_object::value_type> - { - return read::value_type>>(first, last, opt); - } + can thow: + - "std::runtime_error" if a parsing error occured + - "std::bad_alloc" if not enough memory coup be allocated + */ + template + OutputT read(IterT first, const IterT last, const Options& opt = Options{}) + { + auto exclude_files = std::unordered_set< + std::basic_string::value_type>>{}; + auto roots = detail::read_internal(first, last, exclude_files, opt); - /** \brief Loads a stream (e.g. filestream) into the memory and parses the vdf formatted data. - throws "std::bad_alloc" if file buffer could not be allocated - */ - template - OutputT read(iStreamT& inStream, std::error_code& ec, const Options& opt = Options{}) - { - // cache the file - typedef typename iStreamT::char_type charT; - std::basic_string str = detail::read_file(inStream); + OutputT result; + if (roots.size() > 1) { + for (auto& i : roots) + result.add_child(std::move(i)); + } else if (roots.size() == 1) + result = std::move(*roots[0]); - // parse it - return read(str.begin(), str.end(), ec, opt); - } + return result; + } - template - inline basic_object read(iStreamT& inStream, std::error_code& ec, const Options& opt = Options{}) - { - return read>(inStream, ec, opt); - } + /** \brief Read VDF formatted sequences defined by the range [first, last). + If the file is mailformatted, parser will try to read it until it can. + @param first begin iterator + @param end end iterator + @param ec output bool. 0 if ok, otherwise, holds an system error code - /** \brief Loads a stream (e.g. filestream) into the memory and parses the vdf formatted data. - throws "std::bad_alloc" if file buffer could not be allocated - ok == false, if a parsing error occured - */ - template - OutputT read(iStreamT& inStream, bool* ok, const Options& opt = Options{}) - { - std::error_code ec; - const auto r = read(inStream, ec, opt); - if (ok) - *ok = !ec; - return r; - } + Possible error codes: + std::errc::protocol_error: file is mailformatted + std::errc::not_enough_memory: not enough space + std::errc::invalid_argument: iterators throws e.g. out of range + */ + template + OutputT read(IterT first, IterT last, std::error_code& ec, + const Options& opt = Options{}) NOEXCEPT - template - inline basic_object read(iStreamT& inStream, bool* ok, const Options& opt = Options{}) - { - return read>(inStream, ok, opt); - } + { + ec.clear(); + OutputT r{}; + try { + r = read(first, last, opt); + } catch (std::runtime_error&) { + ec = std::make_error_code(std::errc::protocol_error); + } catch (std::bad_alloc&) { + ec = std::make_error_code(std::errc::not_enough_memory); + } catch (...) { + ec = std::make_error_code(std::errc::invalid_argument); + } + return r; + } - /** \brief Loads a stream (e.g. filestream) into the memory and parses the vdf formatted data. - throws "std::bad_alloc" if file buffer could not be allocated - throws "std::runtime_error" if a parsing error occured - */ - template - OutputT read(iStreamT& inStream, const Options& opt) - { + /** \brief Read VDF formatted sequences defined by the range [first, last). + If the file is mailformatted, parser will try to read it until it can. + @param first begin iterator + @param end end iterator + @param ok output bool. true, if parser successed, false, if parser failed + */ + template + OutputT read(IterT first, const IterT last, bool* ok, + const Options& opt = Options{}) NOEXCEPT + { + std::error_code ec; + auto r = read(first, last, ec, opt); + if (ok) + *ok = !ec; + return r; + } - // cache the file - typedef typename iStreamT::char_type charT; - std::basic_string str = detail::read_file(inStream); - // parse it - return read(str.begin(), str.end(), opt); - } + template + inline auto read(IterT first, const IterT last, bool* ok, + const Options& opt = Options{}) NOEXCEPT + ->basic_object::value_type> + { + return read::value_type>>( + first, last, ok, opt); + } - template - inline basic_object read(iStreamT& inStream, const Options& opt = Options{}) - { - return read>(inStream, opt); - } + template + inline auto read(IterT first, IterT last, std::error_code& ec, + const Options& opt = Options{}) NOEXCEPT + ->basic_object::value_type> + { + return read::value_type>>( + first, last, ec, opt); + } - } // namespace vdf -} // namespace tyti + template + inline auto read(IterT first, const IterT last, const Options& opt = Options{}) + -> basic_object::value_type> + { + return read::value_type>>( + first, last, opt); + } + + /** \brief Loads a stream (e.g. filestream) into the memory and parses the vdf + formatted data. throws "std::bad_alloc" if file buffer could not be allocated + */ + template + OutputT read(iStreamT& inStream, std::error_code& ec, const Options& opt = Options{}) + { + // cache the file + typedef typename iStreamT::char_type charT; + std::basic_string str = detail::read_file(inStream); + + // parse it + return read(str.begin(), str.end(), ec, opt); + } + + template + inline basic_object + read(iStreamT& inStream, std::error_code& ec, const Options& opt = Options{}) + { + return read>(inStream, ec, opt); + } + + /** \brief Loads a stream (e.g. filestream) into the memory and parses the vdf + formatted data. throws "std::bad_alloc" if file buffer could not be allocated ok == + false, if a parsing error occured + */ + template + OutputT read(iStreamT& inStream, bool* ok, const Options& opt = Options{}) + { + std::error_code ec; + const auto r = read(inStream, ec, opt); + if (ok) + *ok = !ec; + return r; + } + + template + inline basic_object read(iStreamT& inStream, bool* ok, + const Options& opt = Options{}) + { + return read>(inStream, ok, opt); + } + + /** \brief Loads a stream (e.g. filestream) into the memory and parses the vdf + formatted data. throws "std::bad_alloc" if file buffer could not be allocated + throws "std::runtime_error" if a parsing error occured + */ + template + OutputT read(iStreamT& inStream, const Options& opt) + { + + // cache the file + typedef typename iStreamT::char_type charT; + std::basic_string str = detail::read_file(inStream); + // parse it + return read(str.begin(), str.end(), opt); + } + + template + inline basic_object read(iStreamT& inStream, + const Options& opt = Options{}) + { + return read>(inStream, opt); + } + +} // namespace vdf +} // namespace tyti #ifndef TYTI_NO_L_UNDEF #undef TYTI_L #endif @@ -727,4 +736,4 @@ namespace tyti #undef TYTI_UNDEF_NOTHROW #endif -#endif //__TYTI_STEAM_VDF_PARSER_H__ \ No newline at end of file +#endif //__TYTI_STEAM_VDF_PARSER_H__ \ No newline at end of file