Whole solution of get_next_line.
authorLukas Jiriste <ljiriste@student.42prague.com>
Mon, 28 Aug 2023 11:40:13 +0000 (13:40 +0200)
committerLukas Jiriste <ljiriste@student.42prague.com>
Mon, 28 Aug 2023 11:40:13 +0000 (13:40 +0200)
Needs testing and splitting to multiple files.

get_next_line.c [new file with mode: 0644]
get_next_line.h [new file with mode: 0644]

diff --git a/get_next_line.c b/get_next_line.c
new file mode 100644 (file)
index 0000000..d75f4d1
--- /dev/null
@@ -0,0 +1,187 @@
+/* ************************************************************************** */
+/*                                                                            */
+/*                                                        :::      ::::::::   */
+/*   get_next_line.c                                    :+:      :+:    :+:   */
+/*                                                    +:+ +:+         +:+     */
+/*   By: ljiriste <marvin@42.fr>                    +#+  +:+       +#+        */
+/*                                                +#+#+#+#+#+   +#+           */
+/*   Created: 2023/08/28 00:01:15 by ljiriste          #+#    #+#             */
+/*   Updated: 2023/08/28 00:32:32 by ljiriste         ###   ########.fr       */
+/*                                                                            */
+/* ************************************************************************** */
+
+#include <stdlib.h>
+#include <unistd.h>
+#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 (file)
index 0000000..662a6d6
--- /dev/null
@@ -0,0 +1,34 @@
+/* ************************************************************************** */
+/*                                                                            */
+/*                                                        :::      ::::::::   */
+/*   get_next_line.h                                    :+:      :+:    :+:   */
+/*                                                    +:+ +:+         +:+     */
+/*   By: ljiriste <marvin@42.fr>                    +#+  +:+       +#+        */
+/*                                                +#+#+#+#+#+   +#+           */
+/*   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