crosspoint-reader/src/BookManager.h
cottongin c2a966a6ea
refactor: Memory optimization and XTC format removal
Memory optimization:
- Add LOG_STACK_WATERMARK macro for task stack monitoring
- Add freeCoverBufferIfAllocated() and preloadCoverBuffer() for memory management
- Improve cover buffer reuse to reduce heap fragmentation
- Add grayscale buffer cleanup safety in GfxRenderer
- Make grayscale rendering conditional on successful buffer allocation
- Add detailed heap fragmentation logging with ESP-IDF API
- Add CSS parser memory usage estimation

XTC format removal:
- Remove entire lib/Xtc library (XTC parser and types)
- Remove XtcReaderActivity and XtcReaderChapterSelectionActivity
- Remove XTC file handling from HomeActivity, SleepActivity, ReaderActivity
- Remove .xtc/.xtch from supported extensions in BookManager
- Remove XTC cache prefix from Md5Utils
- Update web server and file browser to exclude XTC format
- Clear in-memory caches when disk cache is cleared
2026-01-27 20:35:32 -05:00

85 lines
2.9 KiB
C++

#pragma once
#include <string>
#include <vector>
/**
* BookManager - Handles book archiving, unarchiving, and deletion
*
* Archive: Moves book and its cache to /.archive/, preserving reading progress
* Unarchive: Restores book and cache to original location
* Delete: Permanently removes book and its cache
*/
class BookManager {
public:
static constexpr const char* ARCHIVE_DIR = "/.archive";
static constexpr const char* ARCHIVE_CACHE_DIR = "/.archive/.cache";
static constexpr const char* CROSSPOINT_DIR = "/.crosspoint";
/**
* Archive a book - moves file and cache to /.archive/
* @param bookPath Full path to the book file (e.g., "/Books/mybook.epub")
* @return true if successful
*/
static bool archiveBook(const std::string& bookPath);
/**
* Unarchive a book - restores file and cache to original location
* @param archivedFilename Filename in /.archive/ (e.g., "mybook.epub")
* @return true if successful
*/
static bool unarchiveBook(const std::string& archivedFilename);
/**
* Delete a book permanently - removes file and cache
* @param bookPath Full path to the book file
* @param isArchived If true, treats path as archived filename and also deletes .meta file
* @return true if successful
*/
static bool deleteBook(const std::string& bookPath, bool isArchived = false);
/**
* List archived books
* @return Vector of archived filenames (without path)
*/
static std::vector<std::string> listArchivedBooks();
/**
* Get the original path of an archived book
* @param archivedFilename Filename in /.archive/
* @return Original path, or empty string if not found
*/
static std::string getArchivedBookOriginalPath(const std::string& archivedFilename);
/**
* Get the full cache directory path for a book
* @param bookPath Full path to the book file
* @return Cache directory path (e.g., "/.crosspoint/epub_123456")
*/
static std::string getCacheDir(const std::string& bookPath);
private:
// Extract filename from a full path
static std::string getFilename(const std::string& path);
// Get the file extension (lowercase, including the dot)
static std::string getExtension(const std::string& path);
// Compute the hash used for cache directory naming
static size_t computePathHash(const std::string& path);
// Get cache directory prefix for a file type (epub_, txt_)
static std::string getCachePrefix(const std::string& path);
// Write the .meta file for an archived book
static bool writeMetaFile(const std::string& archivedPath, const std::string& originalPath);
// Read the original path from a .meta file
static std::string readMetaFile(const std::string& archivedPath);
// Create parent directories for a path if they don't exist
static bool ensureParentDirExists(const std::string& path);
// Check if a path is a supported book format
static bool isSupportedBookFormat(const std::string& path);
};