Compare commits

..

No commits in common. '51f60eb817d679773282b202a6632300e3ac6370' and '305c039d8392b135deb085516682d6527505e505' have entirely different histories.

  1. 2
      Specification.rst
  2. 120
      cpp/src/monoformat_parsehelpers.hpp
  3. 178
      cpp/src/monoformat_structured.cpp

@ -379,7 +379,7 @@ Horizontally Scrolling Text
+------------------------+------------------------+------------------------+------------------------+
8 | Height | Flags | Scroll Speed |
+------------------------+------------------------+------------------------+------------------------+
12 | Font Index | Text Length |
12 | Font Index | Text ... |
+------------------------+------------------------+------------------------+------------------------+
... | ... Text | Padding (if required) |
+------------------------+------------------------+------------------------+------------------------+

@ -5,7 +5,6 @@
#include <cstddef>
#include <expected>
#include <span>
#include <tuple> // for std::ignore
namespace monoformat {
@ -229,125 +228,6 @@ inline std::pair<std::uint8_t, bool> overflowingShl(std::uint8_t value, std::uin
return {value << bits, overflow};
}
inline std::size_t writeU8LE(std::span<std::byte>& target, std::size_t pos, std::uint8_t value) {
if (pos < target.size()) {
target[pos] = static_cast<std::byte>(value);
}
return pos + 1;
}
inline std::size_t writeU8BE(std::span<std::byte>& target, std::size_t pos, std::uint8_t value) {
if (pos < target.size()) {
target[pos] = static_cast<std::byte>(value);
}
return pos + 1;
}
inline std::size_t writeU16LE(std::span<std::byte>& target, std::size_t pos, std::uint16_t value) {
if ((pos + 1) < target.size()) {
target[pos + 0] = static_cast<std::byte>((value >> 0u) & 0xffu);
target[pos + 1] = static_cast<std::byte>((value >> 8u) & 0xffu);
}
return pos + 2;
}
inline std::size_t writeU16BE(std::span<std::byte>& target, std::size_t pos, std::uint16_t value) {
if ((pos + 1) < target.size()) {
target[pos + 0] = static_cast<std::byte>((value >> 8u) & 0xffu);
target[pos + 1] = static_cast<std::byte>((value >> 0u) & 0xffu);
}
return pos + 2;
}
inline std::size_t writeU24LE(std::span<std::byte>& target, std::size_t pos, std::uint32_t value) {
if ((pos + 2) < target.size()) {
target[pos + 0] = static_cast<std::byte>((value >> 0u) & 0xffu);
target[pos + 1] = static_cast<std::byte>((value >> 8u) & 0xffu);
target[pos + 2] = static_cast<std::byte>((value >> 16u) & 0xffu);
}
return pos + 3;
}
inline std::size_t writeU24BE(std::span<std::byte>& target, std::size_t pos, std::uint32_t value) {
if ((pos + 2) < target.size()) {
target[pos + 0] = static_cast<std::byte>((value >> 16u) & 0xffu);
target[pos + 1] = static_cast<std::byte>((value >> 8u) & 0xffu);
target[pos + 2] = static_cast<std::byte>((value >> 0u) & 0xffu);
}
return pos + 3;
}
inline std::size_t writeU32LE(std::span<std::byte>& target, std::size_t pos, std::uint32_t value) {
if ((pos + 3) < target.size()) {
target[pos + 0] = static_cast<std::byte>((value >> 0u) & 0xffu);
target[pos + 1] = static_cast<std::byte>((value >> 8u) & 0xffu);
target[pos + 2] = static_cast<std::byte>((value >> 16u) & 0xffu);
target[pos + 3] = static_cast<std::byte>((value >> 24u) & 0xffu);
}
return pos + 4;
}
inline std::size_t writeU32BE(std::span<std::byte>& target, std::size_t pos, std::uint32_t value) {
if ((pos + 3) < target.size()) {
target[pos + 0] = static_cast<std::byte>((value >> 24u) & 0xffu);
target[pos + 1] = static_cast<std::byte>((value >> 16u) & 0xffu);
target[pos + 2] = static_cast<std::byte>((value >> 8u) & 0xffu);
target[pos + 3] = static_cast<std::byte>((value >> 0u) & 0xffu);
}
return pos + 4;
}
inline std::size_t writeU64LE(std::span<std::byte>& target, std::size_t pos, std::uint64_t value) {
if ((pos + 7) < target.size()) {
target[pos + 0] = static_cast<std::byte>((value >> 0u) & 0xffu);
target[pos + 1] = static_cast<std::byte>((value >> 8u) & 0xffu);
target[pos + 2] = static_cast<std::byte>((value >> 16u) & 0xffu);
target[pos + 3] = static_cast<std::byte>((value >> 24u) & 0xffu);
target[pos + 4] = static_cast<std::byte>((value >> 32u) & 0xffu);
target[pos + 5] = static_cast<std::byte>((value >> 40u) & 0xffu);
target[pos + 6] = static_cast<std::byte>((value >> 48u) & 0xffu);
target[pos + 7] = static_cast<std::byte>((value >> 56u) & 0xffu);
}
return pos + 8;
}
inline std::size_t writeU64BE(std::span<std::byte>& target, std::size_t pos, std::uint64_t value) {
if ((pos + 3) < target.size()) {
target[pos + 0] = static_cast<std::byte>((value >> 56u) & 0xffu);
target[pos + 1] = static_cast<std::byte>((value >> 48u) & 0xffu);
target[pos + 2] = static_cast<std::byte>((value >> 40u) & 0xffu);
target[pos + 3] = static_cast<std::byte>((value >> 32u) & 0xffu);
target[pos + 4] = static_cast<std::byte>((value >> 24u) & 0xffu);
target[pos + 5] = static_cast<std::byte>((value >> 16u) & 0xffu);
target[pos + 6] = static_cast<std::byte>((value >> 8u) & 0xffu);
target[pos + 7] = static_cast<std::byte>((value >> 0u) & 0xffu);
}
return pos + 8;
}
inline std::size_t writeBuffer(std::span<std::byte>& target, std::size_t pos, std::span<std::byte const> value) {
if ((pos + value.size()) > target.size()) {
if (pos < value.size()) {
std::size_t const n = value.size() - pos;
std::copy(value.begin(), value.begin() + n, target.begin() + pos);
}
} else {
std::copy(value.begin(), value.end(), target.begin() + pos);
}
return pos + value.size();
}
inline std::size_t alignNextWrite(std::span<std::byte>& target, std::size_t pos, std::size_t alignment) {
std::ignore = target;
if (alignment <= 1) {
return pos;
}
if (pos % alignment == 0) {
return pos;
}
return ((pos + alignment - 1) / alignment) * alignment;
}
} // namespace monoformat
#endif // MONOFORMAT_PARSEHELPERS_HPP

