Split FILESYSTEMS and FILESYSTEM_MAP into separate module (!49)

GParted_Core::FILESYSTEMS and ::FILESYSTEM_MAP and the methods that
query and manipulate them are self-contained.  Therefore move them into
a separate SupportedFileSystems module.

Also having a single class maintaining all FileSystem interface objects
will make testing all the file system types much easier as there will be
no need to duplicate this functionality in the test.

Closes !49 - Add file system interface tests
This commit is contained in:
Mike Fleetwood 2019-07-16 13:01:07 +01:00 committed by Curtis Gedak
parent 279a9c44ed
commit 6d121ebb5d
8 changed files with 258 additions and 127 deletions

View File

@ -25,6 +25,7 @@
#include "Partition.h"
#include "PartitionLUKS.h"
#include "PartitionVector.h"
#include "SupportedFileSystems.h"
#include "Utils.h"
#include <parted/parted.h>
@ -62,7 +63,7 @@ public:
bool toggle_flag( const Partition & partition, const Glib::ustring & flag, bool state ) ;
const std::vector<FS> & get_filesystems() const ;
const FS & get_fs( FSType filesystem ) const;
const FS& get_fs(FSType fstype) const;
static std::vector<Glib::ustring> get_disklabeltypes() ;
std::map<Glib::ustring, bool> get_available_flags( const Partition & partition ) ;
Glib::ustring get_thread_status_message() ;
@ -215,9 +216,6 @@ private:
bool update_bootsector( const Partition & partition, OperationDetail & operationdetail ) ;
//general..
static void init_filesystems();
static void fini_filesystems();
void capture_libparted_messages( OperationDetail & operationdetail, bool success );
static bool flush_device( PedDevice * lp_device );
@ -234,13 +232,12 @@ private:
static PedExceptionOption ped_exception_handler( PedException * e ) ;
std::vector<FS> FILESYSTEMS ;
static std::map< FSType, FileSystem * > FILESYSTEM_MAP;
std::vector<PedPartitionFlag> flags;
std::vector<Glib::ustring> device_paths ;
bool probe_devices ;
Glib::ustring thread_status_message; //Used to pass data to show_pulsebar method
Glib::RefPtr<Glib::IOChannel> iocInput, iocOutput; // Used to send data to gpart command
static SupportedFileSystems* supported_filesystems;
};
} //GParted

View File

@ -48,6 +48,7 @@ EXTRA_DIST = \
PipeCapture.h \
Proc_Partitions_Info.h \
ProgressBar.h \
SupportedFileSystems.h \
SWRaid_Info.h \
TreeView_Detail.h \
Utils.h \

View File

@ -0,0 +1,54 @@
/* Copyright (C) 2019 Mike Fleetwood
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program 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
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
#ifndef GPARTED_SUPPORTEDFILESYSTEMS_H
#define GPARTED_SUPPORTEDFILESYSTEMS_H
#include "FileSystem.h"
#include <map>
#include <vector>
namespace GParted
{
class SupportedFileSystems
{
public:
SupportedFileSystems();
~SupportedFileSystems();
void find_supported_filesystems();
FileSystem* get_fs_object(FSType fstype) const;
const FS& get_fs_support(FSType fstype) const;
const std::vector<FS>& get_all_fs_support() const;
bool supported_filesystem(FSType fstype) const;
private:
typedef std::map<FSType, FileSystem *> FSObjectsMap;
std::vector<FS> m_fs_support;
FSObjectsMap m_fs_objects;
};
} //GParted
#endif /* GPARTED_SUPPORTEDFILESYSTEMS_H */

View File

@ -43,6 +43,7 @@ src/PartitionLUKS.cc
src/PartitionVector.cc
src/PasswordRAMStore.cc
src/ProgressBar.cc
src/SupportedFileSystems.cc
src/SWRaid_Info.cc
src/TreeView_Detail.cc
src/Utils.cc

View File

