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 18 : int * perr ) { 9 18 : *perr = 0; 10 18 : ulong const out_max = (ulong)fd_int_max( str_max, 1 ) - 1UL; 11 : 12 36 : for( ulong attempt=0UL; attempt<=1UL; attempt++ ) { 13 30 : char const * peek = fd_io_buffered_istream_peek ( istream ); 14 30 : ulong peek_max = fd_io_buffered_istream_peek_sz( istream ); 15 : 16 30 : void * peek_found = memchr( peek, '\n', peek_max ); 17 30 : if( peek_found ) { 18 12 : ulong peek_sz = (ulong)peek_found - (ulong)peek + 1UL; 19 12 : peek_sz = fd_ulong_min( peek_sz, out_max ); 20 12 : fd_cstr_fini( fd_cstr_append_text( fd_cstr_init( str ), peek, peek_sz ) ); 21 12 : fd_io_buffered_istream_skip( istream, peek_sz ); 22 12 : return str; 23 12 : } 24 : 25 18 : int err = fd_io_buffered_istream_fetch( istream ); 26 18 : if( FD_UNLIKELY( err>0 ) ) { 27 0 : *perr = err; 28 0 : return NULL; 29 0 : } 30 18 : if( FD_UNLIKELY( err<0 ) ) { 31 12 : *perr = -1; 32 : /* continue */ 33 12 : } 34 18 : if( FD_UNLIKELY( !fd_io_buffered_istream_peek_sz( istream ) ) ) { 35 0 : *perr = -1; 36 0 : return NULL; 37 0 : } 38 18 : } 39 : 40 : /* Could not find newline char even with full buffer, so just return 41 : what we have. */ 42 6 : char const * peek = fd_io_buffered_istream_peek ( istream ); 43 6 : ulong peek_max = fd_io_buffered_istream_peek_sz( istream ); 44 6 : ulong peek_sz = fd_ulong_min( out_max, peek_max ); 45 6 : fd_cstr_fini( fd_cstr_append_text( fd_cstr_init( str ), peek, peek_sz ) ); 46 6 : return str; 47 18 : } 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 : }