From 4a35e403764043870057837680d61f7d76a2c26a Mon Sep 17 00:00:00 2001 From: Lukas Jiriste Date: Mon, 28 Aug 2023 13:40:13 +0200 Subject: [PATCH] Whole solution of get_next_line. Needs testing and splitting to multiple files. --- get_next_line.c | 187 ++++++++++++++++++++++++++++++++++++++++++++++++ get_next_line.h | 34 +++++++++ 2 files changed, 221 insertions(+) create mode 100644 get_next_line.c create mode 100644 get_next_line.h diff --git a/get_next_line.c b/get_next_line.c new file mode 100644 index 0000000..d75f4d1 --- /dev/null +++ b/get_next_line.c @@ -0,0 +1,187 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* get_next_line.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: ljiriste +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2023/08/28 00:01:15 by ljiriste #+# #+# */ +/* Updated: 2023/08/28 00:32:32 by ljiriste ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include +#include +#include "get_next_line.h" + +void *ft_memmove(void *dest, const void *src, size_t n) +{ + size_t i; + + if (dest > src) + { + i = n; + while (i > 0) + { + --i; + *((unsigned char *)dest + i) = *((unsigned char *)src + i); + } + } + else if (dest < src) + { + i = 0; + while (i < n) + { + *((unsigned char *)dest + i) = *((unsigned char *)src + i); + ++i; + } + } + return (dest); +} + +t_list *ft_lstnew(void *content) +{ + t_list *res; + + res = malloc(sizeof(t_list)); + if (res == NULL) + return (res); + res->content = content; + res->next = NULL; + return (res); +} + +t_list *new_ft_node(int fd) +{ + t_list *node; + t_ft *thread; + + thread = malloc(sizeof(t_ft)); + if (thread == NULL) + return (NULL); + node = ft_lstnew(thread); + if (node == NULL) + { + free(thread); + return (NULL); + } + thread->buffer = malloc((BUFFER_SIZE + 1) * sizeof(char)); + if (thread->buffer == NULL) + { + free(thread); + free(node); + return (NULL); + } + (thread->buffer)[0] = '\0'; + thread->fd = fd; + return (node); +} + +// How to free? +// static in get_next_line? So it could be passed to select AND delete +char *select_file_buffer(int fd, t_list **list) +{ + t_list *local_head; + + if (*list == NULL) + { + *list = new_ft_node(fd); + if (list == NULL) + return (NULL); + return (((t_ft *)((*list)->content))->buffer); + } + local_head = *list; + while (local_head->next || ((t_ft *)(local_head->content))->fd != fd) + local_head = local_head->next; + if (((t_ft *)(local_head->content))->fd == fd) + return (((t_ft *)(local_head->content))->buffer); + local_head->next = new_ft_node(fd); + if (local_head->next == NULL) + return (NULL); + return (((t_ft *)(local_head->next->content))->buffer); +} + +void delete_file_node(int fd, t_list **list) +{ + t_list *cur; + t_list *prev; + + prev = NULL; + cur = *list; + while (((t_ft *)(cur->content))->fd != fd) + { + prev = cur; + cur = cur->next; + } + if (prev == NULL) + *list = NULL; + else + prev->next = cur->next; + free(((t_ft *)(cur->content))->buffer); + free(cur->content); + free(cur); + return ; +} + +void ft_strncat_alloc(char **dest, char *src, int n) +{ + int size; + char *temp; + + if (n <= 0) + return ; + temp = *dest; + size = 0; + if (temp) + while (temp[size]) + ++size; + size += n + 1; + *dest = malloc(size); + if (*dest == NULL) + { + free(temp); + return ; + } + ft_memmove(*dest, temp, size - n - 1); + ft_memmove(*dest + size - n - 1, src, n); + (*dest)[size - 1] = '\0'; + free(temp); + return ; +} + +char *get_next_line(int fd) +{ + static t_list *list; + char *buffer; + char *res; + int i; + int nl_found; + + res = NULL; + buffer = select_file_buffer(fd, &list); + i = 0; + nl_found = 0; + while (!nl_found) + { + while (buffer[i] && buffer[i] != '\n') + ++i; + nl_found = (buffer[i] == '\n'); + i += nl_found; + ft_strncat_alloc(&res, buffer, i); + if (buffer[i] == '\0') + { + i = read(fd, buffer, BUFFER_SIZE); + buffer[i] = '\0'; + if (i <= 0) + delete_file_node(fd, &list); + if (i < 0) + return (NULL); + if (i == 0) + return (res); + } + else if (i > 0) + ft_memmove(buffer, buffer + i, BUFFER_SIZE + 1 - i); + i = 0; + } + return (res); +} diff --git a/get_next_line.h b/get_next_line.h new file mode 100644 index 0000000..662a6d6 --- /dev/null +++ b/get_next_line.h @@ -0,0 +1,34 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* get_next_line.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: ljiriste +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2023/08/28 11:24:52 by ljiriste #+# #+# */ +/* Updated: 2023/08/28 11:29:18 by ljiriste ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef GET_NEXT_LINE_H +# define GET_NEXT_LINE_H + +# ifndef BUFFER_SIZE +# define BUFFER_SIZE 81 +# endif + +typedef struct s_file_thread +{ + int fd; + char *buffer; +} t_ft; + +typedef struct s_list +{ + void *content; + struct s_list *next; +} t_list; + +char *get_next_line(int fd); + +#endif -- 2.30.2