Reader.h 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. /*
  2. * Copyright (c) 2021, Matthew Olsson <mattco@serenityos.org>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #pragma once
  7. #include <AK/Debug.h>
  8. #include <AK/Function.h>
  9. #include <AK/ScopeGuard.h>
  10. namespace PDF {
  11. class Reader {
  12. public:
  13. explicit Reader(ReadonlyBytes const& bytes)
  14. : m_bytes(bytes)
  15. {
  16. }
  17. ALWAYS_INLINE ReadonlyBytes const& bytes() const { return m_bytes; }
  18. ALWAYS_INLINE size_t offset() const { return m_offset; }
  19. bool done() const
  20. {
  21. if (m_forwards)
  22. return offset() >= bytes().size();
  23. return m_offset < 0;
  24. }
  25. size_t remaining() const
  26. {
  27. if (done())
  28. return 0;
  29. if (m_forwards)
  30. return bytes().size() - offset() - 1;
  31. return offset() + 1;
  32. }
  33. void move_by(size_t count)
  34. {
  35. if (m_forwards) {
  36. m_offset += static_cast<ssize_t>(count);
  37. } else {
  38. m_offset -= static_cast<ssize_t>(count);
  39. }
  40. }
  41. template<typename T = char>
  42. T read()
  43. {
  44. T value = reinterpret_cast<const T*>(m_bytes.offset(m_offset))[0];
  45. move_by(sizeof(T));
  46. return value;
  47. }
  48. char peek(size_t shift = 0) const
  49. {
  50. auto offset = m_offset + shift * (m_forwards ? 1 : -1);
  51. return static_cast<char>(m_bytes.at(offset));
  52. }
  53. template<typename... T>
  54. bool matches_any(T... elements) const
  55. {
  56. if (done())
  57. return false;
  58. auto ch = peek();
  59. return ((ch == elements) || ...);
  60. }
  61. bool matches(char ch) const
  62. {
  63. return !done() && peek() == ch;
  64. }
  65. bool matches(const char* chars) const
  66. {
  67. String string(chars);
  68. if (remaining() < string.length())
  69. return false;
  70. if (!m_forwards)
  71. string = string.reverse();
  72. for (size_t i = 0; i < string.length(); i++) {
  73. if (peek(i) != string[i])
  74. return false;
  75. }
  76. return true;
  77. }
  78. template<typename T = char>
  79. void move_to(size_t offset)
  80. {
  81. VERIFY(offset < m_bytes.size());
  82. m_offset = static_cast<ssize_t>(offset);
  83. }
  84. void move_until(char ch)
  85. {
  86. while (!done() && peek() != ch)
  87. move_by(1);
  88. }
  89. void move_until(Function<bool(char)> predicate)
  90. {
  91. while (!done() && !predicate(peek()))
  92. move_by(1);
  93. }
  94. ALWAYS_INLINE void move_while(Function<bool(char)> predicate)
  95. {
  96. move_until([&predicate](char t) { return !predicate(t); });
  97. }
  98. ALWAYS_INLINE void set_reading_forwards() { m_forwards = true; }
  99. ALWAYS_INLINE void set_reading_backwards() { m_forwards = false; }
  100. ALWAYS_INLINE void save() { m_saved_offsets.append(m_offset); }
  101. ALWAYS_INLINE void load() { m_offset = m_saved_offsets.take_last(); }
  102. ALWAYS_INLINE void discard() { m_saved_offsets.take_last(); }
  103. #ifdef PDF_DEBUG
  104. void dump_state() const
  105. {
  106. dbgln("Reader State (offset={} size={})", offset(), bytes().size());
  107. size_t from = max(0, static_cast<int>(offset()) - 10);
  108. size_t to = min(bytes().size() - 1, offset() + 10);
  109. for (auto i = from; i <= to; i++) {
  110. char value = static_cast<char>(bytes().at(i));
  111. auto line = String::formatted(" {}: '{}' (value={:3d}) ", i, value, static_cast<u8>(value));
  112. if (i == offset()) {
  113. dbgln("{} <<< current location, forwards={}", line, m_forwards);
  114. } else {
  115. dbgln("{}", line);
  116. }
  117. }
  118. dbgln();
  119. }
  120. #endif
  121. private:
  122. ReadonlyBytes m_bytes;
  123. ssize_t m_offset { 0 };
  124. Vector<ssize_t> m_saved_offsets;
  125. bool m_forwards { true };
  126. };
  127. }