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 18 #include <stdint.h> 19 20 /** 21 * Reader interface which reads data from a source and fails safe rather than overreading. 22 */ 23 struct Reader { 24 /** 25 * Read some content from a buffer or other source. 26 * 27 * @param thisReader the Reader which is being called. 28 * @param readInto a pointer to a memory location which will have content written to it. 29 * @param length the number of bytes to read. If this number is 0 then the next 30 * byte will be returned without incrementing the pointer. 31 * @return 0 if read went well, -1 if the content ran out and no more could be read. 32 */ 33 int (* const read)(struct Reader* thisReader, void* readInto, unsigned long length); 34 35 /** 36 * Advance the pointer a number of bytes without reading any. 37 * This function will happily skip off the end of the source and the next read will fail. 38 * 39 * @param thisReader the Reader which is being called. 40 * @param byteCount how far to advance the pointer. 41 */ 42 void (* const skip)(struct Reader* thisReader, unsigned long byteCount); 43 44 /** The total number of bytes which have been read OR SKIPPED by this reader. */ 45 uint64_t bytesRead; 46 }; 47 48 49 #define Reader_readGeneric(bytes) \ 50 static inline uint##bytes##_t Reader_read##bytes (struct Reader* reader) \ 51 { \ 52 uint##bytes##_t num; \ 53 reader->read(reader, &num, bytes/8); \ 54 return num; \ 55 } 56 57 Reader_readGeneric(8) 58 Reader_readGeneric(16) 59 Reader_readGeneric(32) 60 Reader_readGeneric(64) 61 62 63 #define Reader_read(reader, readInto, bytes) \ 64 (reader)->read((reader), (readInto), (bytes)) 65 66 #define Reader_skip(reader, bytes) \ 67 (reader)->skip((reader), (bytes)) 68 69 #define Reader_bytesRead(reader) \ 70 ((reader)->bytesRead + 0) 71 72 #endif 73