From: = <=> Date: Thu, 6 Nov 2025 17:05:40 +0000 (+0100) Subject: bonus X-Git-Url: https://git.uwuaxy.net/?a=commitdiff_plain;h=0c202a8a26dcf3b5a95139a2a88d9472145313ff;p=axy%2Fft%2Fget_next_line.git bonus --- diff --git a/get_next_line_bonus.c b/get_next_line_bonus.c new file mode 100644 index 0000000..964cfb0 --- /dev/null +++ b/get_next_line_bonus.c @@ -0,0 +1,116 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* get_next_line.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: agilliar +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/11/01 10:55:35 by agilliar #+# #+# */ +/* Updated: 2025/11/06 18:00:50 by agilliar ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include +#include + +#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 +#include + +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 index 0000000..ac33fb4 --- /dev/null +++ b/get_next_line_bonus.h @@ -0,0 +1,48 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* get_next_line.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: agilliar +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* 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 + +# 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 index 0000000..7e986cc --- /dev/null +++ b/get_next_line_utils_bonus.c @@ -0,0 +1,101 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* get_next_line_utils.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: agilliar +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/11/06 17:56:20 by agilliar #+# #+# */ +/* Updated: 2025/11/06 17:58:50 by agilliar ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include +#include +#include + +#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; +}