From f31463480f370470c30c51c9de4b010252655e9d Mon Sep 17 00:00:00 2001 From: King_DuckZ Date: Fri, 19 Feb 2016 21:57:43 +0100 Subject: [PATCH] Add stub code to detect VCDs, plus unit test. --- .../dindexer-machinery/guess_content_type.hpp | 3 +- .../set_listing_helpers.hpp | 29 ++++--- src/machinery/guess_content_type.cpp | 78 +++++++++++++++-- test/unit/CMakeLists.txt | 1 + test/unit/test_guess_content_type.cpp | 84 +++++++++++++++++++ 5 files changed, 179 insertions(+), 16 deletions(-) create mode 100644 test/unit/test_guess_content_type.cpp diff --git a/include/dindexer-machinery/guess_content_type.hpp b/include/dindexer-machinery/guess_content_type.hpp index 391b43f..2af43b6 100644 --- a/include/dindexer-machinery/guess_content_type.hpp +++ b/include/dindexer-machinery/guess_content_type.hpp @@ -28,12 +28,13 @@ namespace mchlib { ContentType_Backup, ContentType_VideoDVD, ContentType_VideoBD, + ContentType_VideoCD, ContentType_Unknown }; template class SetListingView; - ContentTypes guess_content_type ( dinlib::MediaTypes parMediaType, const SetListingView& parContent ); + ContentTypes guess_content_type ( dinlib::MediaTypes parMediaType, const SetListingView& parContent, std::size_t parEntriesCount=0 ); } //namespace mchlib #endif diff --git a/include/dindexer-machinery/set_listing_helpers.hpp b/include/dindexer-machinery/set_listing_helpers.hpp index e15c3b0..3d9efa7 100644 --- a/include/dindexer-machinery/set_listing_helpers.hpp +++ b/include/dindexer-machinery/set_listing_helpers.hpp @@ -61,16 +61,25 @@ namespace mchlib { template inline - std::size_t count_listing_items (const SetListingView& /*parList*/) { - assert(false); - return 0; - //return std::count_if( - // parList.cbegin(), - // parList.cend(), - // [] (const FileRecordData&) { - // return true; - // } - //); + std::size_t count_listing_items (const SetListingView& parList) { + return std::count_if( + parList.cbegin(), + parList.cend(), + [] (const FileRecordData&) { + return true; + } + ); + } + + template + inline + std::size_t count_listing_items_recursive (const SetListingView& parList) { + std::size_t retval = 0; + for (auto it = parList.begin(), itEND = parList.end(); it != itEND; ++it, ++retval) { + if (it->is_directory) + retval += count_listing_items_recursive(SetListingView(it)); + } + return retval; } } //namespace mchlib diff --git a/src/machinery/guess_content_type.cpp b/src/machinery/guess_content_type.cpp index cb992f8..75725d2 100644 --- a/src/machinery/guess_content_type.cpp +++ b/src/machinery/guess_content_type.cpp @@ -18,7 +18,7 @@ #ifndef idF5514EBEE7DA404CA2271A4AE74A28D4 #define idF5514EBEE7DA404CA2271A4AE74A28D4 -#include "guess_content_type.hpp" +#include "dindexer-machinery/guess_content_type.hpp" #include "dindexer-machinery/set_listing.hpp" #include "dindexer-machinery/set_listing_helpers.hpp" #include @@ -27,9 +27,12 @@ #include #include #include +#include namespace mchlib { namespace { + using FoundItemPair = std::pair; + template struct IsLevelLikeO { bool operator() ( const FileRecordData& parEntry ); @@ -65,6 +68,29 @@ namespace mchlib { return (parEntry.path == parPath); } + //std::vector check_missing_content (const ConstSetListingView& parContent, const std::vector& parCheck) { + // std::vector retval; + // for (int z = 0; z < static_cast(parCheck.size()), ++z) { + // auto glob_range = glob(parContent, parCheck[z]); + // if (boost::empty(glob_range)) { + // retval.push_back(z); + // } + // } + // return std::move(retval); + //} + + FoundItemPair find_item (const ConstSetListingView& parContent, const char* parPath) { + auto it = std::find_if( + parContent.begin(), + parContent.end(), + [parPath](const FileRecordData& parEntry) { + return (parEntry.path == parPath); + } + ); + + return std::make_pair(parContent.end() != it, it); + } + bool identify_video_dvd (dinlib::MediaTypes parMediaType, const ConstSetListingView& parContent) { if (parMediaType != dinlib::MediaType_DVD) { return false; @@ -87,15 +113,57 @@ namespace mchlib { return true; } + + bool identify_video_cd (dinlib::MediaTypes parMediaType, const ConstSetListingView& parContent) { + if (parMediaType != dinlib::MediaType_CDRom) + return false; + + const auto items_count = count_listing_items(parContent); + if (items_count < 4) + return false; + + //const std::vector should_have { + // "SVCD/*.VCD", + // "MPEGAV/AVSEQ??.DAT", + // "SEGMENT/ITEM???.DAT", + // "CDI" + //}; + + auto found = find_item(parContent, "SVCD"); + if (not found.first or not found.second->is_directory) + return false; + found = find_item(parContent, "MPEGAV"); + if (not found.first or not found.second->is_directory) + return false; + found = find_item(parContent, "SEGMENT"); + if (not found.first or not found.second->is_directory) + return false; + found = find_item(parContent, "CDI"); + if (not found.first or not found.second->is_directory) + return false; + + //FileRecordData("SVCD",0,0,1,true,false), + //FileRecordData("SVCD/INFO.VCD",0,0,2,false,false), + //FileRecordData("SVCD/ENTRIES.VCD",0,0,2,false,false), + //FileRecordData("SVCD/SEARCH.DAT",0,0,2,false,false), + //FileRecordData("SVCD/PSD.VCD",0,0,2,false,false), + //FileRecordData("MPEGAV",0,0,1,true,false), + //FileRecordData("MPEGAV/AVSEQ01.DAT",0,0,2,false,false), + //FileRecordData("SEGMENT",0,0,1,true,false), + //FileRecordData("SEGMENT/ITEM001.DAT",0,0,2,false,false), + //FileRecordData("CDI",0,0,1,true,false), + //FileRecordData("KARAOKE",0,0,1,true,false) + return true; + } } //unnamed namespace - ContentTypes guess_content_type (dinlib::MediaTypes parMediaType, const ConstSetListingView& parContent) { + ContentTypes guess_content_type (dinlib::MediaTypes parMediaType, const ConstSetListingView& parContent, std::size_t parEntriesCount) { std::vector checker_chain { - { 100, &identify_video_dvd, ContentType_VideoDVD } + { 100, &identify_video_dvd, ContentType_VideoDVD }, + { 200, &identify_video_cd, ContentType_VideoCD } }; - assert(false); - const auto total_entries = count_listing_items_recursive(parContent); + const auto total_entries = (parEntriesCount ? parEntriesCount : count_listing_items_recursive(parContent)); for (const auto& chk : checker_chain) { if (chk.max_total_entries and chk.max_total_entries >= total_entries) { diff --git a/test/unit/CMakeLists.txt b/test/unit/CMakeLists.txt index 2292710..e968222 100644 --- a/test/unit/CMakeLists.txt +++ b/test/unit/CMakeLists.txt @@ -2,6 +2,7 @@ project(${bare_name}-test CXX) add_executable(${PROJECT_NAME} test_diriterator.cpp + test_guess_content_type.cpp ) target_include_directories(${PROJECT_NAME} SYSTEM diff --git a/test/unit/test_guess_content_type.cpp b/test/unit/test_guess_content_type.cpp new file mode 100644 index 0000000..32f6207 --- /dev/null +++ b/test/unit/test_guess_content_type.cpp @@ -0,0 +1,84 @@ +/* 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 . + */ + +#include "dindexer-machinery/guess_content_type.hpp" +#include "dindexer-machinery/set_listing.hpp" +#include +#include +#include + +namespace { + template + void detect_type (mchlib::FileRecordData (&parTestData)[N], mchlib::ContentTypes parExpected, dinlib::MediaTypes parMediaType) { + using mchlib::SetListing; + using mchlib::FileRecordData; + + std::vector test_data( + std::make_move_iterator(std::begin(parTestData)), + std::make_move_iterator(std::end(parTestData)) + ); + SetListing dvd_listing(std::move(test_data)); + + const mchlib::ContentTypes detected_type = + guess_content_type(parMediaType, dvd_listing.make_cview()); + + EXPECT_EQ(parExpected, detected_type); + } +} //unnamed namespace + +TEST(machinery, guess_content_type) { + using mchlib::FileRecordData; + + { + FileRecordData test_data[] = { + FileRecordData("",0,0,0,true,false), + FileRecordData("VIDEO_TS",0,0,1,true,false), + FileRecordData("AUDIO_TS",0,0,1,true,false), + FileRecordData("VIDEO_TS/VTS_01_0.BUP",0,0,2,false,false) + }; + detect_type(test_data, mchlib::ContentType_VideoDVD, dinlib::MediaType_DVD); + } + + { + FileRecordData test_data[] = { + FileRecordData("",0,0,0,true,false), + FileRecordData("dummy",0,0,1,true,false), + FileRecordData("another_dir",0,0,1,true,false), + 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, dinlib::MediaType_Directory); + } + + { + FileRecordData test_data[] = { + FileRecordData("",0,0,0,true,false), + FileRecordData("SVCD",0,0,1,true,false), + FileRecordData("SVCD/INFO.VCD",0,0,2,false,false), + FileRecordData("SVCD/ENTRIES.VCD",0,0,2,false,false), + FileRecordData("SVCD/SEARCH.DAT",0,0,2,false,false), + FileRecordData("SVCD/PSD.VCD",0,0,2,false,false), + FileRecordData("MPEGAV",0,0,1,true,false), + FileRecordData("MPEGAV/AVSEQ01.DAT",0,0,2,false,false), + FileRecordData("SEGMENT",0,0,1,true,false), + FileRecordData("SEGMENT/ITEM001.DAT",0,0,2,false,false), + FileRecordData("CDI",0,0,1,true,false), + FileRecordData("KARAOKE",0,0,1,true,false) + }; + detect_type(test_data, mchlib::ContentType_VideoCD, dinlib::MediaType_CDRom); + } +}