--- /dev/null
+/* ************************************************************************** */
+/* */
+/* ::: :::::::: */
+/* ft_strncat_alloc.c :+: :+: :+: */
+/* +:+ +:+ +:+ */
+/* By: ljiriste <marvin@42.fr> +#+ +:+ +#+ */
+/* +#+#+#+#+#+ +#+ */
+/* Created: 2023/09/11 13:36:53 by ljiriste #+# #+# */
+/* Updated: 2023/12/03 19:45:18 by ljiriste ### ########.fr */
+/* */
+/* ************************************************************************** */
+
+#include <stdlib.h> // malloc etc.
+#include "libft.h"
+
+/* Functions like ft_strncat but reallocates dest to
+ make sure it is large enough */
+char *ft_strncat_alloc(char **dest, const char *src, size_t n)
+{
+ int size;
+ char *temp;
+
+ if (n == 0)
+ return (*dest);
+ temp = *dest;
+ size = 0;
+ if (temp)
+ while (temp[size])
+ ++size;
+ size += n + 1;
+ *dest = malloc(size);
+ if (*dest == NULL)
+ {
+ free(temp);
+ return (NULL);
+ }
+ ft_memmove(*dest, temp, size - n - 1);
+ ft_memmove(*dest + size - n - 1, src, n);
+ (*dest)[size - 1] = '\0';
+ free(temp);
+ return (*dest);
+}
--- /dev/null
+/* ************************************************************************** */
+/* */
+/* ::: :::::::: */
+/* get_next_line.c :+: :+: :+: */
+/* +:+ +:+ +:+ */
+/* By: ljiriste <marvin@42.fr> +#+ +:+ +#+ */
+/* +#+#+#+#+#+ +#+ */
+/* Created: 2023/08/28 00:01:15 by ljiriste #+# #+# */
+/* Updated: 2023/12/03 19:52:16 by ljiriste ### ########.fr */
+/* */
+/* ************************************************************************** */
+
+#include <stdlib.h>
+#include <unistd.h>
+#include "get_next_line.h"
+#include "libft.h"
+
+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
+static 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);
+}
+
+static 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 = cur->next;
+ else
+ prev->next = cur->next;
+ free(((t_ft *)(cur->content))->buffer);
+ free(cur->content);
+ free(cur);
+ return ;
+}
+
+/* Concatenates res and buffer up to newline.
+ Shifts buffer by the transfered characters.
+ Returns 0 when buffer is empty (and needs filling with read).
+ Also returns 1 when newline is transfered
+ unless buffer empty (to delete node).
+ Otherwise returns true.
+*/
+static int transfer_string(char **res, char *buffer)
+{
+ int i;
+ int nl;
+
+ i = 0;
+ while (buffer[i] && buffer[i] != '\n')
+ ++i;
+ nl = (buffer[i] == '\n');
+ i += nl;
+ ft_strncat_alloc(res, buffer, i);
+ ft_memmove(buffer, buffer + i, BUFFER_SIZE + 1 - i);
+ return (buffer[0] || nl);
+}
+
+char *get_next_line(int fd)
+{
+ static t_list *list;
+ char *buffer;
+ char *res;
+ int i;
+
+ res = NULL;
+ buffer = select_file_buffer(fd, &list);
+ while (!transfer_string(&res, buffer))
+ {
+ if (buffer[0] == '\0')
+ {
+ i = read(fd, buffer, BUFFER_SIZE);
+ if (i <= 0)
+ delete_file_node(fd, &list);
+ if (i < 0)
+ {
+ free(res);
+ return (NULL);
+ }
+ if (i == 0)
+ return (res);
+ buffer[i] = '\0';
+ }
+ }
+ return (res);
+}
--- /dev/null
+/* ************************************************************************** */
+/* */
+/* ::: :::::::: */
+/* get_next_line.h :+: :+: :+: */
+/* +:+ +:+ +:+ */
+/* By: ljiriste <marvin@42.fr> +#+ +:+ +#+ */
+/* +#+#+#+#+#+ +#+ */
+/* Created: 2023/08/28 11:24:52 by ljiriste #+# #+# */
+/* Updated: 2023/10/11 18:16:37 by ljiriste ### ########.fr */
+/* */
+/* ************************************************************************** */
+
+#ifndef GET_NEXT_LINE_H
+# define GET_NEXT_LINE_H
+
+# ifndef BUFFER_SIZE
+# define BUFFER_SIZE 80
+# endif
+
+# include <stddef.h>
+
+typedef struct s_file_thread
+{
+ int fd;
+ char *buffer;
+} t_ft;
+
+char *get_next_line(int fd);
+
+#endif
size_t ft_strlen(const char *s);
size_t ft_strlcpy(char *dst, const char *src, size_t size);
size_t ft_strlcat(char *dst, const char *src, size_t size);
+char *ft_strncat_alloc(char **dest, const char *src, size_t n);
int ft_strncmp(const char *s1, const char *s2, size_t n);
char *ft_strchr(const char *s, int c);
char *ft_strrchr(const char *s, int c);
void ft_swap(void **a, void **b);
+char *get_next_line(int fd);
+
typedef struct s_list
{
struct s_list *next;