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 "src/__support/macros/config.h" 14 #include <stddef.h> 15 16 namespace LIBC_NAMESPACE_DECL { 17 namespace scanf_core { 18 19 using StreamGetc = int (*)(void *); 20 using StreamUngetc = void (*)(int, void *); 21 22 // This is intended to be either a raw string or a buffer syncronized with the 23 // file's internal buffer. 24 struct ReadBuffer { 25 const char *buffer; 26 size_t buff_len; 27 size_t buff_cur = 0; 28 }; 29 30 class Reader { 31 ReadBuffer *rb; 32 33 void *input_stream = nullptr; 34 35 // TODO: Remove these unnecessary function pointers 36 StreamGetc stream_getc = nullptr; 37 StreamUngetc stream_ungetc = nullptr; 38 39 size_t cur_chars_read = 0; 40 41 public: 42 // TODO: Set buff_len with a proper constant Reader(ReadBuffer * string_buffer)43 LIBC_INLINE Reader(ReadBuffer *string_buffer) : rb(string_buffer) {} 44 45 LIBC_INLINE Reader(void *stream, StreamGetc stream_getc_in, 46 StreamUngetc stream_ungetc_in, 47 ReadBuffer *stream_buffer = nullptr) rb(stream_buffer)48 : rb(stream_buffer), input_stream(stream), stream_getc(stream_getc_in), 49 stream_ungetc(stream_ungetc_in) {} 50 51 // This returns the next character from the input and advances it by one 52 // character. When it hits the end of the string or file it returns '\0' to 53 // signal to stop parsing. getc()54 LIBC_INLINE char getc() { 55 ++cur_chars_read; 56 if (rb != nullptr) { 57 char output = rb->buffer[rb->buff_cur]; 58 ++(rb->buff_cur); 59 return output; 60 } 61 // This should reset the buffer if applicable. 62 return static_cast<char>(stream_getc(input_stream)); 63 } 64 65 // This moves the input back by one character, placing c into the buffer if 66 // this is a file reader, else c is ignored. 67 void ungetc(char c); 68 chars_read()69 LIBC_INLINE size_t chars_read() { return cur_chars_read; } 70 }; 71 72 } // namespace scanf_core 73 } // namespace LIBC_NAMESPACE_DECL 74 75 #endif // LLVM_LIBC_SRC_STDIO_SCANF_CORE_READER_H 76