/* vim: set expandtab ts=4 sw=4: */
/*
* You may redistribute this program and/or modify it under the terms of
* the GNU General Public License as published by the Free Software Foundation,
* either version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
#ifndef Reader_H
#define Reader_H
#include
/**
* Reader interface which reads data from a source and fails safe rather than overreading.
*/
struct Reader {
/**
* Read some content from a buffer or other source.
*
* @param thisReader the Reader which is being called.
* @param readInto a pointer to a memory location which will have content written to it.
* @param length the number of bytes to read. If this number is 0 then the next
* byte will be returned without incrementing the pointer.
* @return 0 if read went well, -1 if the content ran out and no more could be read.
*/
int (* const read)(struct Reader* thisReader, void* readInto, unsigned long length);
/**
* Advance the pointer a number of bytes without reading any.
* This function will happily skip off the end of the source and the next read will fail.
*
* @param thisReader the Reader which is being called.
* @param byteCount how far to advance the pointer.
*/
void (* const skip)(struct Reader* thisReader, unsigned long byteCount);
/** The total number of bytes which have been read OR SKIPPED by this reader. */
uint64_t bytesRead;
};
#define Reader_readGeneric(bytes) \
static inline uint##bytes##_t Reader_read##bytes (struct Reader* reader) \
{ \
uint##bytes##_t num; \
reader->read(reader, &num, bytes/8); \
return num; \
}
Reader_readGeneric(8)
Reader_readGeneric(16)
Reader_readGeneric(32)
Reader_readGeneric(64)
#define Reader_read(reader, readInto, bytes) \
(reader)->read((reader), (readInto), (bytes))
#define Reader_skip(reader, bytes) \
(reader)->skip((reader), (bytes))
#define Reader_bytesRead(reader) \
((reader)->bytesRead + 0)
#endif