perf: stream NCX/NAV TOC into parser, drop temp-file round-trip (#2440)
Co-authored-by: Erica Jensen <erica@mailershaven.com>
This commit is contained in:
co-authored by
Erica Jensen
parent
5fbc657aeb
commit
b596f21e61
+14
-59
@@ -153,18 +153,11 @@ bool Epub::parseTocNcxFile() const {
|
|||||||
|
|
||||||
LOG_DBG("EBP", "Parsing toc ncx file: %s", tocNcxItem.c_str());
|
LOG_DBG("EBP", "Parsing toc ncx file: %s", tocNcxItem.c_str());
|
||||||
|
|
||||||
const auto tmpNcxPath = getCachePath() + "/toc.ncx";
|
size_t ncxSize;
|
||||||
HalFile tempNcxFile;
|
if (!getItemSize(tocNcxItem, &ncxSize)) {
|
||||||
if (!Storage.openFileForWrite("EBP", tmpNcxPath, tempNcxFile)) {
|
LOG_ERR("EBP", "Could not get size of toc ncx file");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
readItemContentsToStream(tocNcxItem, tempNcxFile, 1024);
|
|
||||||
// Explicitly close() file before reopening for reading
|
|
||||||
tempNcxFile.close();
|
|
||||||
if (!Storage.openFileForRead("EBP", tmpNcxPath, tempNcxFile)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
const auto ncxSize = tempNcxFile.size();
|
|
||||||
|
|
||||||
TocNcxParser ncxParser(contentBasePath, ncxSize, bookMetadataCache.get());
|
TocNcxParser ncxParser(contentBasePath, ncxSize, bookMetadataCache.get());
|
||||||
|
|
||||||
@@ -173,29 +166,13 @@ bool Epub::parseTocNcxFile() const {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto ncxBuffer = static_cast<uint8_t*>(malloc(1024));
|
// Stream the decompressed NCX straight into the parser instead of round-tripping
|
||||||
if (!ncxBuffer) {
|
// through a temp file on the SD card (decompress -> write -> reopen -> reread -> delete).
|
||||||
LOG_ERR("EBP", "Could not allocate memory for toc ncx parser");
|
if (!readItemContentsToStream(tocNcxItem, ncxParser, 1024)) {
|
||||||
|
LOG_ERR("EBP", "Could not read toc ncx file");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (tempNcxFile.available()) {
|
|
||||||
const auto readSize = tempNcxFile.read(ncxBuffer, 1024);
|
|
||||||
if (readSize == 0) break;
|
|
||||||
const auto processedSize = ncxParser.write(ncxBuffer, readSize);
|
|
||||||
|
|
||||||
if (processedSize != readSize) {
|
|
||||||
LOG_ERR("EBP", "Could not process all toc ncx data");
|
|
||||||
free(ncxBuffer);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
free(ncxBuffer);
|
|
||||||
// Explicitly close() file before calling Storage.remove()
|
|
||||||
tempNcxFile.close();
|
|
||||||
Storage.remove(tmpNcxPath.c_str());
|
|
||||||
|
|
||||||
LOG_DBG("EBP", "Parsed TOC items");
|
LOG_DBG("EBP", "Parsed TOC items");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -209,18 +186,11 @@ bool Epub::parseTocNavFile() const {
|
|||||||
|
|
||||||
LOG_DBG("EBP", "Parsing toc nav file: %s", tocNavItem.c_str());
|
LOG_DBG("EBP", "Parsing toc nav file: %s", tocNavItem.c_str());
|
||||||
|
|
||||||
const auto tmpNavPath = getCachePath() + "/toc.nav";
|
size_t navSize;
|
||||||
HalFile tempNavFile;
|
if (!getItemSize(tocNavItem, &navSize)) {
|
||||||
if (!Storage.openFileForWrite("EBP", tmpNavPath, tempNavFile)) {
|
LOG_ERR("EBP", "Could not get size of toc nav file");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
readItemContentsToStream(tocNavItem, tempNavFile, 1024);
|
|
||||||
// Explicitly close() file before reopening for reading
|
|
||||||
tempNavFile.close();
|
|
||||||
if (!Storage.openFileForRead("EBP", tmpNavPath, tempNavFile)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
const auto navSize = tempNavFile.size();
|
|
||||||
|
|
||||||
// Note: We can't use `contentBasePath` here as the nav file may be in a different folder to the content.opf
|
// Note: We can't use `contentBasePath` here as the nav file may be in a different folder to the content.opf
|
||||||
// and the HTMLX nav file will have hrefs relative to itself
|
// and the HTMLX nav file will have hrefs relative to itself
|
||||||
@@ -232,28 +202,13 @@ bool Epub::parseTocNavFile() const {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto navBuffer = static_cast<uint8_t*>(malloc(1024));
|
// Stream the decompressed nav document straight into the parser instead of round-tripping
|
||||||
if (!navBuffer) {
|
// through a temp file on the SD card (decompress -> write -> reopen -> reread -> delete).
|
||||||
LOG_ERR("EBP", "Could not allocate memory for toc nav parser");
|
if (!readItemContentsToStream(tocNavItem, navParser, 1024)) {
|
||||||
|
LOG_ERR("EBP", "Could not read toc nav file");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (tempNavFile.available()) {
|
|
||||||
const auto readSize = tempNavFile.read(navBuffer, 1024);
|
|
||||||
const auto processedSize = navParser.write(navBuffer, readSize);
|
|
||||||
|
|
||||||
if (processedSize != readSize) {
|
|
||||||
LOG_ERR("EBP", "Could not process all toc nav data");
|
|
||||||
free(navBuffer);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
free(navBuffer);
|
|
||||||
// Explicitly close() file before calling Storage.remove()
|
|
||||||
tempNavFile.close();
|
|
||||||
Storage.remove(tmpNavPath.c_str());
|
|
||||||
|
|
||||||
LOG_DBG("EBP", "Parsed TOC nav items");
|
LOG_DBG("EBP", "Parsed TOC nav items");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user