diff options
author | David Tardon <dtardon@redhat.com> | 2016-02-25 17:55:12 +0100 |
---|---|---|
committer | David Tardon <dtardon@redhat.com> | 2016-02-25 17:55:28 +0100 |
commit | 85eaf29e1798c98c2703dbabad818001c5a6ab00 (patch) | |
tree | 3cb39bb18b57bb2de4f77bf47991fa72fdee173e | |
parent | 0a4be9f5f22605d07d0d795c142d821571973b48 (diff) |
refactor format detection
-rw-r--r-- | configure.ac | 1 | ||||
-rw-r--r-- | src/lib/SW602Document.cpp | 104 | ||||
-rw-r--r-- | src/lib/WinText602Header.cpp | 6 | ||||
-rw-r--r-- | src/lib/WinText602Header.h | 4 | ||||
-rw-r--r-- | src/lib/WinText602Parser.cpp | 7 |
5 files changed, 90 insertions, 32 deletions
diff --git a/configure.ac b/configure.ac index f9054a3..49e9b52 100644 --- a/configure.ac +++ b/configure.ac @@ -52,6 +52,7 @@ AC_SUBST(REVENGE_LIBS) # ================== AC_CHECK_HEADERS( boost/optional.hpp \ + boost/scoped_ptr.hpp \ boost/shared_ptr.hpp \ , [], diff --git a/src/lib/SW602Document.cpp b/src/lib/SW602Document.cpp index 2be0e20..038bd1f 100644 --- a/src/lib/SW602Document.cpp +++ b/src/lib/SW602Document.cpp @@ -9,6 +9,9 @@ #include <libsw602/SW602Document.h> +#include <cassert> + +#include <boost/scoped_ptr.hpp> #include <boost/shared_ptr.hpp> #include <librevenge-stream/librevenge-stream.h> @@ -16,8 +19,6 @@ #include "WinText602Header.h" #include "WinText602Parser.h" -using boost::shared_ptr; - using librevenge::RVNGInputStream; using std::string; @@ -28,15 +29,63 @@ namespace libsw602 namespace { -shared_ptr<RVNGInputStream> getContent(librevenge::RVNGInputStream *const ip) +struct DetectionInfo +{ + DetectionInfo(); + + SW602Document::Kind m_kind; + SW602Document::Type m_type; + SW602Document::Confidence m_confidence; + bool m_needsEncoding; +}; + +DetectionInfo::DetectionInfo() + : m_kind(SW602Document::KIND_UNKNOWN) + , m_type(SW602Document::TYPE_UNKNOWN) + , m_confidence(SW602Document::CONFIDENCE_NONE) + , m_needsEncoding(false) { - const shared_ptr<RVNGInputStream> input(ip, SW602_shared_ptr_noop_deleter<librevenge::RVNGInputStream>()); +} - shared_ptr<RVNGInputStream> strm; - if (input->isStructured()) - strm.reset(input->getSubStreamByName("CONTENTS")); +template<class Header> +void fillDetectionInfo(const Header &header, DetectionInfo &info); + +void fillDetectionInfo(const WinText602Header &/*header*/, DetectionInfo &info) +{ + info.m_kind = SW602Document::KIND_TEXT; + info.m_type = SW602Document::TYPE_WINTEXT602; + info.m_needsEncoding = false; + // TODO: handle encryption + info.m_confidence = SW602Document::CONFIDENCE_EXCELLENT; +} + +template<class Header> +bool probe(RVNGInputStream &input, DetectionInfo &info) try +{ + input.seek(0, librevenge::RVNG_SEEK_SET); + Header header; + header.construct(input); + if (header.isValid()) + { + fillDetectionInfo(header, info); + assert(m_kind != SW602Document::KIND_UNKNOWN); + assert(m_type != SW602Document::TYPE_UNKNOWN); + } + return info.m_confidence != SW602Document::CONFIDENCE_NONE; +} +catch (...) +{ + return false; +} - return strm; +SW602Document::Confidence pass(const DetectionInfo &info, SW602Document::Kind &kind, SW602Document::Type *const type, bool *const needsEncoding) +{ + kind = info.m_kind; + if (type) + *type = info.m_type; + if (needsEncoding) + *needsEncoding = info.m_needsEncoding; + return info.m_confidence; } } @@ -46,20 +95,18 @@ SW602Document::Confidence SW602Document::isSupported(librevenge::RVNGInputStream if (!input) return CONFIDENCE_NONE; - shared_ptr<RVNGInputStream> content = getContent(input); - if (bool(content)) + DetectionInfo info; + + if (input->isStructured()) { - content->seek(0, librevenge::RVNG_SEEK_SET); - WinText602Header header(*content); - // TODO: handle encryption - if (header.isValid()) + if (input->existsSubStream("CONTENTS")) { - kind = KIND_TEXT; - if (type) - *type = TYPE_WINTEXT602; - if (needsEncoding) - *needsEncoding = false; - return CONFIDENCE_EXCELLENT; + const boost::scoped_ptr<RVNGInputStream> content(input->getSubStreamByName("CONTENTS")); + if (bool(content)) + { + if (probe<WinText602Header>(*content, info)) + return pass(info, kind, type, needsEncoding); + } } } @@ -104,15 +151,14 @@ SW602Document::Result SW602Document::parse(librevenge::RVNGInputStream *const in { case TYPE_WINTEXT602: { - shared_ptr<RVNGInputStream> content = getContent(input); - if (bool(content)) - { - content->seek(0, librevenge::RVNG_SEEK_SET); - WinText602Parser parser(content); - parser.parse(document); - return RESULT_OK; - } - break; + if (!input->existsSubStream("CONTENTS")) + return RESULT_UNSUPPORTED_FORMAT; + const boost::shared_ptr<RVNGInputStream> content(input->getSubStreamByName("CONTENTS")); + if (!content) + return RESULT_UNSUPPORTED_FORMAT; + WinText602Parser parser(content); + parser.parse(document); + return RESULT_OK; } default: return RESULT_UNSUPPORTED_FORMAT; diff --git a/src/lib/WinText602Header.cpp b/src/lib/WinText602Header.cpp index 8f88a50..75237d2 100644 --- a/src/lib/WinText602Header.cpp +++ b/src/lib/WinText602Header.cpp @@ -18,10 +18,14 @@ namespace libsw602 { -WinText602Header::WinText602Header(librevenge::RVNGInputStream &input) +WinText602Header::WinText602Header() : m_length(0) , m_valid(false) { +} + +void WinText602Header::construct(librevenge::RVNGInputStream &input) +{ m_length = readU32(input); skip(input, 2); const unsigned char *const sig = readNBytes(input, 5); diff --git a/src/lib/WinText602Header.h b/src/lib/WinText602Header.h index 7dd038d..9ed2656 100644 --- a/src/lib/WinText602Header.h +++ b/src/lib/WinText602Header.h @@ -18,7 +18,9 @@ namespace libsw602 class WinText602Header { public: - explicit WinText602Header(librevenge::RVNGInputStream &input); + WinText602Header(); + + void construct(librevenge::RVNGInputStream &input); bool isValid() const; diff --git a/src/lib/WinText602Parser.cpp b/src/lib/WinText602Parser.cpp index 96d371b..1bcd768 100644 --- a/src/lib/WinText602Parser.cpp +++ b/src/lib/WinText602Parser.cpp @@ -17,6 +17,7 @@ #include <librevenge/librevenge.h> #include "SW602MemoryStream.h" +#include "libsw602_utils.h" using boost::shared_ptr; @@ -111,7 +112,7 @@ namespace libsw602 WinText602Parser::WinText602Parser(const boost::shared_ptr<librevenge::RVNGInputStream> input) : SW602TextParser(input) - , m_header(*input) + , m_header() , m_input(input) , m_document(0) , m_sectionMap() @@ -122,6 +123,10 @@ void WinText602Parser::parse(librevenge::RVNGTextInterface *documentInterface) { m_document = documentInterface; + m_header.construct(*m_input); + if (!m_header.isValid()) + throw ParseException(); + m_sectionMap.reset(new WinText602SectionMap(*m_input)); m_document->startDocument(librevenge::RVNGPropertyList()); |