#pragma region CPL License /* Nuclex Native Framework Copyright (C) 2002-2013 Nuclex Development Labs This library is free software; you can redistribute it and/or modify it under the terms of the IBM Common Public License as published by the IBM Corporation; either version 1.0 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the IBM Common Public License for more details. You should have received a copy of the IBM Common Public License along with this library */ #pragma endregion // CPL License #ifndef NUCLEX_STORAGE_FILESYSTEM_GENERIC_GENERICARCHIVEDCONTAINER_H #define NUCLEX_STORAGE_FILESYSTEM_GENERIC_GENERICARCHIVEDCONTAINER_H #include "Nuclex/Storage/Config.h" #include "Nuclex/Storage/FileSystem/Container.h" #include "Nuclex/Storage/FileSystem/ContainerFileCodec.h" #include "../../Helpers/StringHelper.h" #include namespace Nuclex { namespace Storage { namespace FileSystem { // ------------------------------------------------------------------------------------------- // /// Represents a folder in an archive as a container template class GenericArchivedContainer : public Container { /// Smart pointer to a container stored in the archive private: typedef std::shared_ptr ArchivedContainerPointer; /// Smart pointer to a file stored in the archive private: typedef std::shared_ptr ArchivedFilePointer; /// Smart pointer to a constant container private: typedef std::shared_ptr ConstContainerPointer; /// Smart pointer to a container private: typedef std::shared_ptr ContainerPointer; /// Smart pointer to a constant file private: typedef std::shared_ptr ConstFilePointer; /// Smart pointer to a file private: typedef std::shared_ptr FilePointer; /// Map of container names to archived containers private: typedef std::map ArchivedContainerMap; /// Map of file names to archived files private: typedef std::map ArchivedFileMap; /// Initializes a new archived container /// Codecs used to open nested archives /// Native path of the archive file /// Name of the archive itself public: GenericArchivedContainer( const std::shared_ptr &codecs, const std::string &nativePath, const std::string &name ) : Container(codecs), nativePath(nativePath), name(name) {} /// Destroys the archived container interface public: virtual ~GenericArchivedContainer() {} /// Returns the name of the file /// The file's name public: const std::string &GetName() const { return this->name; } /// Returns the path the file is stored at in the native format /// The file's absolute path in the native OS format public: const std::string &GetNativePath() const { return this->nativePath; } /// Retrieves a list of the containers located in this container /// Wildcard of the containers to list /// A list of all containers matching the wildcard public: std::vector GetContainers( const std::string &wildcard = std::string() ) const { std::vector containers; if(wildcard.empty()) { containers.reserve(this->containers.size()); ArchivedContainerMap::const_iterator iterator = this->containers.begin(); for(; iterator != this->containers.end(); ++iterator) { containers.push_back(iterator->second); } } else { ArchivedContainerMap::const_iterator iterator = this->containers.begin(); for(; iterator != this->containers.end(); ++iterator) { if(Helpers::StringHelper::MatchesWildcard(iterator->first, wildcard)) { containers.push_back(iterator->second); } } } return containers; } /// Retrieves a list of the containers located in this container /// Wildcard of the containers to list /// A list of all containers matching the wildcard public: std::vector GetContainers( const std::string &wildcard = std::string() ) { std::vector containers; if(wildcard.empty()) { containers.reserve(this->containers.size()); ArchivedContainerMap::const_iterator iterator = this->containers.begin(); for(; iterator != this->containers.end(); ++iterator) { containers.push_back(iterator->second); } } else { ArchivedContainerMap::const_iterator iterator = this->containers.begin(); for(; iterator != this->containers.end(); ++iterator) { if(Helpers::StringHelper::MatchesWildcard(iterator->first, wildcard)) { containers.push_back(iterator->second); } } } return containers; } /// Retrieves the container with the specified name /// Name of the container that will be retrieved /// The container with the specified name public: ConstContainerPointer GetContainer(const std::string &name) const { ArchivedContainerMap::const_iterator iterator = this->containers.find(name); if(iterator == this->containers.end()) { throw std::runtime_error("No such container"); } return iterator->second; } /// Retrieves the container with the specified name /// Name of the container that will be retrieved /// The container with the specified name public: ContainerPointer GetContainer(const std::string &name) { ArchivedContainerMap::const_iterator iterator = this->containers.find(name); if(iterator == this->containers.end()) { throw std::runtime_error("No such container"); } return iterator->second; } /// Checks if the container contains the specified child container /// Child container the container will be checked for /// True if the container has a child container with the specified name public: bool HasContainer(const std::string &name) const { ArchivedContainerMap::const_iterator iterator = this->containers.find(name); if(iterator == this->containers.end()) { ArchivedFileMap::const_iterator iterator = this->files.find(name); if(iterator == this->files.end()) { return false; } else { return this->Codecs->CanOpenAsContainer(iterator->second); } } else { return true; } } /// Creates a new container in this container /// Name of the created container /// The created container public: ContainerPointer CreateContainer(const std::string &name) { name; throw std::runtime_error("Archives cannot be modified"); } /// Deletes a container in this container /// Name of the deleted container /// True if the container was deleted, false if it didn't exist public: bool DeleteContainer(const std::string &name) { name; throw std::runtime_error("Archives cannot be modified"); } /// Retrieves a list of the files located in this container /// Wildcard of the files to list /// A list of all files matching the wildcard public: std::vector GetFiles( const std::string &wildcard = std::string() ) const { std::vector files; if(wildcard.empty()) { files.reserve(this->files.size()); ArchivedFileMap::const_iterator iterator = this->files.begin(); for(; iterator != this->files.end(); ++iterator) { files.push_back(iterator->second); } } else { ArchivedFileMap::const_iterator iterator = this->files.begin(); for(; iterator != this->files.end(); ++iterator) { if(Helpers::StringHelper::MatchesWildcard(iterator->first, wildcard)) { files.push_back(iterator->second); } } } return files; } /// Retrieves a list of the files located in this container /// Wildcard of the files to list /// A list of all files matching the wildcard public: std::vector GetFiles( const std::string &wildcard = std::string() ) { std::vector files; if(wildcard.empty()) { files.reserve(this->files.size()); ArchivedFileMap::const_iterator iterator = this->files.begin(); for(; iterator != this->files.end(); ++iterator) { files.push_back(iterator->second); } } else { ArchivedFileMap::const_iterator iterator = this->files.begin(); for(; iterator != this->files.end(); ++iterator) { if(Helpers::StringHelper::MatchesWildcard(iterator->first, wildcard)) { files.push_back(iterator->second); } } } return files; } /// Retrieves the file with the specified name /// Name of the file that will be retrieved /// The file with the specified name public: ConstFilePointer GetFile(const std::string &name) const { ArchivedFileMap::const_iterator iterator = this->files.find(name); if(iterator == this->files.end()) { throw std::runtime_error("No such file"); } return iterator->second; } /// Retrieves the file with the specified name /// Name of the file that will be retrieved /// The file with the specified name public: virtual FilePointer GetFile(const std::string &name) { ArchivedFileMap::const_iterator iterator = this->files.find(name); if(iterator == this->files.end()) { throw std::runtime_error("No such file"); } return iterator->second; } /// Checks if the container contains the specified file /// File the container will be checked for /// True if the container contains a file with the specified name public: virtual bool HasFile(const std::string &name) const { ArchivedFileMap::const_iterator iterator = this->files.find(name); return (iterator != this->files.end()); } /// Retrieves the file with the specified name /// Name of the file that will be retrieved /// The file with the specified name public: virtual FilePointer CreateFile(const std::string &name) { name; throw std::runtime_error("Archives cannot be modified"); } /// Deletes the file with the specified name /// Name of the file that will be deleted /// True if the file was deleted, false if it didn't exist public: virtual bool DeleteFile(const std::string &name) { name; throw std::runtime_error("Archives cannot be modified"); } /// Adds a container as a child of this container /// Container that will be stored inside this container protected: void AddContainer(const std::shared_ptr &container) { this->containers.insert( ArchivedContainerMap::value_type(container->GetName(), container) ); } /// Adds a file as a child of this container /// File that will be stored inside this container protected: void AddFile(const std::shared_ptr &file) { this->files.insert(ArchivedFileMap::value_type(file->GetName(), file)); } /// The native path to this container private: std::string nativePath; /// The container's name private: std::string name; /// Subdirectories inside this directory of the zip archive private: ArchivedContainerMap containers; /// Files on this directory level of the zip archive private: ArchivedFileMap files; }; // ------------------------------------------------------------------------------------------- // }}} // namespace Nuclex::Storage::FileSystem #endif // NUCLEX_STORAGE_FILESYSTEM_GENERIC_GENERICARCHIVEDCONTAINER_H