@ -122,15 +122,7 @@ ElementType ImageElement::elementType() const {
}
std::size_t ImageElement::serializeTo(std::span<std::byte> target) const {
std::size_t pos = 0;
pos = writeU16LE(target, pos, static_cast<std::uint16_t>(ElementType::Image));
pos = writeU16LE(target, pos, m_x);
pos = writeU16LE(target, pos, m_y);
pos = writeU16LE(target, pos, m_width);
pos = writeU16LE(target, pos, m_height);
pos = writeU16LE(target, pos, 0);
pos = writeBuffer(target, pos, m_buffer);
return alignNextWrite(target, pos, 4);
// FIXME: serialize
}
void ImageElement::drawTo(OneBitBufferInterface* imageBuffer, std::size_t animationTick, std::int64_t currentTimestamp) {
@ -217,17 +209,7 @@ ElementType AnimationElement::elementType() const {
}
std::size_t AnimationElement::serializeTo(std::span<std::byte> target) const {
std::size_t pos = 0;
pos = writeU16LE(target, pos, static_cast<std::uint16_t>(ElementType::Animation));
pos = writeU16LE(target, pos, m_x);
pos = writeU16LE(target, pos, m_y);
pos = writeU16LE(target, pos, m_width);
pos = writeU16LE(target, pos, m_height);
pos = writeU16LE(target, pos, m_numberOfFrames);
pos = writeU16LE(target, pos, m_updateInterval);
pos = writeU16LE(target, pos, 0);
pos = writeBuffer(target, pos, m_buffer);
return alignNextWrite(target, pos, 4);
// FIXME: implement this
}
void AnimationElement::drawTo(OneBitBufferInterface* imageBuffer, std::size_t animationTick, std::int64_t currentTimestamp) {
@ -303,18 +285,7 @@ ElementType HScrollImageElement::elementType() const {
}
std::size_t HScrollImageElement::serializeTo(std::span<std::byte> target) const {
std::size_t pos = 0;
pos = writeU16LE(target, pos, static_cast<std::uint16_t>(ElementType::HScrollImage));
pos = writeU16LE(target, pos, m_x);
pos = writeU16LE(target, pos, m_y);
pos = writeU16LE(target, pos, m_width);
pos = writeU16LE(target, pos, m_height);
pos = writeU16LE(target, pos, m_contentWidth);
pos = writeU8LE(target, pos, m_flags);
pos = writeU8LE(target, pos, m_scrollSpeed);
pos = writeU16LE(target, pos, 0);
pos = writeBuffer(target, pos, m_buffer);
return alignNextWrite(target, pos, 4);
// FIXME Serialize
}
void HScrollImageElement::drawTo(OneBitBufferInterface* imageBuffer, std::size_t animationTick, std::int64_t currentTimestamp) {
@ -390,18 +361,7 @@ ElementType VScrollImageElement::elementType() const {
}
std::size_t VScrollImageElement::serializeTo(std::span<std::byte> target) const {
std::size_t pos = 0;
pos = writeU16LE(target, pos, static_cast<std::uint16_t>(ElementType::VScrollImage));
pos = writeU16LE(target, pos, m_x);
pos = writeU16LE(target, pos, m_y);
pos = writeU16LE(target, pos, m_width);
pos = writeU16LE(target, pos, m_height);
pos = writeU16LE(target, pos, m_contentHeight);
pos = writeU8LE(target, pos, m_flags);
pos = writeU8LE(target, pos, m_scrollSpeed);
pos = writeU16LE(target, pos, 0);
pos = writeBuffer(target, pos, m_buffer);
return alignNextWrite(target, pos, 4);
// FIXME Serialize
}
void VScrollImageElement::drawTo(OneBitBufferInterface* imageBuffer, std::size_t animationTick, std::int64_t currentTimestamp) {
@ -455,15 +415,7 @@ ElementType LineElement::elementType() const {
}
std::size_t LineElement::serializeTo(std::span<std::byte> target) const {
std::size_t pos = 0;
pos = writeU16LE(target, pos, static_cast<std::uint16_t>(ElementType::Line));
pos = writeU16LE(target, pos, m_originX);
pos = writeU16LE(target, pos, m_originY);
pos = writeU16LE(target, pos, m_targetX);
pos = writeU16LE(target, pos, m_targetY);
pos = writeU8LE(target, pos, static_cast<std::uint8_t>(m_lineStyle));
pos = writeU8LE(target, pos, m_flags);
return alignNextWrite(target, pos, 4);
// FIXME: serialize
}
void LineElement::drawTo(OneBitBufferInterface* imageBuffer, std::size_t animationTick, std::int64_t currentTimestamp) {
@ -516,16 +468,7 @@ ElementType ClippedTextElement::elementType() const {
}
std::size_t ClippedTextElement::serializeTo(std::span<std::byte> target) const {
std::size_t pos = 0;
pos = writeU16LE(target, pos, static_cast<std::uint16_t>(ElementType::HScrollImage));
pos = writeU16LE(target, pos, m_x);
pos = writeU16LE(target, pos, m_y);
pos = writeU16LE(target, pos, m_width);
pos = writeU16LE(target, pos, m_height);
pos = writeU16LE(target, pos, m_fontIndex);
pos = writeU16LE(target, pos, m_text.size());
pos = writeBuffer(target, pos, std::as_bytes(std::span{m_text}));
return alignNextWrite(target, pos, 4);
// FIXME: serialize
}
void ClippedTextElement::drawTo(OneBitBufferInterface* imageBuffer, std::size_t animationTick, std::int64_t currentTimestamp) {
@ -588,18 +531,7 @@ ElementType HScrollTextElement::elementType() const {
}
std::size_t HScrollTextElement::serializeTo(std::span<std::byte> target) const {
std::size_t pos = 0;
pos = writeU16LE(target, pos, static_cast<std::uint16_t>(ElementType::HScrollImage));
pos = writeU16LE(target, pos, m_x);
pos = writeU16LE(target, pos, m_y);
pos = writeU16LE(target, pos, m_width);
pos = writeU16LE(target, pos, m_height);
pos = writeU8LE(target, pos, m_flags);
pos = writeU8LE(target, pos, m_scrollSpeed);
pos = writeU16LE(target, pos, m_fontIndex);
pos = writeU16LE(target, pos, m_text.size());
pos = writeBuffer(target, pos, std::as_bytes(std::span{m_text}));
return alignNextWrite(target, pos, 4);
// FIXME serialize
}
void HScrollTextElement::drawTo(OneBitBufferInterface* imageBuffer, std::size_t animationTick, std::int64_t currentTimestamp) {
@ -657,16 +589,7 @@ ElementType CurrentTimeElement::elementType() const {
}
std::size_t CurrentTimeElement::serializeTo(std::span<std::byte> target) const {
std::size_t pos = 0;
pos = writeU16LE(target, pos, static_cast<std::uint16_t>(ElementType::HScrollImage));
pos = writeU16LE(target, pos, m_x);
pos = writeU16LE(target, pos, m_y);
pos = writeU16LE(target, pos, m_width);
pos = writeU16LE(target, pos, m_height);
pos = writeU16LE(target, pos, m_fontIndex);
pos = writeU16LE(target, pos, m_utcOffset);
pos = writeU16LE(target, pos, m_flags);
return alignNextWrite(target, pos, 4);
// FIXME: serialize
}
void CurrentTimeElement::drawTo(OneBitBufferInterface* imageBuffer, std::size_t animationTick, std::int64_t currentTimestamp) {
@ -751,32 +674,7 @@ SectionType AlwaysDrawnSection::sectionType() const {
}
std::size_t AlwaysDrawnSection::serializeTo(std::span<std::byte> target) const {
std::size_t pos = 0;
pos = writeU8LE(target, pos, static_cast<std::uint16_t>(SectionType::AlwaysDrawn));
// Will be replaced later
pos = writeU24LE(target, pos, 0);
std::uint16_t flags = 0;
if (m_drawOnFront) {
flags |= std::uint16_t{1};
}
if (m_drawOnBack) {
flags |= std::uint16_t{2};
}
if (m_clearBeforeDrawing) {
flags |= std::uint16_t{4};
}
pos = writeU16LE(target, pos, flags);
pos = writeU16LE(target, pos, m_elements.size());
for (auto const& element : m_elements) {
if (pos < target.size()) {
pos += element->serializeTo(target.subspan(pos));
} else {
pos += element->serializeTo({});
}
}
pos = alignNextWrite(target, pos, 4);
std::ignore = writeU24LE(target, 1, pos);
return pos;
// FIXME: serialize
}
std::expected<std::unique_ptr<AlwaysDrawnSection>, ParseError> AlwaysDrawnSection::parse(std::span<std::byte const>& buffer) {
@ -873,34 +771,7 @@ SectionType TimeBasedDrawnSection::sectionType() const {
}
std::size_t TimeBasedDrawnSection::serializeTo(std::span<std::byte> target) const {
std::size_t pos = 0;
pos = writeU8LE(target, pos, static_cast<std::uint16_t>(SectionType::AlwaysDrawn));
// Will be replaced later
pos = writeU24LE(target, pos, 0);
std::uint16_t flags = 0;
if (m_drawOnFront) {
flags |= std::uint16_t{1};
}
if (m_drawOnBack) {
flags |= std::uint16_t{2};
}
if (m_clearBeforeDrawing) {
flags |= std::uint16_t{4};
}
pos = writeU16LE(target, pos, flags);
pos = writeU16LE(target, pos, m_elements.size());
pos = writeU64LE(target, pos, std::bit_cast<std::uint64_t>(m_startTimestamp));
pos = writeU64LE(target, pos, std::bit_cast<std::uint64_t>(m_endTimestamp));
for (auto const& element : m_elements) {
if (pos < target.size()) {
pos += element->serializeTo(target.subspan(pos));
} else {
pos += element->serializeTo({});
}
}
pos = alignNextWrite(target, pos, 4);
std::ignore = writeU24LE(target, 1, pos);
return pos;
// FIXME: serialize
}
std::expected<std::unique_ptr<TimeBasedDrawnSection>, ParseError> TimeBasedDrawnSection::parse(std::span<std::byte const>& buffer) {
@ -924,16 +795,7 @@ SectionType CustomFontSection::sectionType() const {
}
std::size_t CustomFontSection::serializeTo(std::span<std::byte> target) const {
std::size_t pos = 0;
pos = writeU8LE(target, pos, static_cast<std::uint16_t>(SectionType::AlwaysDrawn));
// Will be replaced later
pos = writeU24LE(target, pos, 0);
pos = writeU24LE(target, pos, m_fontData.size());
pos = writeU8LE(target, pos, 0);
pos = writeBuffer(target, pos, m_fontData);
pos = alignNextWrite(target, pos, 4);
std::ignore = writeU24LE(target, 1, pos);
return pos;
// FIXME: serailize
}
std::expected<std::unique_ptr<CustomFontSection>, ParseError> CustomFontSection::parse(std::span<std::byte const>& buffer) {
@ -941,23 +803,7 @@ std::expected<std::unique_ptr<CustomFontSection>, ParseError> CustomFontSection:
}
std::size_t serializeFile(std::span<std::byte>& buffer, File const& file) {
std::size_t pos = 0;
pos = writeU8LE(buffer, pos, 0xAF);
pos = writeU8LE(buffer, pos, 0x7E);
pos = writeU8LE(buffer, pos, 0x2B);
pos = writeU8LE(buffer, pos, 0x64);
pos = writeU32LE(buffer, pos, 1);
pos = writeU16LE(buffer, pos, file.sections.size());
pos = writeU16LE(buffer, pos, 0);
pos = alignNextWrite(buffer, pos, 4);
for (auto const& section : file.sections) {
if (pos < buffer.size()) {
pos += section->serializeTo(buffer.subspan(pos));
} else {
pos += section->serializeTo({});
}
}
return pos;
// FIXME: serialize
}
std::expected<File, ParseError> parseFile(std::span<std::byte const> data) {

Loading…
Cancel
Save