@ -31,28 +31,11 @@
#include "PartitionLUKS.h"
#include "PartitionVector.h"
#include "Proc_Partitions_Info.h"
#include "SupportedFileSystems.h"
#include "SWRaid_Info.h"
#include "Utils.h"
#include "../config.h"
#include "btrfs.h"
#include "exfat.h"
#include "ext2.h"
#include "f2fs.h"
#include "fat16.h"
#include "linux_swap.h"
#include "lvm2_pv.h"
#include "luks.h"
#include "reiserfs.h"
#include "minix.h"
#include "nilfs2.h"
#include "ntfs.h"
#include "xfs.h"
#include "jfs.h"
#include "hfs.h"
#include "hfsplus.h"
#include "reiser4.h"
#include "udf.h"
#include <parted/parted.h>
#include <cerrno>
@ -94,11 +77,10 @@ GParted_Core::GParted_Core()
find_supported_core();
//initialize file system list
init_filesystems() ;
supported_filesystems = new SupportedFileSystems();
//Determine file system support capabilities for the first time
find_supported_filesystems() ;
supported_filesystems->find_supported_filesystems();
}
@ -132,33 +114,13 @@ void GParted_Core::find_supported_core()
hdparm_found = ! Glib::find_program_in_path( "hdparm" ).empty();
}
void GParted_Core::find_supported_filesystems()
{
std::map< FSType, FileSystem * >::iterator f;
// Iteration of std::map is ordered according to operator< of the key. Hence the
// FILESYSTEMS vector is constructed in FSType enum order: FS_UNKNOWN, FS_BTRFS,
// ..., FS_XFS, ... . This ultimately controls the default order of the file
// systems in the menus and dialogs.
FILESYSTEMS .clear() ;
for ( f = FILESYSTEM_MAP .begin() ; f != FILESYSTEM_MAP .end() ; f++ ) {
if ( f ->second )
{
FILESYSTEMS .push_back( f ->second ->get_filesystem_support() ) ;
}
else
{
// For basic supported file systems create the supported action
// set.
FS fs_basicsupp( f->first );
fs_basicsupp.move = FS::GPARTED;
fs_basicsupp.copy = FS::GPARTED;
FILESYSTEMS.push_back( fs_basicsupp );
}
}
supported_filesystems->find_supported_filesystems();
}
void GParted_Core::set_user_devices( const std::vector<Glib::ustring> & user_devices )
{
this ->device_paths = user_devices ;
@ -603,23 +565,18 @@ bool GParted_Core::toggle_flag( const Partition & partition, const Glib::ustring
const std::vector<FS> & GParted_Core::get_filesystems() const
{
return FILESYSTEMS ;
return supported_filesystems->get_all_fs_support();
}
// Return supported capabilities of the file system type or, if not found, not supported
// capabilities set.
const FS & GParted_Core::get_fs( FSType filesystem ) const
const FS& GParted_Core::get_fs(FSType fstype) const
{
for ( unsigned int t = 0 ; t < FILESYSTEMS .size() ; t++ )
{
if ( FILESYSTEMS[ t ] .filesystem == filesystem )
return FILESYSTEMS[ t ] ;
}
static FS fs_notsupp( FS_UNSUPPORTED );
return fs_notsupp;
return supported_filesystems->get_fs_support(fstype);
}
//Return all libparted's partition table types in it's preferred ordering,
// alphabetic except with "loop" last.
// Ref: parted >= 1.8 ./libparted/libparted.c init_disk_types()
@ -3619,24 +3576,23 @@ bool GParted_Core::update_dmraid_entry( const Partition & partition, OperationDe
return success;
}
FileSystem * GParted_Core::get_filesystem_object( FSType fstype )
{
std::map<FSType, FileSystem *>::const_iterator fs_iter = FILESYSTEM_MAP.find( fstype );
if ( fs_iter == FILESYSTEM_MAP.end() )
return NULL;
else
return fs_iter->second;
return supported_filesystems->get_fs_object(fstype);
}
// Return true for file systems with an implementation class, false otherwise
bool GParted_Core::supported_filesystem( FSType fstype )
{
return get_filesystem_object( fstype ) != NULL;
return supported_filesystems->get_fs_object(fstype) != NULL;
}
FS_Limits GParted_Core::get_filesystem_limits( FSType fstype, const Partition & partition )
{
FileSystem *p_filesystem = get_filesystem_object( fstype );
FileSystem* p_filesystem = supported_filesystems->get_fs_object(fstype);
FS_Limits fs_limits;
if ( p_filesystem != NULL )
fs_limits = p_filesystem->get_filesystem_limits( partition );
@ -3980,62 +3936,6 @@ bool GParted_Core::update_bootsector( const Partition & partition, OperationDeta
return true ;
}
void GParted_Core::init_filesystems()
{
// File system support falls into 3 categories determined by their entry in
// FILESYSTEM_MAP:
// 1) Fully supported file systems have an entry pointing to the instance of
// their derived FileSystem object, which determines and implements their
// supported actions.
// supported_filesystem() -> true
// 2) Basic supported file systems have a NULL pointer entry, with
// find_supported_filesystems() creating a basic set of supported actions.
// supported_filesystem() -> false
// 3) Unsupported file systems have no entry, and no supported actions.
// supported_filesystem() -> false
FILESYSTEM_MAP[FS_UNKNOWN] = NULL;
FILESYSTEM_MAP[FS_OTHER] = NULL;
FILESYSTEM_MAP[FS_BTRFS] = new btrfs();
FILESYSTEM_MAP[FS_EXFAT] = new exfat();
FILESYSTEM_MAP[FS_EXT2] = new ext2( FS_EXT2 );
FILESYSTEM_MAP[FS_EXT3] = new ext2( FS_EXT3 );
FILESYSTEM_MAP[FS_EXT4] = new ext2( FS_EXT4 );
FILESYSTEM_MAP[FS_F2FS] = new f2fs();
FILESYSTEM_MAP[FS_FAT16] = new fat16( FS_FAT16 );
FILESYSTEM_MAP[FS_FAT32] = new fat16( FS_FAT32 );
FILESYSTEM_MAP[FS_HFS] = new hfs();
FILESYSTEM_MAP[FS_HFSPLUS] = new hfsplus();
FILESYSTEM_MAP[FS_JFS] = new jfs();
FILESYSTEM_MAP[FS_LINUX_SWAP] = new linux_swap();
FILESYSTEM_MAP[FS_LVM2_PV] = new lvm2_pv();
FILESYSTEM_MAP[FS_LUKS] = new luks();
FILESYSTEM_MAP[FS_MINIX] = new minix();
FILESYSTEM_MAP[FS_NILFS2] = new nilfs2();
FILESYSTEM_MAP[FS_NTFS] = new ntfs();
FILESYSTEM_MAP[FS_REISER4] = new reiser4();
FILESYSTEM_MAP[FS_REISERFS] = new reiserfs();
FILESYSTEM_MAP[FS_UDF] = new udf();
FILESYSTEM_MAP[FS_XFS] = new xfs();
FILESYSTEM_MAP[FS_APFS] = NULL;
FILESYSTEM_MAP[FS_BITLOCKER] = NULL;
FILESYSTEM_MAP[FS_GRUB2_CORE_IMG] = NULL;
FILESYSTEM_MAP[FS_ISO9660] = NULL;
FILESYSTEM_MAP[FS_LINUX_SWRAID] = NULL;
FILESYSTEM_MAP[FS_LINUX_SWSUSPEND] = NULL;
FILESYSTEM_MAP[FS_REFS] = NULL;
FILESYSTEM_MAP[FS_UFS] = NULL;
FILESYSTEM_MAP[FS_ZFS] = NULL;
}
void GParted_Core::fini_filesystems()
{
std::map<FSType, FileSystem *>::iterator fs_iter;
for ( fs_iter = FILESYSTEM_MAP.begin() ; fs_iter != FILESYSTEM_MAP.end() ; fs_iter ++ )
{
delete fs_iter->second;
fs_iter->second = NULL;
}
}
void GParted_Core::capture_libparted_messages( OperationDetail & operationdetail, bool success )
{
@ -4332,12 +4232,15 @@ PedExceptionOption GParted_Core::ped_exception_handler( PedException * e )
GParted_Core::~GParted_Core()
{
// Delete file system map entries
fini_filesystems();
delete supported_filesystems;
supported_filesystems = NULL;
}
Glib::Thread *GParted_Core::mainthread;
std::map< FSType, FileSystem * > GParted_Core::FILESYSTEM_MAP;
SupportedFileSystems* GParted_Core::supported_filesystems;
} //GParted

View File

@ -58,6 +58,7 @@ gpartedbin_SOURCES = \
PipeCapture.cc \
Proc_Partitions_Info.cc \
ProgressBar.cc \
SupportedFileSystems.cc \
SWRaid_Info.cc \
TreeView_Detail.cc \
Utils.cc \

173
src/SupportedFileSystems.cc Normal file
View File

@ -0,0 +1,173 @@
/* Copyright (C) 2016 Mike Fleetwood
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program 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
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
#include "SupportedFileSystems.h"
#include "FileSystem.h"
#include "Utils.h"
#include "btrfs.h"
#include "exfat.h"
#include "ext2.h"
#include "f2fs.h"
#include "fat16.h"
#include "hfs.h"
#include "hfsplus.h"
#include "jfs.h"
#include "linux_swap.h"
#include "lvm2_pv.h"
#include "luks.h"
#include "minix.h"
#include "nilfs2.h"
#include "ntfs.h"
#include "reiser4.h"
#include "reiserfs.h"
#include "udf.h"
#include "xfs.h"
#include <stddef.h>
namespace GParted
{
SupportedFileSystems::SupportedFileSystems()
{
// File system support falls into 3 categories determined by their entry in
// m_fs_objects:
// 1) Fully supported file systems have an entry pointing to the instance of
// their derived FileSystem object, which determines and implements their
// supported actions.
// supported_filesystem() -> true
// 2) Basic supported file systems have a NULL pointer entry, with
// find_supported_filesystems() creating a basic set of supported actions.
// supported_filesystem() -> false
// 3) Unsupported file systems have no entry, and no supported actions.
// supported_filesystem() -> false
m_fs_objects[FS_UNKNOWN] = NULL;
m_fs_objects[FS_OTHER] = NULL;
m_fs_objects[FS_BTRFS] = new btrfs();
m_fs_objects[FS_EXFAT] = new exfat();
m_fs_objects[FS_EXT2] = new ext2(FS_EXT2);
m_fs_objects[FS_EXT3] = new ext2(FS_EXT3);
m_fs_objects[FS_EXT4] = new ext2(FS_EXT4);
m_fs_objects[FS_F2FS] = new f2fs();
m_fs_objects[FS_FAT16] = new fat16(FS_FAT16);
m_fs_objects[FS_FAT32] = new fat16(FS_FAT32);
m_fs_objects[FS_HFS] = new hfs();
m_fs_objects[FS_HFSPLUS] = new hfsplus();
m_fs_objects[FS_JFS] = new jfs();
m_fs_objects[FS_LINUX_SWAP] = new linux_swap();
m_fs_objects[FS_LVM2_PV] = new lvm2_pv();
m_fs_objects[FS_LUKS] = new luks();
m_fs_objects[FS_MINIX] = new minix();
m_fs_objects[FS_NILFS2] = new nilfs2();
m_fs_objects[FS_NTFS] = new ntfs();
m_fs_objects[FS_REISER4] = new reiser4();
m_fs_objects[FS_REISERFS] = new reiserfs();
m_fs_objects[FS_UDF] = new udf();
m_fs_objects[FS_XFS] = new xfs();
m_fs_objects[FS_APFS] = NULL;
m_fs_objects[FS_BITLOCKER] = NULL;
m_fs_objects[FS_GRUB2_CORE_IMG] = NULL;
m_fs_objects[FS_ISO9660] = NULL;
m_fs_objects[FS_LINUX_SWRAID] = NULL;
m_fs_objects[FS_LINUX_SWSUSPEND] = NULL;
m_fs_objects[FS_REFS] = NULL;
m_fs_objects[FS_UFS] = NULL;
m_fs_objects[FS_ZFS] = NULL;
}
SupportedFileSystems::~SupportedFileSystems()
{
FSObjectsMap::iterator iter;
for (iter = m_fs_objects.begin(); iter != m_fs_objects.end(); iter++)
{
delete iter->second;
iter->second = NULL;
}
}
void SupportedFileSystems::find_supported_filesystems()
{
FSObjectsMap::iterator iter;
// Iteration of std::map is ordered according to operator< of the key. Hence the
// m_fs_support vector is constructed in FSType enum order: FS_UNKNOWN, FS_BTRFS,
// ..., FS_XFS, ... . This ultimately controls the default order of the file
// systems in the menus and dialogs.
m_fs_support.clear();
for (iter = m_fs_objects.begin(); iter != m_fs_objects.end(); iter++)
{
if (iter->second)
{
m_fs_support.push_back(iter->second->get_filesystem_support());
}
else
{
// For basic supported file systems create the supported action
// set.
FS fs_basicsupp(iter->first);
fs_basicsupp.move = FS::GPARTED;
fs_basicsupp.copy = FS::GPARTED;
m_fs_support.push_back(fs_basicsupp);
}
}
}
FileSystem* SupportedFileSystems::get_fs_object(FSType fstype) const
{
FSObjectsMap::const_iterator iter = m_fs_objects.find(fstype);
if (iter == m_fs_objects.end())
return NULL;
else
return iter->second;
}
// Return supported action set of the file system type or, if not found, not supported
// action set.
const FS& SupportedFileSystems::get_fs_support(FSType fstype) const
{
for (unsigned int i = 0; i < m_fs_support.size(); i++)
{
if (m_fs_support[i].filesystem == fstype)
return m_fs_support[i];
}
static FS fs_notsupp(FS_UNSUPPORTED);
return fs_notsupp;
}
const std::vector<FS>& SupportedFileSystems::get_all_fs_support() const
{
return m_fs_support;
}
// Return true for file systems with an implementation class, false otherwise.
bool SupportedFileSystems::supported_filesystem(FSType fstype) const
{
return get_fs_object(fstype) != NULL;
}
} //GParted

View File

@ -43,6 +43,7 @@ test_ext2_LDADD = \
$(top_builddir)/src/PipeCapture.$(OBJEXT) \
$(top_builddir)/src/Proc_Partitions_Info.$(OBJEXT) \
$(top_builddir)/src/ProgressBar.$(OBJEXT) \
$(top_builddir)/src/SupportedFileSystems.$(OBJEXT) \
$(top_builddir)/src/SWRaid_Info.$(OBJEXT) \
$(top_builddir)/src/Utils.$(OBJEXT) \
$(top_builddir)/src/btrfs.$(OBJEXT) \