1 //===-- Reader definition for scanf -----------------------------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #ifndef LLVM_LIBC_SRC_STDIO_SCANF_CORE_READER_H 10 #define LLVM_LIBC_SRC_STDIO_SCANF_CORE_READER_H 11 12 #include "src/__support/macros/attributes.h" // For LIBC_INLINE 13 #include <stddef.h> 14 15 namespace LIBC_NAMESPACE { 16 namespace scanf_core { 17 18 using StreamGetc = int (*)(void *); 19 using StreamUngetc = void (*)(int, void *); 20 21 // This is intended to be either a raw string or a buffer syncronized with the 22 // file's internal buffer. 23 struct ReadBuffer { 24 char *buffer; 25 size_t buff_len; 26 size_t buff_cur = 0; 27 }; 28 29 class Reader { 30 ReadBuffer *rb; 31 32 void *input_stream = nullptr; 33 34 StreamGetc stream_getc = nullptr; 35 StreamUngetc stream_ungetc = nullptr; 36 37 size_t cur_chars_read = 0; 38 39 public: 40 // TODO: Set buff_len with a proper constant Reader(ReadBuffer * string_buffer)41 LIBC_INLINE Reader(ReadBuffer *string_buffer) : rb(string_buffer) {} 42 43 LIBC_INLINE Reader(void *stream, StreamGetc stream_getc_in, 44 StreamUngetc stream_ungetc_in, 45 ReadBuffer *stream_buffer = nullptr) rb(stream_buffer)46 : rb(stream_buffer), input_stream(stream), stream_getc(stream_getc_in), 47 stream_ungetc(stream_ungetc_in) {} 48 49 // This returns the next character from the input and advances it by one 50 // character. When it hits the end of the string or file it returns '\0' to 51 // signal to stop parsing. getc()52 LIBC_INLINE char getc() { 53 ++cur_chars_read; 54 if (rb != nullptr) { 55 char output = rb->buffer[rb->buff_cur]; 56 ++(rb->buff_cur); 57 return output; 58 } 59 // This should reset the buffer if applicable. 60 return static_cast<char>(stream_getc(input_stream)); 61 } 62 63 // This moves the input back by one character, placing c into the buffer if 64 // this is a file reader, else c is ignored. 65 void ungetc(char c); 66 chars_read()67 LIBC_INLINE size_t chars_read() { return cur_chars_read; } 68 }; 69 70 } // namespace scanf_core 71 } // namespace LIBC_NAMESPACE 72 73 #endif // LLVM_LIBC_SRC_STDIO_SCANF_CORE_READER_H 74