aboutsummaryrefslogtreecommitdiff
path: root/Src/external_dependencies/openmpt-trunk/soundlib/tuningCollection.cpp
diff options
context:
space:
mode:
authorJef <jef@targetspot.com>2024-09-24 08:54:57 -0400
committerJef <jef@targetspot.com>2024-09-24 08:54:57 -0400
commit20d28e80a5c861a9d5f449ea911ab75b4f37ad0d (patch)
tree12f17f78986871dd2cfb0a56e5e93b545c1ae0d0 /Src/external_dependencies/openmpt-trunk/soundlib/tuningCollection.cpp
parent537bcbc86291b32fc04ae4133ce4d7cac8ebe9a7 (diff)
downloadwinamp-20d28e80a5c861a9d5f449ea911ab75b4f37ad0d.tar.gz
Initial community commit
Diffstat (limited to 'Src/external_dependencies/openmpt-trunk/soundlib/tuningCollection.cpp')
-rw-r--r--Src/external_dependencies/openmpt-trunk/soundlib/tuningCollection.cpp320
1 files changed, 320 insertions, 0 deletions
diff --git a/Src/external_dependencies/openmpt-trunk/soundlib/tuningCollection.cpp b/Src/external_dependencies/openmpt-trunk/soundlib/tuningCollection.cpp
new file mode 100644
index 00000000..f11260b2
--- /dev/null
+++ b/Src/external_dependencies/openmpt-trunk/soundlib/tuningCollection.cpp
@@ -0,0 +1,320 @@
+/*
+ * tuningCollection.cpp
+ * --------------------
+ * Purpose: Alternative sample tuning collection class.
+ * Notes : (currently none)
+ * Authors: OpenMPT Devs
+ * The OpenMPT source code is released under the BSD license. Read LICENSE for more details.
+ */
+
+
+#include "stdafx.h"
+#include "tuningcollection.h"
+#include "mpt/io/io.hpp"
+#include "mpt/io/io_stdstream.hpp"
+#include "../common/serialization_utils.h"
+#include <algorithm>
+#include "../common/mptFileIO.h"
+#include "Loaders.h"
+#ifdef MODPLUG_TRACKER
+#include "../mptrack/TrackerSettings.h"
+#endif //MODPLUG_TRACKER
+
+
+OPENMPT_NAMESPACE_BEGIN
+
+
+namespace Tuning {
+
+
+/*
+Version history:
+ 2->3: Serialization revamp(August 2007)
+ 1->2: Sizetypes of string serialisation from size_t(uint32)
+ to uint8. (March 2007)
+*/
+
+
+namespace CTuningS11n
+{
+ void ReadStr(std::istream &iStrm, mpt::ustring &ustr, const std::size_t dummy, mpt::Charset charset);
+ void WriteStr(std::ostream &oStrm, const mpt::ustring &ustr);
+} // namespace CTuningS11n
+
+using namespace CTuningS11n;
+
+
+static void ReadTuning(std::istream &iStrm, CTuningCollection &Tc, const std::size_t dummy, mpt::Charset defaultCharset)
+{
+ MPT_UNREFERENCED_PARAMETER(dummy);
+ Tc.AddTuning(iStrm, defaultCharset);
+}
+
+static void WriteTuning(std::ostream& oStrm, const CTuning& t)
+{
+ t.Serialize(oStrm);
+}
+
+
+CTuning* CTuningCollection::GetTuning(const mpt::ustring &name)
+{
+ for(std::size_t i = 0; i<m_Tunings.size(); i++)
+ {
+ if(m_Tunings[i]->GetName() == name)
+ {
+ return m_Tunings[i].get();
+ }
+ }
+ return nullptr;
+}
+
+const CTuning* CTuningCollection::GetTuning(const mpt::ustring &name) const
+{
+ for(std::size_t i = 0; i<m_Tunings.size(); i++)
+ {
+ if(m_Tunings[i]->GetName() == name)
+ {
+ return m_Tunings[i].get();
+ }
+ }
+ return nullptr;
+}
+
+
+Tuning::SerializationResult CTuningCollection::Serialize(std::ostream& oStrm, const mpt::ustring &name) const
+{
+ srlztn::SsbWrite ssb(oStrm);
+ ssb.BeginWrite("TC", 3); // version
+ ssb.WriteItem(int8(1), "UTF8");
+ ssb.WriteItem(name, "0", &WriteStr);
+ uint16 dummyEditMask = 0xffff;
+ ssb.WriteItem(dummyEditMask, "1");
+
+ const size_t tcount = m_Tunings.size();
+ for(size_t i = 0; i<tcount; i++)
+ ssb.WriteItem(*m_Tunings[i], "2", &WriteTuning);
+ ssb.FinishWrite();
+
+ if(ssb.GetStatus() & srlztn::SNT_FAILURE)
+ return Tuning::SerializationResult::Failure;
+ else
+ return Tuning::SerializationResult::Success;
+}
+
+
+Tuning::SerializationResult CTuningCollection::Deserialize(std::istream &iStrm, mpt::ustring &name, mpt::Charset defaultCharset)
+{
+ std::istream::pos_type startpos = iStrm.tellg();
+
+ const Tuning::SerializationResult oldLoadingResult = DeserializeOLD(iStrm, name, defaultCharset);
+
+ if(oldLoadingResult == Tuning::SerializationResult::NoMagic)
+ { // An old version was not recognised - trying new version.
+ iStrm.clear();
+ iStrm.seekg(startpos);
+ srlztn::SsbRead ssb(iStrm);
+ ssb.BeginRead("TC", 3); // version
+ int8 use_utf8 = 0;
+ ssb.ReadItem(use_utf8, "UTF8");
+ const mpt::Charset charset = use_utf8 ? mpt::Charset::UTF8 : defaultCharset;
+
+ const srlztn::SsbRead::ReadIterator iterBeg = ssb.GetReadBegin();
+ const srlztn::SsbRead::ReadIterator iterEnd = ssb.GetReadEnd();
+ for(srlztn::SsbRead::ReadIterator iter = iterBeg; iter != iterEnd; iter++)
+ {
+ uint16 dummyEditMask = 0xffff;
+ if (ssb.CompareId(iter, "0") == srlztn::SsbRead::IdMatch)
+ ssb.ReadIterItem(iter, name, [charset](std::istream &iStrm, mpt::ustring &ustr, const std::size_t dummy){ return ReadStr(iStrm, ustr, dummy, charset); });
+ else if (ssb.CompareId(iter, "1") == srlztn::SsbRead::IdMatch)
+ ssb.ReadIterItem(iter, dummyEditMask);
+ else if (ssb.CompareId(iter, "2") == srlztn::SsbRead::IdMatch)
+ ssb.ReadIterItem(iter, *this, [charset](std::istream &iStrm, CTuningCollection &Tc, const std::size_t dummy){ return ReadTuning(iStrm, Tc, dummy, charset); });
+ }
+
+ if(ssb.GetStatus() & srlztn::SNT_FAILURE)
+ return Tuning::SerializationResult::Failure;
+ else
+ return Tuning::SerializationResult::Success;
+ }
+ else
+ {
+ return oldLoadingResult;
+ }
+}
+
+
+Tuning::SerializationResult CTuningCollection::DeserializeOLD(std::istream &inStrm, mpt::ustring &uname, mpt::Charset defaultCharset)
+{
+
+ //1. begin marker:
+ uint32 beginMarker = 0;
+ mpt::IO::ReadIntLE<uint32>(inStrm, beginMarker);
+ if(beginMarker != MagicBE("TCSH")) // Magic is reversed in file, hence BE
+ return Tuning::SerializationResult::NoMagic;
+
+ //2. version
+ int32 version = 0;
+ mpt::IO::ReadIntLE<int32>(inStrm, version);
+ if(version > 2 || version < 1)
+ return Tuning::SerializationResult::Failure;
+
+ //3. Name
+ if(version < 2)
+ {
+ std::string name;
+ if(!mpt::IO::ReadSizedStringLE<uint32>(inStrm, name, 256))
+ return Tuning::SerializationResult::Failure;
+ uname = mpt::ToUnicode(defaultCharset, name);
+ }
+ else
+ {
+ std::string name;
+ if(!mpt::IO::ReadSizedStringLE<uint8>(inStrm, name))
+ return Tuning::SerializationResult::Failure;
+ uname = mpt::ToUnicode(defaultCharset, name);
+ }
+
+ //4. Editmask
+ int16 em = 0;
+ mpt::IO::ReadIntLE<int16>(inStrm, em);
+ //Not assigning the value yet, for if it sets some property const,
+ //further loading might fail.
+
+ //5. Tunings
+ {
+ uint32 s = 0;
+ mpt::IO::ReadIntLE<uint32>(inStrm, s);
+ if(s > 50)
+ return Tuning::SerializationResult::Failure;
+ for(size_t i = 0; i<s; i++)
+ {
+ if(!AddTuning(inStrm, defaultCharset))
+ {
+ return Tuning::SerializationResult::Failure;
+ }
+ }
+ }
+
+ //6. End marker
+ uint32 endMarker = 0;
+ mpt::IO::ReadIntLE<uint32>(inStrm, endMarker);
+ if(endMarker != MagicBE("TCSF")) // Magic is reversed in file, hence BE
+ return Tuning::SerializationResult::Failure;
+
+ return Tuning::SerializationResult::Success;
+}
+
+
+
+bool CTuningCollection::Remove(const CTuning *pT)
+{
+ const auto it = std::find_if(m_Tunings.begin(), m_Tunings.end(),
+ [&] (const std::unique_ptr<CTuning> & upT) -> bool
+ {
+ return upT.get() == pT;
+ }
+ );
+ if(it == m_Tunings.end())
+ {
+ return false;
+ }
+ m_Tunings.erase(it);
+ return true;
+}
+
+
+bool CTuningCollection::Remove(const std::size_t i)
+{
+ if(i >= m_Tunings.size())
+ {
+ return false;
+ }
+ m_Tunings.erase(m_Tunings.begin() + i);
+ return true;
+}
+
+
+CTuning* CTuningCollection::AddTuning(std::unique_ptr<CTuning> pT)
+{
+ if(m_Tunings.size() >= s_nMaxTuningCount)
+ {
+ return nullptr;
+ }
+ if(!pT)
+ {
+ return nullptr;
+ }
+ CTuning *result = pT.get();
+ m_Tunings.push_back(std::move(pT));
+ return result;
+}
+
+
+CTuning* CTuningCollection::AddTuning(std::istream &inStrm, mpt::Charset defaultCharset)
+{
+ if(m_Tunings.size() >= s_nMaxTuningCount)
+ {
+ return nullptr;
+ }
+ if(!inStrm.good())
+ {
+ return nullptr;
+ }
+ std::unique_ptr<CTuning> pT = CTuning::CreateDeserializeOLD(inStrm, defaultCharset);
+ if(!pT)
+ {
+ pT = CTuning::CreateDeserialize(inStrm, defaultCharset);
+ }
+ if(!pT)
+ {
+ return nullptr;
+ }
+ CTuning *result = pT.get();
+ m_Tunings.push_back(std::move(pT));
+ return result;
+}
+
+
+#ifdef MODPLUG_TRACKER
+
+
+bool UnpackTuningCollection(const CTuningCollection &tc, const mpt::PathString &prefix)
+{
+ bool error = false;
+ auto numberFmt = mpt::FormatSpec().Dec().FillNul().Width(1 + static_cast<int>(std::log10(tc.GetNumTunings())));
+ for(std::size_t i = 0; i < tc.GetNumTunings(); ++i)
+ {
+ const CTuning & tuning = *(tc.GetTuning(i));
+ mpt::PathString fn;
+ fn += prefix;
+ mpt::ustring tuningName = tuning.GetName();
+ if(tuningName.empty())
+ {
+ tuningName = U_("untitled");
+ }
+ SanitizeFilename(tuningName);
+ fn += mpt::PathString::FromUnicode(MPT_UFORMAT("{} - {}")(mpt::ufmt::fmt(i + 1, numberFmt), tuningName));
+ fn += mpt::PathString::FromUTF8(CTuning::s_FileExtension);
+ if(fn.FileOrDirectoryExists())
+ {
+ error = true;
+ } else
+ {
+ mpt::SafeOutputFile sfout(fn, std::ios::binary, mpt::FlushModeFromBool(TrackerSettings::Instance().MiscFlushFileBuffersOnSave));
+ if(tuning.Serialize(sfout) != Tuning::SerializationResult::Success)
+ {
+ error = true;
+ }
+ }
+ }
+ return !error;
+}
+
+
+#endif
+
+
+} // namespace Tuning
+
+
+OPENMPT_NAMESPACE_END