| 1030 | using byte searches for a single-byte or valid UTF-8 field delimiter. */ |
| 1031 | |
| 1032 | static void |
| 1033 | cut_fields_bytesearch (FILE *stream) |
| 1034 | { |
| 1035 | /* Leave 1 byte unused so space to NUL terminate (for strstr). */ |
| 1036 | static char bytes_in[IO_BUFSIZE+1]; |
| 1037 | mbbuf_t mbbuf; |
| 1038 | uintmax_t field_idx = 1; |
| 1039 | bool found_any_selected_field = false; |
| 1040 | bool have_pending_line = false; |
| 1041 | bool skip_blank_run = false; |
| 1042 | bool pending_line_delim_field = false; |
| 1043 | bool write_field; |
| 1044 | idx_t field_1_n_bytes = 0; |
| 1045 | |
| 1046 | current_rp = frp; |
| 1047 | bool buffer_first_field = suppress_non_delimited ^ !print_kth (1); |
| 1048 | mbbuf_init (&mbbuf, bytes_in, sizeof bytes_in - 1, stream); |
| 1049 | write_field = begin_field_output (field_idx, buffer_first_field, |
| 1050 | &found_any_selected_field); |
| 1051 | |
| 1052 | struct bytesearch_context search = { .blank_delimited = whitespace_delimited}; |
| 1053 | bytesearch_context_reset (&search); |
| 1054 | |
| 1055 | while (true) |
| 1056 | { |
| 1057 | idx_t n_avail = mbbuf_topup (&mbbuf); |
| 1058 | search.at_eof = mbbuf.eof; |
| 1059 | search.line_end_known = false; |
| 1060 | |
| 1061 | if (pending_line_delim_field) |
| 1062 | { |
| 1063 | pending_line_delim_field = false; |
| 1064 | |
| 1065 | if (n_avail == 0) |
| 1066 | { |
| 1067 | if (handle_field_1 (field_idx, buffer_first_field, |
| 1068 | &field_1_n_bytes)) |
| 1069 | next_item (&field_idx); |
| 1070 | maybe_write_line_delim (found_any_selected_field, field_idx); |
| 1071 | return; |
| 1072 | } |
| 1073 | |
| 1074 | handle_field_delimiter (&field_idx, buffer_first_field, |
| 1075 | &field_1_n_bytes, |
| 1076 | &found_any_selected_field, &write_field, |
| 1077 | whitespace_delimited, &skip_blank_run); |
| 1078 | } |
| 1079 | |
| 1080 | if (n_avail == 0) |
| 1081 | break; |
| 1082 | |
| 1083 | char *chunk = mbbuf.buffer + mbbuf.offset; |
| 1084 | idx_t processed = 0; |
| 1085 | |
| 1086 | /* Fast path: no field delimiter in chunk — output or skip lines. */ |
| 1087 | if (field_idx == 1 |
| 1088 | && !whitespace_delimited |
| 1089 | && !field_delim_is_line_delim () |
no test coverage detected