]> Untitled Git - axy/ft/get_next_line.git/commitdiff
bonus
author= <=>
Thu, 6 Nov 2025 17:05:40 +0000 (18:05 +0100)
committer= <=>
Thu, 6 Nov 2025 17:05:40 +0000 (18:05 +0100)
get_next_line_bonus.c [new file with mode: 0644]
get_next_line_bonus.h [new file with mode: 0644]
get_next_line_utils_bonus.c [new file with mode: 0644]

diff --git a/get_next_line_bonus.c b/get_next_line_bonus.c
new file mode 100644 (file)
index 0000000..964cfb0
--- /dev/null
@@ -0,0 +1,116 @@
+/* ************************************************************************** */
+/*                                                                            */
+/*                                                        :::      ::::::::   */
+/*   get_next_line.c                                    :+:      :+:    :+:   */
+/*                                                    +:+ +:+         +:+     */
+/*   By: agilliar <agilliar@student.42mulhouse.fr>  +#+  +:+       +#+        */
+/*                                                +#+#+#+#+#+   +#+           */
+/*   Created: 2025/11/01 10:55:35 by agilliar          #+#    #+#             */
+/*   Updated: 2025/11/06 18:00:50 by agilliar         ###   ########.fr       */
+/*                                                                            */
+/* ************************************************************************** */
+
+#include <stdbool.h>
+#include <stdlib.h>
+
+#include "get_next_line.h"
+
+void           buffer_pushchar(t_buf *buf, char c);
+void           buffers_remove(t_readbufs *bufs, int fd);
+void           *ft_memcpy(void *dest, const void *src, size_t n);
+bool           readbuf_read(t_readbuf *buf);
+t_readbuf      *buffers_get(t_readbufs *bufs, int fd);
+
+char   *buffer_finish(t_buf buf, t_readbufs *buffers, int fd)
+{
+       if (buf.buf)
+               buffer_pushchar(&buf, '\0');
+       if (!buf.buf)
+               buffers_remove(buffers, fd);
+       return (buf.buf);
+}
+
+/*
+       returns whether it should keep going
+*/
+bool   buffer_empty(t_readbuf *buf, t_buf *dst)
+{
+       size_t  i;
+
+       if (buf->written == 0)
+               return (false);
+       i = 0;
+       while (i < buf->written)
+       {
+               buffer_pushchar(dst, buf->buf[i++]);
+               if (dst->buf == NULL)
+                       return (false);
+               if (dst->buf[dst->len - 1] == '\n')
+                       break ;
+       }
+       buf->written -= i;
+       ft_memcpy(buf->buf, &buf->buf[i], buf->written);
+       if (dst->buf[dst->len - 1] == '\n')
+               return (false);
+       return (true);
+}
+
+char   *get_next_line(int fd)
+{
+       static t_readbufs       buffers = {
+               .used = 0
+       };
+       t_readbuf                       *buf;
+       t_buf                           res;
+
+       res.len = 0;
+       res.capacity = 0;
+       res.buf = NULL;
+       buf = buffers_get(&buffers, fd);
+       if (!buf)
+               return (NULL);
+       while (true)
+       {
+               if (!readbuf_read(buf))
+               {
+                       buffers_remove(&buffers, fd);
+                       free(res.buf);
+                       return (NULL);
+               }
+               if (!buffer_empty(buf, &res))
+                       return (buffer_finish(res, &buffers, fd));
+       }
+}
+
+/*
+#include <fcntl.h>
+#include <stdio.h>
+
+int    main(int argc, char **argv)
+{
+       char    *nl;
+       bool    any_line;
+
+       for (int i = 1; i < argc; i++)
+               ((int *)argv)[i] = open(argv[i], O_RDONLY);
+       any_line = true;
+       for (int i = 0; any_line; i++)
+       {
+               any_line = false;
+               for (int j = 1; j < argc; j++)
+               {
+                       nl = get_next_line(((int *)argv)[j]);
+                       if (!nl)
+                               continue;
+                       any_line = true;
+                       printf("line %i file %i: %s", i, j, nl);
+                       free(nl);
+               }
+       }
+       for (char *nl; (nl = get_next_line(0));)
+       {
+               printf("stdin: %s", nl);
+               free(nl);
+       }
+}
+*/
diff --git a/get_next_line_bonus.h b/get_next_line_bonus.h
new file mode 100644 (file)
index 0000000..ac33fb4
--- /dev/null
@@ -0,0 +1,48 @@
+/* ************************************************************************** */
+/*                                                                            */
+/*                                                        :::      ::::::::   */
+/*   get_next_line.h                                    :+:      :+:    :+:   */
+/*                                                    +:+ +:+         +:+     */
+/*   By: agilliar <agilliar@student.42mulhouse.fr>  +#+  +:+       +#+        */
+/*                                                +#+#+#+#+#+   +#+           */
+/*   Created: 2025/11/01 10:38:19 by agilliar          #+#    #+#             */
+/*   Updated: 2025/11/06 17:20:44 by agilliar         ###   ########.fr       */
+/*                                                                            */
+/* ************************************************************************** */
+
+#ifndef GET_NEXT_LINE_H
+# define GET_NEXT_LINE_H
+
+# include <stddef.h>
+
+# ifndef BUFFER_SIZE
+#  define BUFFER_SIZE 256
+# endif
+
+# ifndef GNL_MAX_FD
+#  define GNL_MAX_FD 256
+# endif
+
+typedef struct s_buf
+{
+       size_t  len;
+       size_t  capacity;
+       char    *buf;
+}      t_buf;
+
+typedef struct s_readbuf
+{
+       size_t  written;
+       int             fd;
+       char    buf[BUFFER_SIZE];
+}      t_readbuf;
+
+typedef struct s_readbufs
+{
+       size_t          used;
+       t_readbuf       bufs[GNL_MAX_FD];
+}      t_readbufs;
+
+char   *get_next_line(int fd);
+
+#endif
diff --git a/get_next_line_utils_bonus.c b/get_next_line_utils_bonus.c
new file mode 100644 (file)
index 0000000..7e986cc
--- /dev/null
@@ -0,0 +1,101 @@
+/* ************************************************************************** */
+/*                                                                            */
+/*                                                        :::      ::::::::   */
+/*   get_next_line_utils.c                              :+:      :+:    :+:   */
+/*                                                    +:+ +:+         +:+     */
+/*   By: agilliar <marvin@42.fr>                    +#+  +:+       +#+        */
+/*                                                +#+#+#+#+#+   +#+           */
+/*   Created: 2025/11/06 17:56:20 by agilliar          #+#    #+#             */
+/*   Updated: 2025/11/06 17:58:50 by agilliar         ###   ########.fr       */
+/*                                                                            */
+/* ************************************************************************** */
+
+#include <stdbool.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "get_next_line.h"
+
+t_readbuf      *buffers_get(t_readbufs *bufs, int fd)
+{
+       size_t  i;
+
+       i = 0;
+       while (i < bufs->used && bufs->bufs[i].fd != fd)
+               i++;
+       if (i == GNL_MAX_FD)
+               return (NULL);
+       if (i == bufs->used)
+       {
+               bufs->bufs[i].written = 0;
+               bufs->bufs[i].fd = fd;
+               bufs->used++;
+       }
+       return (&bufs->bufs[i]);
+}
+
+void   buffers_remove(t_readbufs *bufs, int fd)
+{
+       size_t  i;
+
+       i = 0;
+       while (i < bufs->used && bufs->bufs[i].fd != fd)
+               i++;
+       if (i == GNL_MAX_FD)
+               return ;
+       bufs->bufs[i] = bufs->bufs[--bufs->used];
+}
+
+bool   readbuf_read(t_readbuf *buf)
+{
+       int     n;
+
+       if (buf->written != 0)
+               return (true);
+       n = read(buf->fd, &buf->buf, BUFFER_SIZE);
+       if (n < 0)
+               return (false);
+       buf->written = n;
+       return (true);
+}
+
+void   *ft_memcpy(void *dest, const void *src, size_t n)
+{
+       size_t  i;
+
+       i = 0;
+       while (i < n)
+       {
+               ((unsigned char *)dest)[i] = ((unsigned char *)src)[i];
+               i++;
+       }
+       return (dest);
+}
+
+/*
+       frees its own resources on failure
+*/
+void   buffer_pushchar(t_buf *buf, char c)
+{
+       size_t  new_capacity;
+       char    *new_buf;
+
+       if (buf->len + 1 > buf->capacity)
+       {
+               new_capacity = buf->len + 1;
+               if (new_capacity < BUFFER_SIZE + buf->capacity * 2)
+                       new_capacity = BUFFER_SIZE + buf->capacity * 2;
+               new_buf = malloc(new_capacity);
+               if (!new_buf)
+               {
+                       free(buf->buf);
+                       buf->buf = NULL;
+                       return ;
+               }
+               ft_memcpy(new_buf, buf->buf, buf->len);
+               free(buf->buf);
+               buf->buf = new_buf;
+               buf->capacity = new_capacity;
+       }
+       buf->buf[buf->len++] = c;
+}