diff --git a/.gitmodules b/.gitmodules index aecac93..94e1d37 100644 --- a/.gitmodules +++ b/.gitmodules @@ -4,3 +4,6 @@ [submodule "lib/pbl/pbl"] path = lib/pbl/pbl url = https://github.com/peterGraf/pbl.git +[submodule "lib/better-enums"] + path = lib/better-enums + url = https://github.com/aantron/better-enums diff --git a/include/dindexer-machinery/mediatypes.hpp b/include/dindexer-machinery/mediatypes.hpp index ede0b32..205179a 100644 --- a/include/dindexer-machinery/mediatypes.hpp +++ b/include/dindexer-machinery/mediatypes.hpp @@ -19,21 +19,22 @@ #define id700AFD0F33634ACC88079BB8853A9E13 #include "helpers/compatibility.h" +#include "enum.h" #include namespace mchlib { - enum MediaTypes { - MediaType_CDRom = 'C', - MediaType_Directory = 'D', - MediaType_DVD = 'V', - MediaType_BluRay = 'B', - MediaType_FloppyDisk = 'F', - MediaType_HardDisk = 'H', - MediaType_IomegaZip = 'Z', - MediaType_Other = 'O' - }; + BETTER_ENUM(MediaTypes, char, + CDRom = 'C', + Directory = 'D', + DVD = 'V', + BluRay = 'B', + FloppyDisk = 'F', + HardDisk = 'H', + IomegaZip = 'Z', + Other = 'O' + ); - const std::string& media_type_to_str ( MediaTypes parType ); + std::string media_type_to_str ( MediaTypes parType ); MediaTypes char_to_media_type ( char parMType ) a_pure; char media_type_to_char ( MediaTypes parMType ) a_pure; } //namespace mchlib diff --git a/lib/better-enums b/lib/better-enums new file mode 160000 index 0000000..18cbeb0 --- /dev/null +++ b/lib/better-enums @@ -0,0 +1 @@ +Subproject commit 18cbeb0808697a9a71ce281c033ae468d74e2e29 diff --git a/src/machinery/CMakeLists.txt b/src/machinery/CMakeLists.txt index 08f077c..cda93f0 100644 --- a/src/machinery/CMakeLists.txt +++ b/src/machinery/CMakeLists.txt @@ -3,6 +3,9 @@ project(${bare_name}-machinery CXX C) include(WithMediaAutodetect) find_package(Magic REQUIRED) +option(DINDEXER_WITH_NICE_MEDIA_TYPES "Enable this if C++14 is available in order to get some nicer media type names, like CD-Rom instead of CDRom" OFF) +string(TOUPPER ${DINDEXER_WITH_NICE_MEDIA_TYPES} DINDEXER_WITH_NICE_MEDIA_TYPES) + add_library(${PROJECT_NAME} SHARED pathname.cpp tiger.c @@ -26,6 +29,7 @@ add_library(${PROJECT_NAME} SHARED target_include_directories(${PROJECT_NAME} PRIVATE ${MAGIC_INCLUDE_DIR} + PRIVATE ${CMAKE_CURRENT_BINARY_DIR} ) target_link_libraries(${PROJECT_NAME} @@ -35,14 +39,17 @@ target_link_libraries(${PROJECT_NAME} target_include_directories(${PROJECT_NAME} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} + PUBLIC ${CMAKE_SOURCE_DIR}/lib/better-enums ) target_compile_features(${PROJECT_NAME} PUBLIC cxx_constexpr - PRIVATE cxx_relaxed_constexpr PUBLIC cxx_nullptr PUBLIC cxx_override ) +if (DINDEXER_WITH_NICE_MEDIA_TYPES) + target_compile_features(${PROJECT_NAME} PRIVATE cxx_relaxed_constexpr) +endif() if (DINDEXER_WITH_MEDIA_AUTODETECT) target_include_directories(${PROJECT_NAME} SYSTEM @@ -61,3 +68,5 @@ install(TARGETS ${PROJECT_NAME} RUNTIME DESTINATION bin ARCHIVE DESTINATION lib/static ) + +configure_file(machineryConfig.h.in ${CMAKE_CURRENT_BINARY_DIR}/machineryConfig.h) diff --git a/src/machinery/guess_content_type.cpp b/src/machinery/guess_content_type.cpp index a609c92..304c23e 100644 --- a/src/machinery/guess_content_type.cpp +++ b/src/machinery/guess_content_type.cpp @@ -88,7 +88,7 @@ namespace mchlib { } bool identify_video_dvd (MediaTypes parMediaType, const ConstSetListingView& parContent, const std::vector& parFlatContent ) { - if (parMediaType != MediaType_DVD and parMediaType != MediaType_Directory) + if (parMediaType != +MediaTypes::DVD and parMediaType != +MediaTypes::Directory) return false; const auto items_count = count_listing_items(parContent); @@ -104,7 +104,7 @@ namespace mchlib { } bool identify_video_cd (MediaTypes parMediaType, const ConstSetListingView& parContent, const std::vector& parFlatContent) { - if (parMediaType != MediaType_CDRom and parMediaType != MediaType_Directory) + if (parMediaType != +MediaTypes::CDRom and parMediaType != +MediaTypes::Directory) return false; const auto items_count = count_listing_items(parContent); diff --git a/src/machinery/machineryConfig.h.in b/src/machinery/machineryConfig.h.in new file mode 100644 index 0000000..cf264da --- /dev/null +++ b/src/machinery/machineryConfig.h.in @@ -0,0 +1,32 @@ +/* Copyright 2015, 2016, Michele Santullo + * This file is part of "dindexer". + * + * "dindexer" 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 3 of the License, or + * (at your option) any later version. + * + * "dindexer" 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 "dindexer". If not, see . + */ + +#ifndef id32A00B72E29D463795CBF66517387E8D +#define id32A00B72E29D463795CBF66517387E8D + +#if !defined(CMAKE_ON) +# define CMAKE_ON 1 +#endif +#if !defined(CMAKE_OFF) +# define CMAKE_OFF 0 +#endif + +#if CMAKE_@DINDEXER_WITH_NICE_MEDIA_TYPES@ +# define WITH_NICE_MEDIA_TYPES +#endif + +#endif diff --git a/src/machinery/mediatype.cpp b/src/machinery/mediatype.cpp index 4a3feb3..5b3feb2 100644 --- a/src/machinery/mediatype.cpp +++ b/src/machinery/mediatype.cpp @@ -45,18 +45,18 @@ namespace mchlib { const DriveTypes drive_type = info.drive_type(); if (DriveType_HardDisk == drive_type) { if (info.mountpoint() == PathName(info.original_path()).path()) - return MediaType_HardDisk; + return MediaTypes::HardDisk; else - return MediaType_Directory; + return MediaTypes::Directory; } else if (DriveType_Optical == drive_type) { switch (info.optical_type()) { case OpticalType_DVD: - return MediaType_DVD; + return MediaTypes::DVD; case OpticalType_CDRom: - return MediaType_CDRom; + return MediaTypes::CDRom; case OpticalType_BluRay: - return MediaType_BluRay; + return MediaTypes::BluRay; default: throw UnknownMediaTypeException("Set autodetect failed because this media type is unknown, please specify the set type manually"); } diff --git a/src/machinery/mediatypes.cpp b/src/machinery/mediatypes.cpp index f6ab0dc..d4c9aed 100644 --- a/src/machinery/mediatypes.cpp +++ b/src/machinery/mediatypes.cpp @@ -16,35 +16,49 @@ */ #include "dindexer-machinery/mediatypes.hpp" -#include +#include "machineryConfig.h" #include namespace mchlib { - const std::string& media_type_to_str (MediaTypes parType) { - static const std::map types { - {MediaType_CDRom, "CD-Rom"}, - {MediaType_Directory, "Directory"}, - {MediaType_DVD, "DVD"}, - {MediaType_BluRay, "BluRay"}, - {MediaType_FloppyDisk, "Floppy Disk"}, - {MediaType_HardDisk, "Hard Disk"}, - {MediaType_IomegaZip, "Iomega Zip"}, - {MediaType_Other, "Other"} - }; + namespace { +#if defined(WITH_NICE_MEDIA_TYPES) + constexpr const char* get_enum_desc (MediaTypes parType) { + switch (parType) { + case MediaTypes::CDRom: return "CD-Rom"; + case MediaTypes::Directory: return "Directory"; + case MediaTypes::DVD: return "DVD"; + case MediaTypes::BluRay: return "BluRay"; + case MediaTypes::FloppyDisk: return "Floppy Disk"; + case MediaTypes::HardDisk: return "Hard Disk"; + case MediaTypes::IomegaZip: return "Iomega Zip"; + case MediaTypes::Other: return "Other"; + } + return "needed for gcc 5"; + } - auto it_ret = types.find(parType); - if (types.end() == it_ret) { + constexpr auto g_descriptions = ::better_enums::make_map(get_enum_desc); +#endif + } //unnamed namespace + + std::string media_type_to_str (MediaTypes parType) { + try { +#if defined(WITH_NICE_MEDIA_TYPES) + return std::string(g_descriptions[parType]); +#else + return std::string(parType._to_string()); +#endif + } + catch (const std::runtime_error&) { const char err[2] = {static_cast(parType), '\0'}; throw std::out_of_range(err); } - return it_ret->second; } MediaTypes char_to_media_type (char parMType) { - return static_cast(parMType); + return MediaTypes::_from_integral(parMType); } char media_type_to_char (MediaTypes parMType) { - return static_cast(parMType); + return parMType._to_integral(); } } //namespace mchlib diff --git a/src/scan/commandline.cpp b/src/scan/commandline.cpp index 92d04cb..3c47612 100644 --- a/src/scan/commandline.cpp +++ b/src/scan/commandline.cpp @@ -16,26 +16,14 @@ */ #include "commandline.hpp" -#include "helpers/lengthof.h" #include "dindexer-common/commandline.hpp" #include #include -#include namespace po = boost::program_options; namespace din { namespace { - const char g_allowed_types[] = { - static_cast(mchlib::MediaType_CDRom), - static_cast(mchlib::MediaType_Directory), - static_cast(mchlib::MediaType_DVD), - static_cast(mchlib::MediaType_BluRay), - static_cast(mchlib::MediaType_FloppyDisk), - static_cast(mchlib::MediaType_HardDisk), - static_cast(mchlib::MediaType_IomegaZip), - static_cast(mchlib::MediaType_Other) - }; } //unnamed namespace bool parse_commandline (int parArgc, char* parArgv[], po::variables_map& parVarMap) { @@ -43,9 +31,10 @@ namespace din { { std::ostringstream oss; oss << "Default set type. Valid values are "; - oss << g_allowed_types[0]; - for (std::size_t z = 1; z < lengthof(g_allowed_types); ++z) { - oss << ", " << g_allowed_types[z]; + const char* comma = ""; + for (auto mediatype : mchlib::MediaTypes::_values()) { + oss << comma << mediatype._to_integral() << " (" << mediatype << ')'; + comma = ", "; } oss << '.'; #if defined(WITH_MEDIA_AUTODETECT) @@ -95,7 +84,8 @@ namespace din { #if defined(WITH_MEDIA_AUTODETECT) if (parVarMap.count("type")) { #endif - if (g_allowed_types + lengthof(g_allowed_types) == std::find(g_allowed_types, g_allowed_types + lengthof(g_allowed_types), parVarMap["type"].as())) { + better_enums::optional maybe_mediatype = mchlib::MediaTypes::_from_integral_nothrow(parVarMap["type"].as()); + if (!maybe_mediatype) { throw std::invalid_argument("Invalid value for parameter \"type\""); } #if defined(WITH_MEDIA_AUTODETECT) diff --git a/test/unit/test_guess_content_type.cpp b/test/unit/test_guess_content_type.cpp index 1cf18ab..8623ec3 100644 --- a/test/unit/test_guess_content_type.cpp +++ b/test/unit/test_guess_content_type.cpp @@ -52,7 +52,7 @@ TEST(machinery, guess_content_type) { FileRecordData("VIDEO_TS/VTS_01_0.VOB",0,0,2,false,false), FileRecordData("VIDEO_TS/VIDEO_TS.VOB",0,0,2,false,false) }; - detect_type(test_data, mchlib::ContentType_VideoDVD, mchlib::MediaType_DVD); + detect_type(test_data, mchlib::ContentType_VideoDVD, mchlib::MediaTypes::DVD); } { @@ -63,7 +63,7 @@ TEST(machinery, guess_content_type) { FileRecordData("some_file.bin",0,0,1,false,false), FileRecordData("another_dir/VTS_01_0.BUP",0,0,2,false,false) }; - detect_type(test_data, mchlib::ContentType_Generic, mchlib::MediaType_Directory); + detect_type(test_data, mchlib::ContentType_Generic, mchlib::MediaTypes::Directory); } { @@ -81,6 +81,6 @@ TEST(machinery, guess_content_type) { FileRecordData("CDI",0,0,1,true,false), FileRecordData("KARAOKE",0,0,1,true,false) }; - detect_type(test_data, mchlib::ContentType_VideoCD, mchlib::MediaType_CDRom); + detect_type(test_data, mchlib::ContentType_VideoCD, mchlib::MediaTypes::CDRom); } }