aboutsummaryrefslogtreecommitdiff
path: root/Src/external_dependencies/openmpt-trunk/unarchiver/unlha.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/unarchiver/unlha.cpp
parent537bcbc86291b32fc04ae4133ce4d7cac8ebe9a7 (diff)
downloadwinamp-20d28e80a5c861a9d5f449ea911ab75b4f37ad0d.tar.gz
Initial community commit
Diffstat (limited to 'Src/external_dependencies/openmpt-trunk/unarchiver/unlha.cpp')
-rw-r--r--Src/external_dependencies/openmpt-trunk/unarchiver/unlha.cpp162
1 files changed, 162 insertions, 0 deletions
diff --git a/Src/external_dependencies/openmpt-trunk/unarchiver/unlha.cpp b/Src/external_dependencies/openmpt-trunk/unarchiver/unlha.cpp
new file mode 100644
index 00000000..e243d1d1
--- /dev/null
+++ b/Src/external_dependencies/openmpt-trunk/unarchiver/unlha.cpp
@@ -0,0 +1,162 @@
+/*
+ * unlha.cpp
+ * ---------
+ * Purpose: Implementation file for extracting modules from .lha archives, making use of lhasa
+ * 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 "unlha.h"
+
+#ifdef MPT_WITH_LHASA
+#include "lhasa.h"
+#endif // MPT_WITH_LHASA
+
+
+OPENMPT_NAMESPACE_BEGIN
+
+
+#ifdef MPT_WITH_LHASA
+
+
+static int LHAreadFileReader(void *handle, void *buf, size_t buf_len)
+{
+ FileReader *f = reinterpret_cast<FileReader*>(handle);
+ int read_len = mpt::saturate_cast<int>(buf_len);
+ int result = mpt::saturate_cast<int>(f->ReadRaw(mpt::span(mpt::void_cast<std::byte*>(buf), read_len)).size());
+ if(result == 0)
+ {
+ return -1;
+ }
+ return result;
+}
+
+static int LHAskipFileReader(void *handle, size_t bytes)
+{
+ FileReader *f = reinterpret_cast<FileReader*>(handle);
+ if(f->CanRead(bytes))
+ {
+ f->Skip(bytes);
+ return 1;
+ }
+ return 0;
+}
+
+static void LHAcloseFileReader(void * /*handle*/)
+{
+ return;
+}
+
+static LHAInputStreamType vtable =
+{
+ LHAreadFileReader,
+ LHAskipFileReader,
+ LHAcloseFileReader
+};
+
+
+CLhaArchive::CLhaArchive(FileReader &file) : ArchiveBase(file), inputstream(nullptr), reader(nullptr), firstfile(nullptr)
+{
+ OpenArchive();
+ for(LHAFileHeader *fileheader = firstfile; fileheader; fileheader = lha_reader_next_file(reader))
+ {
+ ArchiveFileInfo info;
+ info.name = mpt::PathString::FromUnicode(mpt::ToUnicode(mpt::Charset::Amiga_no_C1, fileheader->filename));
+ info.size = fileheader->length;
+ info.type = ArchiveFileType::Normal;
+ contents.push_back(info);
+ }
+ CloseArchive();
+}
+
+
+CLhaArchive::~CLhaArchive()
+{
+ return;
+}
+
+
+void CLhaArchive::OpenArchive()
+{
+ inFile.Rewind();
+ inputstream = lha_input_stream_new(&vtable, &inFile);
+ if(inputstream)
+ {
+ reader = lha_reader_new(inputstream);
+ }
+ if(reader)
+ {
+ lha_reader_set_dir_policy(reader, LHA_READER_DIR_END_OF_DIR);
+ firstfile = lha_reader_next_file(reader);
+ }
+}
+
+
+void CLhaArchive::CloseArchive()
+{
+ if(reader)
+ {
+ lha_reader_free(reader);
+ reader = nullptr;
+ }
+ if(inputstream)
+ {
+ lha_input_stream_free(inputstream);
+ inputstream = nullptr;
+ }
+}
+
+
+bool CLhaArchive::ExtractFile(std::size_t index)
+{
+ if(index >= contents.size())
+ {
+ return false;
+ }
+ data.clear();
+ OpenArchive();
+ const std::size_t bufSize = 4096;
+ std::size_t i = 0;
+ for(LHAFileHeader *fileheader = firstfile; fileheader; fileheader = lha_reader_next_file(reader))
+ {
+ if(index == i)
+ {
+ data.clear();
+ std::size_t countRead = 0;
+ do
+ {
+ try
+ {
+ data.resize(data.size() + bufSize);
+ } catch(...)
+ {
+ CloseArchive();
+ return false;
+ }
+ countRead = lha_reader_read(reader, &data[data.size() - bufSize], bufSize);
+ if(countRead < bufSize)
+ {
+ try
+ {
+ data.resize(data.size() - (bufSize - countRead));
+ } catch(...)
+ {
+ CloseArchive();
+ return false;
+ }
+ }
+ } while(countRead > 0);
+ }
+ ++i;
+ }
+ CloseArchive();
+ return data.size() > 0;
+}
+
+
+#endif // MPT_WITH_LHASA
+
+
+OPENMPT_NAMESPACE_END