/* ************************************************************************** */ /* */ /* ::: :::::::: */ /* get_next_line_bonus.c :+: :+: :+: */ /* +:+ +:+ +:+ */ /* By: narnaud +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2021/10/25 10:00:41 by narnaud #+# #+# */ /* Updated: 2021/11/19 17:27:43 by narnaud ### ########.fr */ /* */ /* ************************************************************************** */ #include "get_next_line_bonus.h" int close_buffer(t_buffer **buffers, int fd) { t_buffer *buffer; t_buffer *previous; buffer = *buffers; previous = NULL; while (buffer) { if (buffer->fd == fd) { if (previous && buffer->next) previous->next = buffer->next; else if (previous) previous->next = NULL; else if (buffer->next) *buffers = buffer->next; else *buffers = NULL; free(buffer->content); free(buffer); return (1); } previous = buffer; buffer = buffer->next; } return (1); } static t_buffer *load_buffer(t_buffer **buffers, int fd) { t_buffer *previous; t_buffer *buffer; buffer = *buffers; previous = NULL; while (buffer) { if (buffer->fd == fd) return (buffer); previous = buffer; buffer = buffer->next; } buffer = ft_calloc(1, sizeof(*buffer)); buffer->content = (char *)ft_calloc(BUFFER_SIZE + 1, sizeof(char)); buffer->pos = 0; buffer->read_length = 0; buffer->fd = fd; buffer->next = NULL; if (previous) previous->next = buffer; else *buffers = buffer; return (buffer); } int parse_buffer(t_buffer *buffer, t_split **line) { t_split *split; split = ft_lstlast(*line); while (buffer->content[buffer->pos]) { if (buffer->pos >= buffer->read_length) break ; if (split->i == SPLIT_SIZE) { split = ft_new_split(ft_calloc(SPLIT_SIZE + 1, sizeof(char))); ft_lstadd_back(line, split); } (split->content)[split->i] = buffer->content[buffer->pos]; if (buffer->content[buffer->pos++] == '\n') return (1); (split->i)++; } buffer->pos = 0; return (0); } char *merge_splits(t_split **split) { t_split *next; char *ret; size_t i; size_t count; next = ft_lstlast(*split); count = next->count; ret = (char *)ft_calloc((count * SPLIT_SIZE) + 1, sizeof(char)); i = 0; while (split && *split) { next = (*split)->next; (*split)->i = 0; while ((*split)->content[(*split)->i]) { ret[i] = (*split)->content[(*split)->i]; i++; ((*split)->i)++; } free((*split)->content); free(*split); *split = next; } ret[i] = '\0'; return (ret); } char *get_next_line(int fd) { static t_buffer *buffers; t_buffer *buffer; t_split *line; char *ret; buffer = load_buffer(&buffers, fd); if (read(fd, buffer->content, 0) < 0 && close_buffer(&buffers, fd)) return (NULL); line = ft_new_split(ft_calloc(SPLIT_SIZE + 1, sizeof(char))); while (!parse_buffer(buffer, &line)) { buffer->read_length = read(fd, buffer->content, BUFFER_SIZE); if (buffer->read_length <= 0 && close_buffer(&buffers, fd)) break ; } ret = merge_splits(&line); if (*ret) return (ret); free(ret); return (NULL); }