Example #1
0
// -----------------------------------------------------------------------------
// Opens [dir] as a DirArchive and adds it to the list.
// Returns a pointer to the archive or nullptr if an error occurred.
// -----------------------------------------------------------------------------
Archive* ArchiveManager::openDirArchive(const string& dir, bool manage, bool silent)
{
	auto new_archive = getArchive(dir);

	LOG_MESSAGE(1, "Opening directory %s as archive", dir);

	// If the archive is already open, just return it
	if (new_archive)
	{
		// Announce open
		if (!silent)
		{
			MemChunk mc;
			uint32_t index = archiveIndex(new_archive);
			mc.write(&index, 4);
			announce("archive_opened", mc);
		}

		return new_archive;
	}

	new_archive = new DirArchive();

	// If it opened successfully, add it to the list if needed & return it,
	// Otherwise, delete it and return nullptr
	if (new_archive->open(dir))
	{
		if (manage)
		{
			// Add the archive
			addArchive(new_archive);

			// Announce open
			if (!silent)
			{
				MemChunk mc;
				uint32_t index = archiveIndex(new_archive);
				mc.write(&index, 4);
				announce("archive_opened", mc);
			}

			// Add to recent files
			addRecentFile(dir);
		}

		// Return the opened archive
		return new_archive;
	}
	else
	{
		LOG_MESSAGE(1, "Error: " + Global::error);
		delete new_archive;
		return nullptr;
	}
}
Example #2
0
// -----------------------------------------------------------------------------
// Called when an announcement is recieved from one of the archives in the list
// -----------------------------------------------------------------------------
void ArchiveManager::onAnnouncement(Announcer* announcer, const string& event_name, MemChunk& event_data)
{
	// Reset event data for reading
	event_data.seek(0, SEEK_SET);

	// Check that the announcement came from an archive in the list
	int32_t index = archiveIndex((Archive*)announcer);
	if (index >= 0)
	{
		// If the archive was saved
		if (event_name == "saved")
		{
			MemChunk mc;
			mc.write(&index, 4);
			announce("archive_saved", mc);
		}

		// If the archive was modified
		if (event_name == "modified" || event_name == "entry_modified")
		{
			MemChunk mc;
			mc.write(&index, 4);
			announce("archive_modified", mc);
		}
	}
}
Example #3
0
// -----------------------------------------------------------------------------
// Returns true if [archive] is set to be used as a resource, false otherwise
// -----------------------------------------------------------------------------
bool ArchiveManager::archiveIsResource(Archive* archive)
{
	int index = archiveIndex(archive);
	if (index < 0)
		return false;
	else
		return open_archives_[index].resource;
}
Example #4
0
// -----------------------------------------------------------------------------
// Returns all open archives that live inside this one, recursively.
// -----------------------------------------------------------------------------
// This is the recursive bit, separate from the public entry point
void ArchiveManager::getDependentArchivesInternal(Archive* archive, vector<Archive*>& vec)
{
	int ai = archiveIndex(archive);

	for (auto& child : open_archives_[ai].open_children)
	{
		vec.push_back(child);

		getDependentArchivesInternal(child, vec);
	}
}
Example #5
0
// This is the recursive bit, separate from the public entry point
void ArchiveManager::getDependentArchivesInternal(Archive* archive, vector<Archive*>& vec)
{
	Archive* child;
	int ai = archiveIndex(archive);

	for (size_t a = 0; a < open_archives[ai].open_children.size(); a++)
	{
		child = open_archives[ai].open_children[a];
		vec.push_back(child);

		getDependentArchivesInternal(child, vec);
	}
}
Example #6
0
// -----------------------------------------------------------------------------
// Sets/unsets [archive] to be used as a resource
// -----------------------------------------------------------------------------
void ArchiveManager::setArchiveResource(Archive* archive, bool resource)
{
	int index = archiveIndex(archive);
	if (index >= 0)
	{
		bool was_resource              = open_archives_[index].resource;
		open_archives_[index].resource = resource;

		// Update resource manager
		if (resource && !was_resource)
			theResourceManager->addArchive(archive);
		else if (!resource && was_resource)
			theResourceManager->removeArchive(archive);
	}
}
Example #7
0
// -----------------------------------------------------------------------------
// Closes the archive at index, and removes it from the list if the index is
// valid. Returns false on invalid index, true otherwise
// -----------------------------------------------------------------------------
bool ArchiveManager::closeArchive(int index)
{
	// Check for invalid index
	if (index < 0 || index >= (int)open_archives_.size())
		return false;

	// Announce archive closing
	MemChunk mc;
	int32_t  temp = index;
	mc.write(&temp, 4);
	announce("archive_closing", mc);

	// Delete any bookmarked entries contained in the archive
	deleteBookmarksInArchive(open_archives_[index].archive);

	// Remove from resource manager
	theResourceManager->removeArchive(open_archives_[index].archive);

	// Close any open child archives
	// Clear out the open_children vector first, lest the children try to remove themselves from it
	auto open_children = open_archives_[index].open_children;
	open_archives_[index].open_children.clear();
	for (auto& archive : open_children)
	{
		int ci = archiveIndex(archive);
		if (ci >= 0)
			closeArchive(ci);
	}

	// Remove ourselves from our parent's open-child list
	auto parent = open_archives_[index].archive->parentEntry();
	if (parent)
	{
		auto gp = parent->parent();
		if (gp)
		{
			int pi = archiveIndex(gp);
			if (pi >= 0)
			{
				auto& children = open_archives_[pi].open_children;
				for (auto it = children.begin(); it < children.end(); ++it)
				{
					if (*it == open_archives_[index].archive)
					{
						children.erase(it, it + 1);
						break;
					}
				}
			}
		}
	}

	// Close the archive
	open_archives_[index].archive->close();

	// Delete the archive object
	delete open_archives_[index].archive;

	// Remove the archive at index from the list
	open_archives_.erase(open_archives_.begin() + index);

	// Announce closed
	announce("archive_closed", mc);

	return true;
}
Example #8
0
// -----------------------------------------------------------------------------
// Same as the above function, except it opens from an ArchiveEntry
// -----------------------------------------------------------------------------
Archive* ArchiveManager::openArchive(ArchiveEntry* entry, bool manage, bool silent)
{
	// Check entry was given
	if (!entry)
		return nullptr;

	// Check if the entry is already opened
	for (auto& open_archive : open_archives_)
	{
		if (open_archive.archive->parentEntry() == entry)
		{
			// Announce open
			if (!silent)
			{
				MemChunk mc;
				uint32_t index = archiveIndex(open_archive.archive);
				mc.write(&index, 4);
				announce("archive_opened", mc);
			}

			return open_archive.archive;
		}
	}

	// Check entry type
	Archive* new_archive;
	if (WadArchive::isWadArchive(entry->data()))
		new_archive = new WadArchive();
	else if (ZipArchive::isZipArchive(entry->data()))
		new_archive = new ZipArchive();
	else if (ResArchive::isResArchive(entry->data()))
		new_archive = new ResArchive();
	else if (LibArchive::isLibArchive(entry->data()))
		new_archive = new LibArchive();
	else if (DatArchive::isDatArchive(entry->data()))
		new_archive = new DatArchive();
	else if (PakArchive::isPakArchive(entry->data()))
		new_archive = new PakArchive();
	else if (BSPArchive::isBSPArchive(entry->data()))
		new_archive = new BSPArchive();
	else if (GrpArchive::isGrpArchive(entry->data()))
		new_archive = new GrpArchive();
	else if (RffArchive::isRffArchive(entry->data()))
		new_archive = new RffArchive();
	else if (GobArchive::isGobArchive(entry->data()))
		new_archive = new GobArchive();
	else if (LfdArchive::isLfdArchive(entry->data()))
		new_archive = new LfdArchive();
	else if (HogArchive::isHogArchive(entry->data()))
		new_archive = new HogArchive();
	else if (ADatArchive::isADatArchive(entry->data()))
		new_archive = new ADatArchive();
	else if (Wad2Archive::isWad2Archive(entry->data()))
		new_archive = new Wad2Archive();
	else if (WadJArchive::isWadJArchive(entry->data()))
		new_archive = new WadJArchive();
	else if (WolfArchive::isWolfArchive(entry->data()))
		new_archive = new WolfArchive();
	else if (GZipArchive::isGZipArchive(entry->data()))
		new_archive = new GZipArchive();
	else if (BZip2Archive::isBZip2Archive(entry->data()))
		new_archive = new BZip2Archive();
	else if (TarArchive::isTarArchive(entry->data()))
		new_archive = new TarArchive();
	else if (DiskArchive::isDiskArchive(entry->data()))
		new_archive = new DiskArchive();
	else if (entry->name().Lower().EndsWith(".pod") && PodArchive::isPodArchive(entry->data()))
		new_archive = new PodArchive();
	else if (ChasmBinArchive::isChasmBinArchive(entry->data()))
		new_archive = new ChasmBinArchive();
	else if (SiNArchive::isSiNArchive(entry->data()))
		new_archive = new SiNArchive();
	else
	{
		// Unsupported format
		Global::error = "Unsupported or invalid Archive format";
		return nullptr;
	}

	// If it opened successfully, add it to the list & return it,
	// Otherwise, delete it and return nullptr
	if (new_archive->open(entry))
	{
		if (manage)
		{
			// Add to parent's child list if parent is open in the manager (it should be)
			int index_parent = -1;
			if (entry->parent())
				index_parent = archiveIndex(entry->parent());
			if (index_parent >= 0)
				open_archives_[index_parent].open_children.push_back(new_archive);

			// Add the new archive
			addArchive(new_archive);

			// Announce open
			if (!silent)
			{
				MemChunk mc;
				uint32_t index = archiveIndex(new_archive);
				mc.write(&index, 4);
				announce("archive_opened", mc);
			}
		}

		return new_archive;
	}
	else
	{
		LOG_MESSAGE(1, "Error: " + Global::error);
		delete new_archive;
		return nullptr;
	}
}
Example #9
0
// -----------------------------------------------------------------------------
// Opens and adds a archive to the list, returns a pointer to the newly opened
// and added archive, or nullptr if an error occurred
// -----------------------------------------------------------------------------
Archive* ArchiveManager::openArchive(const string& filename, bool manage, bool silent)
{
	// Check for directory
	if (!wxFile::Exists(filename) && wxDirExists(filename))
		return openDirArchive(filename, manage, silent);

	auto new_archive = getArchive(filename);

	LOG_MESSAGE(1, "Opening archive %s", filename);

	// If the archive is already open, just return it
	if (new_archive)
	{
		// Announce open
		if (!silent)
		{
			MemChunk mc;
			uint32_t index = archiveIndex(new_archive);
			mc.write(&index, 4);
			announce("archive_opened", mc);
		}

		return new_archive;
	}

	// Determine file format
	if (WadArchive::isWadArchive(filename))
		new_archive = new WadArchive();
	else if (ZipArchive::isZipArchive(filename))
		new_archive = new ZipArchive();
	else if (ResArchive::isResArchive(filename))
		new_archive = new ResArchive();
	else if (DatArchive::isDatArchive(filename))
		new_archive = new DatArchive();
	else if (LibArchive::isLibArchive(filename))
		new_archive = new LibArchive();
	else if (PakArchive::isPakArchive(filename))
		new_archive = new PakArchive();
	else if (BSPArchive::isBSPArchive(filename))
		new_archive = new BSPArchive();
	else if (GrpArchive::isGrpArchive(filename))
		new_archive = new GrpArchive();
	else if (RffArchive::isRffArchive(filename))
		new_archive = new RffArchive();
	else if (GobArchive::isGobArchive(filename))
		new_archive = new GobArchive();
	else if (LfdArchive::isLfdArchive(filename))
		new_archive = new LfdArchive();
	else if (HogArchive::isHogArchive(filename))
		new_archive = new HogArchive();
	else if (ADatArchive::isADatArchive(filename))
		new_archive = new ADatArchive();
	else if (Wad2Archive::isWad2Archive(filename))
		new_archive = new Wad2Archive();
	else if (WadJArchive::isWadJArchive(filename))
		new_archive = new WadJArchive();
	else if (WolfArchive::isWolfArchive(filename))
		new_archive = new WolfArchive();
	else if (GZipArchive::isGZipArchive(filename))
		new_archive = new GZipArchive();
	else if (BZip2Archive::isBZip2Archive(filename))
		new_archive = new BZip2Archive();
	else if (TarArchive::isTarArchive(filename))
		new_archive = new TarArchive();
	else if (DiskArchive::isDiskArchive(filename))
		new_archive = new DiskArchive();
	else if (PodArchive::isPodArchive(filename))
		new_archive = new PodArchive();
	else if (ChasmBinArchive::isChasmBinArchive(filename))
		new_archive = new ChasmBinArchive();
	else if (SiNArchive::isSiNArchive(filename))
		new_archive = new SiNArchive();
	else
	{
		// Unsupported format
		Global::error = "Unsupported or invalid Archive format";
		return nullptr;
	}

	// If it opened successfully, add it to the list if needed & return it,
	// Otherwise, delete it and return nullptr
	if (new_archive->open(filename))
	{
		if (manage)
		{
			// Add the archive
			addArchive(new_archive);

			// Announce open
			if (!silent)
			{
				MemChunk mc;
				uint32_t index = archiveIndex(new_archive);
				mc.write(&index, 4);
				announce("archive_opened", mc);
			}

			// Add to recent files
			addRecentFile(filename);
		}

		// Return the opened archive
		return new_archive;
	}
	else
	{
		LOG_MESSAGE(1, "Error: " + Global::error);
		delete new_archive;
		return nullptr;
	}
}
Example #10
0
/* ArchiveManager::closeArchive
 * Closes the archive at index, and removes it from the list if the
 * index is valid. Returns false on invalid index, true otherwise
 *******************************************************************/
