/* ************************************************************************** */ /* */ /* ::: :::::::: */ /* get_next_line.c :+: :+: :+: */ /* +:+ +:+ +:+ */ /* By: thrieg +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/10/17 16:43:41 by thrieg #+# #+# */ /* Updated: 2025/02/16 19:06:56 by thrieg ### ########.fr */ /* */ /* ************************************************************************** */ #include "get_next_line.h" char *ft_read( int fd, t_gnl_list *node, t_gnl_vector *vec, t_gnl_list **node_before); t_gnl_vector *ft_read_buffer(t_gnl_list *node, t_gnl_vector *ret); char *ft_read_return( t_gnl_vector *vec, t_gnl_list *node_to_free, t_gnl_list **node_before, int return_null_flag); t_gnl_list *ft_gnl_create_bufflist(int fd); void *ft_gnl_free_list(t_gnl_list **buff_list); t_gnl_vector *ft_gnl_create_vector(size_t size); char *ft_gnl_vtoc(t_gnl_vector *vec); t_gnl_vector *ft_gnl_vector_concat( t_gnl_vector *dest, void *src, size_t size); t_gnl_vector *ft_read_buffer(t_gnl_list *node, t_gnl_vector *ret) { t_gnl_vector *temp; size_t initial_index; if (!ret) ret = ft_gnl_create_vector(2); if (!ret) return (NULL); initial_index = node->index; while ((node->index < (size_t)node->nb_chars) && (node->buffer[node->index] != '\n')) node->index++; if (node->index < (size_t)node->nb_chars) { node->index++; ret->finished = 1; } temp = ft_gnl_vector_concat(ret, &node->buffer[initial_index], (node->index - initial_index)); if (!temp) { if (ret->buffer) free(ret->buffer); free(ret); } return (temp); } char *ft_read_return( t_gnl_vector *vec, t_gnl_list *node_to_free, t_gnl_list **node_before, int return_null_flag) { char *ret; t_gnl_list *next_node; ret = NULL; if (!return_null_flag) ret = ft_gnl_vtoc(vec); if (vec) { if (vec->buffer) free(vec->buffer); free(vec); } if (node_to_free) { next_node = node_to_free->next; if (*node_before != node_to_free) (*node_before)->next = next_node; if (node_to_free->buffer) free(node_to_free->buffer); free(node_to_free); if (*node_before == node_to_free) *node_before = next_node; } return (ret); } //vec must be initialized to NULL or it will cause a segfault char *ft_read( int fd, t_gnl_list *node, t_gnl_vector *vec, t_gnl_list **node_before) { if (node->index < (size_t)node->nb_chars) { vec = ft_read_buffer(node, vec); if (!vec) return (ft_read_return(vec, node, node_before, 1)); if (vec->finished == 1) return (ft_read_return(vec, NULL, NULL, 0)); } while (node->index >= (size_t)node->nb_chars) { node->index = 0; node->nb_chars = read(fd, node->buffer, BUFFER_SIZE); if (node->nb_chars == 0) return (ft_read_return(vec, node, node_before, 0)); if (node->nb_chars < 0) return (ft_read_return(vec, node, node_before, 1)); vec = ft_read_buffer(node, vec); if (!vec) return (ft_read_return(vec, node, node_before, 1)); if (vec->finished == 1) return (ft_read_return(vec, NULL, NULL, 0)); } return (ft_read_return(vec, NULL, NULL, 0)); } //returns the node having fd as its fd member //node_before set to the previous node //if no node is found, the last node is returned //if we return the first node, flag is set and node_before = current_node t_gnl_list *ft_get_current_node( t_gnl_list *start_node, int fd, int *first_node_flag, t_gnl_list **node_before) { t_gnl_list *current_node; current_node = start_node; *first_node_flag = 1; *node_before = current_node; while (current_node->next) { if (current_node->fd == fd) break ; *first_node_flag = 0; *node_before = current_node; current_node = current_node->next; } if (current_node->fd != fd) { current_node->next = ft_gnl_create_bufflist(fd); if (!(current_node->next)) return (NULL); *first_node_flag = 0; *node_before = current_node; current_node = current_node->next; } return (current_node); } char *get_next_line(int fd) { static t_gnl_list *buff_list = NULL; t_gnl_list *current_node; t_gnl_list *previous_node; t_gnl_vector *vec; int flag; if (fd < 0) return (NULL); if (!buff_list) buff_list = ft_gnl_create_bufflist(fd); if (!buff_list) return (NULL); flag = 0; current_node = ft_get_current_node(buff_list, fd, &flag, &previous_node); if (!current_node) return (NULL); vec = NULL; if (flag) return (ft_read(fd, current_node, vec, &buff_list)); else return (ft_read(fd, current_node, vec, &previous_node)); }