mirror of
https://github.com/daveallie/crosspoint-reader.git
synced 2026-02-05 15:17:37 +03:00
Remove excess data from page line serialization
This commit is contained in:
parent
85188afc8e
commit
e353deac05
@ -7,12 +7,12 @@ void PageLine::render(GfxRenderer& renderer, const int fontId, const int xOffset
|
|||||||
block->render(renderer, fontId, xPos + xOffset, yPos + yOffset);
|
block->render(renderer, fontId, xPos + xOffset, yPos + yOffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PageLine::serialize(File& file) {
|
bool PageLine::serialize(File &file) {
|
||||||
serialization::writePod(file, xPos);
|
serialization::writePod(file, xPos);
|
||||||
serialization::writePod(file, yPos);
|
serialization::writePod(file, yPos);
|
||||||
|
|
||||||
// serialize TextBlock pointed to by PageLine
|
// serialize TextBlock pointed to by PageLine
|
||||||
block->serialize(file);
|
return block->serialize(file);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<PageLine> PageLine::deserialize(File& file) {
|
std::unique_ptr<PageLine> PageLine::deserialize(File& file) {
|
||||||
@ -31,15 +31,19 @@ void Page::render(GfxRenderer& renderer, const int fontId, const int xOffset, co
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Page::serialize(File& file) const {
|
bool Page::serialize(File& file) const {
|
||||||
const uint32_t count = elements.size();
|
const uint32_t count = elements.size();
|
||||||
serialization::writePod(file, count);
|
serialization::writePod(file, count);
|
||||||
|
|
||||||
for (const auto& el : elements) {
|
for (const auto& el : elements) {
|
||||||
// Only PageLine exists currently
|
// Only PageLine exists currently
|
||||||
serialization::writePod(file, static_cast<uint8_t>(TAG_PageLine));
|
serialization::writePod(file, static_cast<uint8_t>(TAG_PageLine));
|
||||||
el->serialize(file);
|
if (!el->serialize(file)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<Page> Page::deserialize(File& file) {
|
std::unique_ptr<Page> Page::deserialize(File& file) {
|
||||||
|
|||||||
@ -18,7 +18,7 @@ class PageElement {
|
|||||||
explicit PageElement(const int16_t xPos, const int16_t yPos) : xPos(xPos), yPos(yPos) {}
|
explicit PageElement(const int16_t xPos, const int16_t yPos) : xPos(xPos), yPos(yPos) {}
|
||||||
virtual ~PageElement() = default;
|
virtual ~PageElement() = default;
|
||||||
virtual void render(GfxRenderer& renderer, int fontId, int xOffset, int yOffset) = 0;
|
virtual void render(GfxRenderer& renderer, int fontId, int xOffset, int yOffset) = 0;
|
||||||
virtual void serialize(File& file) = 0;
|
virtual bool serialize(File &file) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
// a line from a block element
|
// a line from a block element
|
||||||
@ -29,7 +29,7 @@ class PageLine final : public PageElement {
|
|||||||
PageLine(std::shared_ptr<TextBlock> block, const int16_t xPos, const int16_t yPos)
|
PageLine(std::shared_ptr<TextBlock> block, const int16_t xPos, const int16_t yPos)
|
||||||
: PageElement(xPos, yPos), block(std::move(block)) {}
|
: PageElement(xPos, yPos), block(std::move(block)) {}
|
||||||
void render(GfxRenderer& renderer, int fontId, int xOffset, int yOffset) override;
|
void render(GfxRenderer& renderer, int fontId, int xOffset, int yOffset) override;
|
||||||
void serialize(File& file) override;
|
bool serialize(File &file) override;
|
||||||
static std::unique_ptr<PageLine> deserialize(File& file);
|
static std::unique_ptr<PageLine> deserialize(File& file);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -38,6 +38,6 @@ class Page {
|
|||||||
// the list of block index and line numbers on this page
|
// the list of block index and line numbers on this page
|
||||||
std::vector<std::shared_ptr<PageElement>> elements;
|
std::vector<std::shared_ptr<PageElement>> elements;
|
||||||
void render(GfxRenderer& renderer, int fontId, int xOffset, int yOffset) const;
|
void render(GfxRenderer& renderer, int fontId, int xOffset, int yOffset) const;
|
||||||
void serialize(File& file) const;
|
bool serialize(File& file) const;
|
||||||
static std::unique_ptr<Page> deserialize(File& file);
|
static std::unique_ptr<Page> deserialize(File& file);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -18,8 +18,12 @@ size_t Section::onPageComplete(std::unique_ptr<Page> page) {
|
|||||||
Serial.printf("[%lu] [SCT] File not open for writing page %d\n", millis(), pageCount);
|
Serial.printf("[%lu] [SCT] File not open for writing page %d\n", millis(), pageCount);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto position = file.position();
|
const auto position = file.position();
|
||||||
page->serialize(file);
|
if (!page->serialize(file)) {
|
||||||
|
Serial.printf("[%lu] [SCT] Failed to serialize page %d\n", millis(), pageCount);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
Serial.printf("[%lu] [SCT] Page %d processed\n", millis(), pageCount);
|
Serial.printf("[%lu] [SCT] Page %d processed\n", millis(), pageCount);
|
||||||
|
|
||||||
pageCount++;
|
pageCount++;
|
||||||
@ -174,10 +178,23 @@ bool Section::createSectionFile(const int fontId, const float lineCompression, c
|
|||||||
}
|
}
|
||||||
|
|
||||||
const auto lutOffset = file.position();
|
const auto lutOffset = file.position();
|
||||||
|
bool hasFailedLutRecords = false;
|
||||||
// Write LUT
|
// Write LUT
|
||||||
for (const auto& pos : lut) {
|
for (const auto& pos : lut) {
|
||||||
|
if (pos == 0) {
|
||||||
|
hasFailedLutRecords = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
serialization::writePod(file, pos);
|
serialization::writePod(file, pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (hasFailedLutRecords) {
|
||||||
|
Serial.printf("[%lu] [SCT] Failed to write LUT due to invalid page positions\n", millis());
|
||||||
|
file.close();
|
||||||
|
SD.remove(filePath.c_str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// Go back and write LUT offset
|
// Go back and write LUT offset
|
||||||
file.seek(HEADER_SIZE - sizeof(size_t) - sizeof(pageCount));
|
file.seek(HEADER_SIZE - sizeof(size_t) - sizeof(pageCount));
|
||||||
serialization::writePod(file, pageCount);
|
serialization::writePod(file, pageCount);
|
||||||
|
|||||||
@ -24,34 +24,33 @@ void TextBlock::render(const GfxRenderer& renderer, const int fontId, const int
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextBlock::serialize(File& file) const {
|
bool TextBlock::serialize(File &file) const {
|
||||||
// words
|
if (words.size() != wordXpos.size() || words.size() != wordStyles.size()) {
|
||||||
const uint32_t wc = words.size();
|
Serial.printf("[%lu] [TXB] Serialization failed: size mismatch (words=%u, xpos=%u, styles=%u)\n", millis(),
|
||||||
serialization::writePod(file, wc);
|
words.size(), wordXpos.size(), wordStyles.size());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Word data
|
||||||
|
serialization::writePod(file, static_cast<uint32_t>(words.size()));
|
||||||
for (const auto& w : words) serialization::writeString(file, w);
|
for (const auto& w : words) serialization::writeString(file, w);
|
||||||
|
|
||||||
// wordXpos
|
|
||||||
const uint32_t xc = wordXpos.size();
|
|
||||||
serialization::writePod(file, xc);
|
|
||||||
for (auto x : wordXpos) serialization::writePod(file, x);
|
for (auto x : wordXpos) serialization::writePod(file, x);
|
||||||
|
|
||||||
// wordStyles
|
|
||||||
const uint32_t sc = wordStyles.size();
|
|
||||||
serialization::writePod(file, sc);
|
|
||||||
for (auto s : wordStyles) serialization::writePod(file, s);
|
for (auto s : wordStyles) serialization::writePod(file, s);
|
||||||
|
|
||||||
// style
|
// Block style
|
||||||
serialization::writePod(file, style);
|
serialization::writePod(file, style);
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<TextBlock> TextBlock::deserialize(File& file) {
|
std::unique_ptr<TextBlock> TextBlock::deserialize(File& file) {
|
||||||
uint32_t wc, xc, sc;
|
uint32_t wc;
|
||||||
std::list<std::string> words;
|
std::list<std::string> words;
|
||||||
std::list<uint16_t> wordXpos;
|
std::list<uint16_t> wordXpos;
|
||||||
std::list<EpdFontStyle> wordStyles;
|
std::list<EpdFontStyle> wordStyles;
|
||||||
BLOCK_STYLE style;
|
BLOCK_STYLE style;
|
||||||
|
|
||||||
// words
|
// Word count
|
||||||
serialization::readPod(file, wc);
|
serialization::readPod(file, wc);
|
||||||
|
|
||||||
// Sanity check: prevent allocation of unreasonably large lists (max 10000 words per block)
|
// Sanity check: prevent allocation of unreasonably large lists (max 10000 words per block)
|
||||||
@ -60,27 +59,15 @@ std::unique_ptr<TextBlock> TextBlock::deserialize(File& file) {
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Word data
|
||||||
words.resize(wc);
|
words.resize(wc);
|
||||||
|
wordXpos.resize(wc);
|
||||||
|
wordStyles.resize(wc);
|
||||||
for (auto& w : words) serialization::readString(file, w);
|
for (auto& w : words) serialization::readString(file, w);
|
||||||
|
|
||||||
// wordXpos
|
|
||||||
serialization::readPod(file, xc);
|
|
||||||
wordXpos.resize(xc);
|
|
||||||
for (auto& x : wordXpos) serialization::readPod(file, x);
|
for (auto& x : wordXpos) serialization::readPod(file, x);
|
||||||
|
|
||||||
// wordStyles
|
|
||||||
serialization::readPod(file, sc);
|
|
||||||
wordStyles.resize(sc);
|
|
||||||
for (auto& s : wordStyles) serialization::readPod(file, s);
|
for (auto& s : wordStyles) serialization::readPod(file, s);
|
||||||
|
|
||||||
// Validate data consistency: all three lists must have the same size
|
// Block style
|
||||||
if (wc != xc || wc != sc) {
|
|
||||||
Serial.printf("[%lu] [TXB] Deserialization failed: size mismatch (words=%u, xpos=%u, styles=%u)\n", millis(), wc,
|
|
||||||
xc, sc);
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
// style
|
|
||||||
serialization::readPod(file, style);
|
serialization::readPod(file, style);
|
||||||
|
|
||||||
return std::unique_ptr<TextBlock>(new TextBlock(std::move(words), std::move(wordXpos), std::move(wordStyles), style));
|
return std::unique_ptr<TextBlock>(new TextBlock(std::move(words), std::move(wordXpos), std::move(wordStyles), style));
|
||||||
|
|||||||
@ -36,6 +36,6 @@ class TextBlock final : public Block {
|
|||||||
// given a renderer works out where to break the words into lines
|
// given a renderer works out where to break the words into lines
|
||||||
void render(const GfxRenderer& renderer, int fontId, int x, int y) const;
|
void render(const GfxRenderer& renderer, int fontId, int x, int y) const;
|
||||||
BlockType getType() override { return TEXT_BLOCK; }
|
BlockType getType() override { return TEXT_BLOCK; }
|
||||||
void serialize(File& file) const;
|
bool serialize(File &file) const;
|
||||||
static std::unique_ptr<TextBlock> deserialize(File& file);
|
static std::unique_ptr<TextBlock> deserialize(File& file);
|
||||||
};
|
};
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user