bool ArchiveManager::closeArchive(int index)
{
	// Check for invalid index
	if (index < 0 || index >= (int) open_archives.size())
		return false;

	// Announce archive closing
	MemChunk mc;
	int32_t temp = index;
	mc.write(&temp, 4);
	announce("archive_closing", mc);

	// Delete any bookmarked entries contained in the archive
	deleteBookmarksInArchive(open_archives[index].archive);

	// Remove from resource manager
	theResourceManager->removeArchive(open_archives[index].archive);

	// Delete any embedded configuration
	//theGameConfiguration->removeEmbeddedConfig(open_archives[index].archive->getFilename());

	// Close any open child archives
	// Clear out the open_children vector first, lest the children try to
	// remove themselves from it
	vector<Archive*> open_children = open_archives[index].open_children;
	open_archives[index].open_children.clear();
	for (size_t a = 0; a < open_children.size(); a++)
	{
		int ci = archiveIndex(open_children[a]);
		if (ci >= 0)
			closeArchive(ci);
	}

	// Remove ourselves from our parent's open-child list
	ArchiveEntry* parent = open_archives[index].archive->getParent();
	if (parent)
	{
		Archive* gp = parent->getParent();
		if (gp)
		{
			int pi = archiveIndex(gp);
			if (pi >= 0)
			{
				vector<Archive*>& children = open_archives[pi].open_children;
				for (vector<Archive*>::iterator it = children.begin();
					it < children.end();
					it++)
				{
					if (*it == open_archives[index].archive)
					{
						children.erase(it, it + 1);
						break;
					}
				}
			}
		}
	}

	// Close the archive
	open_archives[index].archive->close();

	// Delete the archive object
	delete open_archives[index].archive;

	// Remove the archive at index from the list
	open_archives.erase(open_archives.begin() + index);

	// Announce closed
	announce("archive_closed", mc);

	return true;
}
Example #11
0
/* ArchiveManager::openArchive
 * Same as the above function, except it opens from an ArchiveEntry
 *******************************************************************/
