File: ArchiveLoader.cpp

package info (click to toggle)
spring 105.0.1%2Bdfsg-2
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 108,860 kB
  • sloc: cpp: 467,785; ansic: 302,607; python: 12,925; java: 12,201; awk: 5,889; sh: 2,371; xml: 655; perl: 405; php: 276; objc: 194; makefile: 75; sed: 2
file content (84 lines) | stat: -rw-r--r-- 2,762 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
/* This file is part of the Spring engine (GPL v2 or later), see LICENSE.html */

#include <algorithm>

#include "ArchiveLoader.h"

#include "Archives/IArchiveFactory.h"
#include "Archives/IArchive.h"
#include "Archives/PoolArchive.h"
#include "Archives/DirArchive.h"
#include "Archives/ZipArchive.h"
#include "Archives/SevenZipArchive.h"
#include "Archives/VirtualArchive.h"

#include "FileSystem.h"
#include "DataDirsAccess.h"
#include "System/Log/ILog.h"

static CPoolArchiveFactory sdpArchiveFactory;
static CDirArchiveFactory sddArchiveFactory;
static CZipArchiveFactory sdzArchiveFactory;
static CSevenZipArchiveFactory sd7ArchiveFactory;
static CVirtualArchiveFactory sdvArchiveFactory;

CArchiveLoader::CArchiveLoader()
{
	const auto AddFactory = [&](unsigned archiveType, IArchiveFactory& factory) {
		archiveFactories[archiveType] = {factory.GetDefaultExtension(), &factory};
	};
	AddFactory(ARCHIVE_TYPE_SDP, sdpArchiveFactory);
	AddFactory(ARCHIVE_TYPE_SDD, sddArchiveFactory);
	AddFactory(ARCHIVE_TYPE_SDZ, sdzArchiveFactory);
	AddFactory(ARCHIVE_TYPE_SD7, sd7ArchiveFactory);
	AddFactory(ARCHIVE_TYPE_SDV, sdvArchiveFactory);

	using P = decltype(archiveFactories)::value_type;
	std::sort(archiveFactories.begin(), archiveFactories.end(), [](const P& a, const P& b) { return (a.first < b.first); });
}


const CArchiveLoader& CArchiveLoader::GetInstance()
{
	static const CArchiveLoader singleton;
	return singleton;
}


bool CArchiveLoader::IsArchiveFile(const std::string& fileName) const
{
	const std::string fileExt = FileSystem::GetExtension(fileName);

	using P = decltype(archiveFactories)::value_type;

	const auto pred = [](const P& a, const P& b) { return (a.first < b.first); };
	const auto iter = std::lower_bound(archiveFactories.begin(), archiveFactories.end(), P{fileExt, nullptr}, pred);

	return (iter != archiveFactories.end() && iter->first == fileExt);
}


IArchive* CArchiveLoader::OpenArchive(const std::string& fileName, const std::string& type) const
{
	IArchive* ret = nullptr;

	const std::string fileExt = type.empty() ? FileSystem::GetExtension(fileName) : type;
	const std::string filePath = dataDirsAccess.LocateFile(fileName);

	using P = decltype(archiveFactories)::value_type;

	const auto pred = [](const P& a, const P& b) { return (a.first < b.first); };
	const auto iter = std::lower_bound(archiveFactories.begin(), archiveFactories.end(), P{fileExt, nullptr}, pred);

	if (iter != archiveFactories.end() && iter->first == fileExt)
		ret = iter->second->CreateArchive(filePath);

	if (ret != nullptr && ret->IsOpen())
		return ret;

	LOG_L(L_INFO, "[ArchiveLoader::%s(name=\"%s\" type=\"%s\")] could not load or open archive %p", __func__, fileName.c_str(), type.c_str(), ret);

	delete ret;
	return nullptr;
}