diff --git a/lib/Epub/Epub/htmlEntities.cpp b/lib/Epub/Epub/htmlEntities.cpp index 6fdcb71c..2fd35b8a 100644 --- a/lib/Epub/Epub/htmlEntities.cpp +++ b/lib/Epub/Epub/htmlEntities.cpp @@ -4,6 +4,7 @@ #include "htmlEntities.h" #include +#include struct EntityPair { const char* key; @@ -62,8 +63,6 @@ static constexpr EntityPair ENTITY_LOOKUP[] = { {"¥", "¥"}, {"ÿ", "ÿ"}, {"ζ", "ζ"}, {"‍", "\u200D"}, {"‌", "\u200C"}, }; -static const size_t ENTITY_LOOKUP_COUNT = sizeof(ENTITY_LOOKUP) / sizeof(ENTITY_LOOKUP[0]); - // Verify the table is sorted at compile time. static constexpr int constexprStrcmp(const char* a, const char* b) { for (size_t i = 0;; i++) { @@ -73,7 +72,7 @@ static constexpr int constexprStrcmp(const char* a, const char* b) { } static constexpr bool isTableSorted() { - for (size_t i = 1; i < ENTITY_LOOKUP_COUNT; i++) { + for (size_t i = 1; i < std::size(ENTITY_LOOKUP); i++) { if (constexprStrcmp(ENTITY_LOOKUP[i - 1].key, ENTITY_LOOKUP[i].key) >= 0) return false; } return true; @@ -85,7 +84,7 @@ const char* lookupHtmlEntity(const char* entity, size_t len) { if (entity == nullptr || len == 0) return nullptr; size_t lo = 0; - size_t hi = ENTITY_LOOKUP_COUNT; + size_t hi = std::size(ENTITY_LOOKUP); while (lo < hi) { const size_t mid = lo + (hi - lo) / 2; diff --git a/lib/Epub/Epub/parsers/ChapterHtmlSlimParser.cpp b/lib/Epub/Epub/parsers/ChapterHtmlSlimParser.cpp index 3c8694af..92f0280a 100644 --- a/lib/Epub/Epub/parsers/ChapterHtmlSlimParser.cpp +++ b/lib/Epub/Epub/parsers/ChapterHtmlSlimParser.cpp @@ -8,42 +8,30 @@ #include #include +#include + #include "../../Epub.h" #include "../Page.h" #include "../converters/ImageDecoderFactory.h" #include "../converters/ImageToFramebufferDecoder.h" #include "../htmlEntities.h" -const char* HEADER_TAGS[] = {"h1", "h2", "h3", "h4", "h5", "h6"}; -constexpr int NUM_HEADER_TAGS = sizeof(HEADER_TAGS) / sizeof(HEADER_TAGS[0]); - // Minimum file size (in bytes) to show indexing popup - smaller chapters don't benefit from it constexpr size_t MIN_SIZE_FOR_POPUP = 10 * 1024; // 10KB constexpr size_t PARSE_BUFFER_SIZE = 1024; -const char* BLOCK_TAGS[] = {"p", "li", "div", "br", "blockquote"}; -constexpr int NUM_BLOCK_TAGS = sizeof(BLOCK_TAGS) / sizeof(BLOCK_TAGS[0]); - -const char* BOLD_TAGS[] = {"b", "strong"}; -constexpr int NUM_BOLD_TAGS = sizeof(BOLD_TAGS) / sizeof(BOLD_TAGS[0]); - -const char* ITALIC_TAGS[] = {"i", "em"}; -constexpr int NUM_ITALIC_TAGS = sizeof(ITALIC_TAGS) / sizeof(ITALIC_TAGS[0]); - -const char* UNDERLINE_TAGS[] = {"u", "ins"}; -constexpr int NUM_UNDERLINE_TAGS = sizeof(UNDERLINE_TAGS) / sizeof(UNDERLINE_TAGS[0]); - -const char* IMAGE_TAGS[] = {"img"}; -constexpr int NUM_IMAGE_TAGS = sizeof(IMAGE_TAGS) / sizeof(IMAGE_TAGS[0]); - -const char* SKIP_TAGS[] = {"head"}; -constexpr int NUM_SKIP_TAGS = sizeof(SKIP_TAGS) / sizeof(SKIP_TAGS[0]); +constexpr const char* HEADER_TAGS[] = {"h1", "h2", "h3", "h4", "h5", "h6"}; +constexpr const char* BLOCK_TAGS[] = {"p", "li", "div", "br", "blockquote"}; +constexpr const char* BOLD_TAGS[] = {"b", "strong"}; +constexpr const char* ITALIC_TAGS[] = {"i", "em"}; +constexpr const char* UNDERLINE_TAGS[] = {"u", "ins"}; +constexpr const char* IMAGE_TAGS[] = {"img"}; +constexpr const char* SKIP_TAGS[] = {"head"}; bool isWhitespace(const char c) { return c == ' ' || c == '\r' || c == '\n' || c == '\t'; } -// given the start and end of a tag, check to see if it matches a known tag -bool matches(const char* tag_name, const char* possible_tags[], const int possible_tag_count) { - for (int i = 0; i < possible_tag_count; i++) { +bool matches(const char* tag_name, const char* const* possible_tags, size_t count) { + for (size_t i = 0; i < count; i++) { if (strcmp(tag_name, possible_tags[i]) == 0) { return true; } @@ -70,7 +58,7 @@ bool isInternalEpubLink(const char* href) { } bool isHeaderOrBlock(const char* name) { - return matches(name, HEADER_TAGS, NUM_HEADER_TAGS) || matches(name, BLOCK_TAGS, NUM_BLOCK_TAGS); + return matches(name, HEADER_TAGS, std::size(HEADER_TAGS)) || matches(name, BLOCK_TAGS, std::size(BLOCK_TAGS)); } bool isTableStructuralTag(const char* name) { @@ -271,7 +259,7 @@ void XMLCALL ChapterHtmlSlimParser::startElement(void* userData, const XML_Char* return; } - if (matches(name, IMAGE_TAGS, NUM_IMAGE_TAGS)) { + if (matches(name, IMAGE_TAGS, std::size(IMAGE_TAGS))) { std::string src; std::string alt; if (atts != nullptr) { @@ -541,7 +529,7 @@ void XMLCALL ChapterHtmlSlimParser::startElement(void* userData, const XML_Char* } } - if (matches(name, SKIP_TAGS, NUM_SKIP_TAGS)) { + if (matches(name, SKIP_TAGS, std::size(SKIP_TAGS))) { // start skip self->skipUntilDepth = self->depth; self->depth += 1; @@ -608,7 +596,7 @@ void XMLCALL ChapterHtmlSlimParser::startElement(void* userData, const XML_Char* const auto userAlignmentBlockStyle = BlockStyle::fromCssStyle( cssStyle, emSize, static_cast(self->paragraphAlignment), self->viewportWidth); - if (matches(name, HEADER_TAGS, NUM_HEADER_TAGS)) { + if (matches(name, HEADER_TAGS, std::size(HEADER_TAGS))) { self->currentCssStyle = cssStyle; auto headerBlockStyle = BlockStyle::fromCssStyle(cssStyle, emSize, CssTextAlign::Center, self->viewportWidth); headerBlockStyle.textAlignDefined = true; @@ -621,7 +609,7 @@ void XMLCALL ChapterHtmlSlimParser::startElement(void* userData, const XML_Char* self->startNewTextBlock(accumulated.withoutBottom()); self->boldUntilDepth = std::min(self->boldUntilDepth, self->depth); self->updateEffectiveInlineStyle(); - } else if (matches(name, BLOCK_TAGS, NUM_BLOCK_TAGS)) { + } else if (matches(name, BLOCK_TAGS, std::size(BLOCK_TAGS))) { if (strcmp(name, "br") == 0) { if (self->partWordBufferIndex > 0) { // flush word preceding
to currentTextBlock before calling startNewTextBlock @@ -640,7 +628,7 @@ void XMLCALL ChapterHtmlSlimParser::startElement(void* userData, const XML_Char* self->currentTextBlock->addWord("\xe2\x80\xa2", EpdFontFamily::REGULAR); } } - } else if (matches(name, UNDERLINE_TAGS, NUM_UNDERLINE_TAGS)) { + } else if (matches(name, UNDERLINE_TAGS, std::size(UNDERLINE_TAGS))) { // Flush buffer before style change so preceding text gets current style if (self->partWordBufferIndex > 0) { self->flushPartWordBuffer(); @@ -662,7 +650,7 @@ void XMLCALL ChapterHtmlSlimParser::startElement(void* userData, const XML_Char* } self->inlineStyleStack.push_back(entry); self->updateEffectiveInlineStyle(); - } else if (matches(name, BOLD_TAGS, NUM_BOLD_TAGS)) { + } else if (matches(name, BOLD_TAGS, std::size(BOLD_TAGS))) { // Flush buffer before style change so preceding text gets current style if (self->partWordBufferIndex > 0) { self->flushPartWordBuffer(); @@ -684,7 +672,7 @@ void XMLCALL ChapterHtmlSlimParser::startElement(void* userData, const XML_Char* } self->inlineStyleStack.push_back(entry); self->updateEffectiveInlineStyle(); - } else if (matches(name, ITALIC_TAGS, NUM_ITALIC_TAGS)) { + } else if (matches(name, ITALIC_TAGS, std::size(ITALIC_TAGS))) { // Flush buffer before style change so preceding text gets current style if (self->partWordBufferIndex > 0) { self->flushPartWordBuffer(); @@ -946,12 +934,12 @@ void XMLCALL ChapterHtmlSlimParser::endElement(void* userData, const XML_Char* n // Flush buffer with current style BEFORE any style changes if (self->partWordBufferIndex > 0) { // Flush if style will change OR if we're closing a block/structural element - const bool isInlineTag = - !headerOrBlockTag && !tableStructuralTag && !matches(name, IMAGE_TAGS, NUM_IMAGE_TAGS) && self->depth != 1; - const bool shouldFlush = styleWillChange || headerOrBlockTag || matches(name, BOLD_TAGS, NUM_BOLD_TAGS) || - matches(name, ITALIC_TAGS, NUM_ITALIC_TAGS) || - matches(name, UNDERLINE_TAGS, NUM_UNDERLINE_TAGS) || tableStructuralTag || - matches(name, IMAGE_TAGS, NUM_IMAGE_TAGS) || self->depth == 1; + const bool isInlineTag = !headerOrBlockTag && !tableStructuralTag && + !matches(name, IMAGE_TAGS, std::size(IMAGE_TAGS)) && self->depth != 1; + const bool shouldFlush = styleWillChange || headerOrBlockTag || matches(name, BOLD_TAGS, std::size(BOLD_TAGS)) || + matches(name, ITALIC_TAGS, std::size(ITALIC_TAGS)) || + matches(name, UNDERLINE_TAGS, std::size(UNDERLINE_TAGS)) || tableStructuralTag || + matches(name, IMAGE_TAGS, std::size(IMAGE_TAGS)) || self->depth == 1; if (shouldFlush) { self->flushPartWordBuffer(); diff --git a/src/network/CrossPointWebServer.cpp b/src/network/CrossPointWebServer.cpp index 0ad2f1ab..2346f221 100644 --- a/src/network/CrossPointWebServer.cpp +++ b/src/network/CrossPointWebServer.cpp @@ -22,8 +22,7 @@ namespace { // Folders/files to hide from the web interface file browser // Note: Items starting with "." are automatically hidden -const char* HIDDEN_ITEMS[] = {"System Volume Information", "XTCache"}; -constexpr size_t HIDDEN_ITEMS_COUNT = sizeof(HIDDEN_ITEMS) / sizeof(HIDDEN_ITEMS[0]); +constexpr const char* HIDDEN_ITEMS[] = {"System Volume Information", "XTCache"}; constexpr uint16_t UDP_PORTS[] = {54982, 48123, 39001, 44044, 59678}; constexpr uint16_t LOCAL_UDP_PORT = 8134; @@ -75,8 +74,8 @@ bool isProtectedItemName(const String& name) { if (name.startsWith(".")) { return true; } - for (size_t i = 0; i < HIDDEN_ITEMS_COUNT; i++) { - if (name.equals(HIDDEN_ITEMS[i])) { + for (const auto* item : HIDDEN_ITEMS) { + if (name.equals(item)) { return true; } } @@ -389,8 +388,8 @@ void CrossPointWebServer::scanFiles(const char* path, const std::function