Archive* ArchiveManager::openArchive(ArchiveEntry* entry, bool manage, bool silent)
{
	Archive* new_archive = NULL;

	// Check entry was given
	if (!entry)
		return NULL;

	// Check if the entry is already opened
	for (size_t a = 0; a < open_archives.size(); a++)
	{
		if (open_archives[a].archive->getParent() == entry)
		{
			// Announce open
			if (!silent)
			{
				MemChunk mc;
				uint32_t index = archiveIndex(open_archives[a].archive);
				mc.write(&index, 4);
				announce("archive_opened", mc);
			}

			return open_archives[a].archive;
		}
	}

	// Check entry type
	if (WadArchive::isWadArchive(entry->getMCData()))
		new_archive = new WadArchive();
	else if (ZipArchive::isZipArchive(entry->getMCData()))
		new_archive = new ZipArchive();
	else if (ResArchive::isResArchive(entry->getMCData()))
		new_archive = new ResArchive();
	else if (LibArchive::isLibArchive(entry->getMCData()))
		new_archive = new LibArchive();
	else if (DatArchive::isDatArchive(entry->getMCData()))
		new_archive = new DatArchive();
	else if (PakArchive::isPakArchive(entry->getMCData()))
		new_archive = new PakArchive();
	else if (BSPArchive::isBSPArchive(entry->getMCData()))
		new_archive = new BSPArchive();
	else if (GrpArchive::isGrpArchive(entry->getMCData()))
		new_archive = new GrpArchive();
	else if (RffArchive::isRffArchive(entry->getMCData()))
		new_archive = new RffArchive();
	else if (GobArchive::isGobArchive(entry->getMCData()))
		new_archive = new GobArchive();
	else if (LfdArchive::isLfdArchive(entry->getMCData()))
		new_archive = new LfdArchive();
	else if (HogArchive::isHogArchive(entry->getMCData()))
		new_archive = new HogArchive();
	else if (ADatArchive::isADatArchive(entry->getMCData()))
		new_archive = new ADatArchive();
	else if (Wad2Archive::isWad2Archive(entry->getMCData()))
		new_archive = new Wad2Archive();
	else if (WadJArchive::isWadJArchive(entry->getMCData()))
		new_archive = new WadJArchive();
	else if (WolfArchive::isWolfArchive(entry->getMCData()))
		new_archive = new WolfArchive();
	else if (GZipArchive::isGZipArchive(entry->getMCData()))
		new_archive = new GZipArchive();
	else if (BZip2Archive::isBZip2Archive(entry->getMCData()))
		new_archive = new BZip2Archive();
	else if (TarArchive::isTarArchive(entry->getMCData()))
		new_archive = new TarArchive();
	else if (DiskArchive::isDiskArchive(entry->getMCData()))
		new_archive = new DiskArchive();
	else
	{
		// Unsupported format
		Global::error = "Unsupported or invalid Archive format";
		return NULL;
	}

	// If it opened successfully, add it to the list & return it,
	// Otherwise, delete it and return NULL
	if (new_archive->open(entry))
	{
		if (manage)
		{
			// Add to parent's child list if parent is open in the manager (it should be)
			int index_parent = -1;
			if (entry->getParent())
				index_parent = archiveIndex(entry->getParent());
			if (index_parent >= 0)
				open_archives[index_parent].open_children.push_back(new_archive);

			// Add the new archive
			addArchive(new_archive);

			// Announce open
			if (!silent)
			{
				MemChunk mc;
				uint32_t index = archiveIndex(new_archive);
				mc.write(&index, 4);
				announce("archive_opened", mc);
			}
		}

		return new_archive;
	}
	else
	{
		wxLogMessage("Error: " + Global::error);
		delete new_archive;
		return NULL;
	}
}