Line data Source code
1 : #include "fd_io_readline.h" 2 : #include "../../util/cstr/fd_cstr.h" 3 : 4 : char * 5 : fd_io_fgets( char * restrict str, 6 : int str_max, 7 : fd_io_buffered_istream_t * istream, 8 0 : int * perr ) { 9 0 : *perr = 0; 10 0 : ulong const out_max = (ulong)fd_int_max( str_max, 1 ) - 1UL; 11 : 12 0 : for( ulong attempt=0UL; attempt<=1UL; attempt++ ) { 13 0 : char const * peek = fd_io_buffered_istream_peek ( istream ); 14 0 : ulong peek_max = fd_io_buffered_istream_peek_sz( istream ); 15 : 16 0 : void * peek_found = memchr( peek, '\n', peek_max ); 17 0 : if( peek_found ) { 18 0 : ulong peek_sz = (ulong)peek_found - (ulong)peek + 1UL; 19 0 : peek_sz = fd_ulong_min( peek_sz, out_max ); 20 0 : fd_cstr_fini( fd_cstr_append_text( fd_cstr_init( str ), peek, peek_sz ) ); 21 0 : fd_io_buffered_istream_skip( istream, peek_sz ); 22 0 : return str; 23 0 : } 24 : 25 0 : int err = fd_io_buffered_istream_fetch( istream ); 26 0 : if( FD_UNLIKELY( err>0 ) ) { 27 0 : *perr = err; 28 0 : return NULL; 29 0 : } 30 0 : if( FD_UNLIKELY( err<0 ) ) { 31 0 : *perr = -1; 32 : /* continue */ 33 0 : } 34 0 : if( FD_UNLIKELY( !fd_io_buffered_istream_peek_sz( istream ) ) ) { 35 0 : *perr = -1; 36 0 : return NULL; 37 0 : } 38 0 : } 39 : 40 : /* Could not find newline char even with full buffer, so just return 41 : what we have. */ 42 0 : char const * peek = fd_io_buffered_istream_peek ( istream ); 43 0 : ulong peek_max = fd_io_buffered_istream_peek_sz( istream ); 44 0 : ulong peek_sz = fd_ulong_min( out_max, peek_max ); 45 0 : fd_cstr_fini( fd_cstr_append_text( fd_cstr_init( str ), peek, peek_sz ) ); 46 0 : return str; 47 0 : } 48 : 49 : int 50 : fd_io_fgetc( fd_io_buffered_istream_t * istream, 51 0 : int * perr ) { 52 0 : for( ulong attempt=0UL; attempt<=1UL; attempt++ ) { 53 0 : uchar const * peek = fd_io_buffered_istream_peek ( istream ); 54 0 : ulong peek_max = fd_io_buffered_istream_peek_sz( istream ); 55 0 : if( peek_max ) { 56 0 : *perr = 0; 57 0 : return (int)*peek; 58 0 : } 59 : 60 0 : int err = fd_io_buffered_istream_fetch( istream ); 61 0 : if( FD_UNLIKELY( err!=0 ) ) { 62 0 : *perr = err; 63 0 : return -1; 64 0 : } 65 0 : } 66 : 67 : /* unreachable */ 68 0 : *perr = -1; 69 0 : return -1; 70 0 : }