Reader.h 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. /* vim: set expandtab ts=4 sw=4: */
  2. /*
  3. * You may redistribute this program and/or modify it under the terms of
  4. * the GNU General Public License as published by the Free Software Foundation,
  5. * either version 3 of the License, or (at your option) any later version.
  6. *
  7. * This program is distributed in the hope that it will be useful,
  8. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. * GNU General Public License for more details.
  11. *
  12. * You should have received a copy of the GNU General Public License
  13. * along with this program. If not, see <https://www.gnu.org/licenses/>.
  14. */
  15. #ifndef Reader_H
  16. #define Reader_H
  17. #include <stdint.h>
  18. /**
  19. * Reader interface which reads data from a source and fails safe rather than overreading.
  20. */
  21. struct Reader {
  22. /**
  23. * Read some content from a buffer or other source.
  24. *
  25. * @param thisReader the Reader which is being called.
  26. * @param readInto a pointer to a memory location which will have content written to it.
  27. * @param length the number of bytes to read. If this number is 0 then the next
  28. * byte will be returned without incrementing the pointer.
  29. * @return 0 if read went well, -1 if the content ran out and no more could be read.
  30. */
  31. int (* const read)(struct Reader* thisReader, void* readInto, unsigned long length);
  32. /**
  33. * Advance the pointer a number of bytes without reading any.
  34. * This function will happily skip off the end of the source and the next read will fail.
  35. *
  36. * @param thisReader the Reader which is being called.
  37. * @param byteCount how far to advance the pointer.
  38. */
  39. void (* const skip)(struct Reader* thisReader, unsigned long byteCount);
  40. /** The total number of bytes which have been read OR SKIPPED by this reader. */
  41. uint64_t bytesRead;
  42. };
  43. #define Reader_readGeneric(bytes) \
  44. static inline uint##bytes##_t Reader_read##bytes (struct Reader* reader) \
  45. { \
  46. uint##bytes##_t num; \
  47. reader->read(reader, &num, bytes/8); \
  48. return num; \
  49. }
  50. Reader_readGeneric(8)
  51. Reader_readGeneric(16)
  52. Reader_readGeneric(32)
  53. Reader_readGeneric(64)
  54. #define Reader_read(reader, readInto, bytes) \
  55. (reader)->read((reader), (readInto), (bytes))
  56. #define Reader_skip(reader, bytes) \
  57. (reader)->skip((reader), (bytes))
  58. #define Reader_bytesRead(reader) \
  59. ((reader)->bytesRead + 0)
  60. #endif