diff --git a/src/dwarfs/categorizer/pcmaudio_categorizer.cpp b/src/dwarfs/categorizer/pcmaudio_categorizer.cpp index cd0194cc..e1dce645 100644 --- a/src/dwarfs/categorizer/pcmaudio_categorizer.cpp +++ b/src/dwarfs/categorizer/pcmaudio_categorizer.cpp @@ -257,9 +257,36 @@ struct Wav64Policy { "data\xf3\xac\xd3\x11\x8c\xd1\x00\xc0\x4f\x8e\xdb\x8a", id_size}; }; -template +struct AiffChunkPolicy { + static constexpr std::string_view const format_name{"AIFF"}; + static constexpr endianness const endian{endianness::BIG}; + static constexpr bool const size_includes_header{false}; + static void preprocess(auto&, std::span) {} +}; + +struct CafChunkPolicy { + static constexpr std::string_view const format_name{"CAF"}; + static constexpr endianness const endian{endianness::BIG}; + static constexpr bool const size_includes_header{false}; + static void preprocess(auto& c, std::span data) { + if (c.header.size == std::numeric_limits::max() && + c.is("data")) { + c.header.size = data.size() - (c.pos + sizeof(c.header)); + } + } +}; + +template +struct WavChunkPolicy { + static constexpr std::string_view const format_name{ + FormatPolicy::format_name}; + static constexpr endianness const endian{endianness::LITTLE}; + static constexpr bool const size_includes_header{ + FormatPolicy::size_includes_header}; + static void preprocess(auto&, std::span) {} +}; + +template class iff_parser final { public: struct chunk { @@ -283,11 +310,10 @@ class iff_parser final { size_t size() const { return header.size; } }; - iff_parser(logger& lgr, std::string_view name, fs::path const& path, - std::span data, size_t pos) + iff_parser(logger& lgr, fs::path const& path, std::span data, + size_t pos) : LOG_PROXY_INIT(lgr) , data_{data} - , name_{name} , path_{path} , pos_{pos} {} @@ -298,20 +324,14 @@ class iff_parser final { c.emplace(); DWARFS_CHECK(read(c->header, pos_), "iff_parser::read failed"); - c->header.size = endian::convert(c->header.size); + c->header.size = endian::convert(c->header.size); c->pos = pos_; - if constexpr (IsCaf) { - if (c->header.size == - std::numeric_limitsheader.size)>::max() && - c->is("data")) { - c->header.size = data_.size() - (pos_ + sizeof(ChunkHeaderType)); - } - } + ChunkPolicy::preprocess(*c, data_); - if constexpr (SizeIncludesHeader) { + if constexpr (ChunkPolicy::size_includes_header) { if (c->header.size < sizeof(ChunkHeaderType)) { - LOG_WARN << "[" << name_ << "] " << path_ + LOG_WARN << "[" << ChunkPolicy::format_name << "] " << path_ << ": invalid chunk size: " << c->header.size; c.reset(); return c; @@ -324,7 +344,7 @@ class iff_parser final { } if (pos_ > data_.size()) { - LOG_WARN << "[" << name_ << "] " << path_ + LOG_WARN << "[" << ChunkPolicy::format_name << "] " << path_ << ": unexpected end of file (pos=" << pos_ << ", hdr.size=" << c->header.size << ", end=" << data_.size() << ")"; @@ -332,8 +352,8 @@ class iff_parser final { return c; } - LOG_TRACE << "[" << name_ << "] " << path_ << ": `" << c->fourcc() - << "` (len=" << c->size() << ")"; + LOG_TRACE << "[" << ChunkPolicy::format_name << "] " << path_ << ": `" + << c->fourcc() << "` (len=" << c->size() << ")"; } return c; @@ -360,9 +380,10 @@ class iff_parser final { return true; } - LOG_WARN << "[" << name_ << "] " << path_ << ": unexpected size for `" - << c.fourcc() << "` chunk: " << c.size() << " (expected " - << expected_size << ")"; + LOG_WARN << "[" << ChunkPolicy::format_name << "] " << path_ + << ": unexpected size for `" << c.fourcc() + << "` chunk: " << c.size() << " (expected " << expected_size + << ")"; return false; } @@ -382,14 +403,14 @@ class iff_parser final { return true; } - LOG_WARN << "[" << name_ << "] " << path_ << ": unexpected end of file"; + LOG_WARN << "[" << ChunkPolicy::format_name << "] " << path_ + << ": unexpected end of file"; return false; } LOG_PROXY_DECL(LoggerPolicy); std::span data_; - std::string_view name_; fs::path const& path_; size_t pos_; }; @@ -573,8 +594,8 @@ bool pcmaudio_categorizer_::check_aiff( static_assert(sizeof(comm_chk_t) == 8); static_assert(sizeof(ssnd_chk_t) == 8); - iff_parser parser( - LOG_GET_LOGGER, "AIFF", path, data, sizeof(file_hdr_t)); + iff_parser parser( + LOG_GET_LOGGER, path, data, sizeof(file_hdr_t)); file_hdr_t file_header; if (!parser.read_file_header(file_header)) { @@ -707,8 +728,8 @@ bool pcmaudio_categorizer_::check_caf( static constexpr uint32_t const kCAFLinearPCMFormatFlagIsLittleEndian{1L << 1}; - iff_parser parser( - LOG_GET_LOGGER, "CAF", path, data, sizeof(caff_hdr_t)); + iff_parser parser( + LOG_GET_LOGGER, path, data, sizeof(caff_hdr_t)); caff_hdr_t caff_hdr; if (!parser.read_file_header(caff_hdr)) { @@ -882,10 +903,8 @@ bool pcmaudio_categorizer_::check_wav_like( static constexpr uint16_t const WAVE_FORMAT_PCM{0x0001}; static constexpr uint16_t const WAVE_FORMAT_EXTENSIBLE{0xFFFE}; - iff_parser - parser(LOG_GET_LOGGER, FormatPolicy::format_name, path, data, - sizeof(file_hdr_t)); + iff_parser, chunk_hdr_t> parser( + LOG_GET_LOGGER, path, data, sizeof(file_hdr_t)); file_hdr_t file_header; if (!parser.read_file_header(file_header)) {