diff --git a/Makefile b/Makefile index 9e47358..f0abf7c 100644 --- a/Makefile +++ b/Makefile @@ -19,6 +19,7 @@ ifeq ($(CFLAGS),) endif export CFLAGS srcs = \ + src/buffer/buffer.c \ src/env/env.c \ src/env/env_convert.c \ src/env/env_manip.c \ diff --git a/src/buffer/buffer.c b/src/buffer/buffer.c new file mode 100644 index 0000000..f2f1677 --- /dev/null +++ b/src/buffer/buffer.c @@ -0,0 +1,104 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* buffer.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: kcolin +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/12/12 12:39:58 by kcolin #+# #+# */ +/* Updated: 2025/02/14 18:19:49 by khais ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "buffer.h" +#include "libft.h" +#include + +t_buffer *ft_buffer_new(void) +{ + t_buffer *out; + + out = ft_calloc(1, sizeof(t_buffer)); + if (out == NULL) + return (NULL); + out->length = 0; + out->capacity = SL_BUFFER_SIZE; + out->buffer = ft_calloc(SL_BUFFER_SIZE, sizeof(char)); + if (out->buffer == NULL) + { + free(out); + return (NULL); + } + return (out); +} + +void ft_buffer_free(t_buffer *buffer) +{ + if (buffer != NULL) + free(buffer->buffer); + free(buffer); +} + +/* +** grows the buffer such that the new capacity is 1.5 times the old. +** +** in case of error, free all memory and return null. +** else return buffer. +*/ +t_buffer *ft_buffer_grow(t_buffer *buffer) +{ + char *newbuffer; + + if (buffer == NULL) + return (NULL); + newbuffer = ft_calloc(buffer->capacity * 1.5, sizeof(char)); + if (newbuffer == NULL) + { + ft_buffer_free(buffer); + return (NULL); + } + ft_memcpy(newbuffer, buffer->buffer, buffer->length); + free(buffer->buffer); + buffer->buffer = newbuffer; + buffer->capacity *= 1.5; + return (buffer); +} + +t_buffer *ft_buffer_pushchar(t_buffer *buffer, char c) +{ + if (buffer == NULL) + return (NULL); + if (buffer->length + 1 < buffer->capacity) + { + buffer->buffer[buffer->length] = c; + buffer->length++; + } + else + { + buffer = ft_buffer_grow(buffer); + buffer = ft_buffer_pushchar(buffer, c); + } + return (buffer); +} + +/* +** push buf to the end of buffer, growing buffer if needed. +** +** the number of bytes to copy to buffer is n. +** returns buffer. +** in case of error, all memory is freed and null is returned. +*/ +t_buffer *ft_buffer_push_buf(t_buffer *buffer, char *buf, size_t n) +{ + if (buffer == NULL) + return (NULL); + while (buffer->length + n > buffer->capacity) + { + buffer = ft_buffer_grow(buffer); + if (buffer == NULL) + return (NULL); + } + ft_memcpy(buffer->buffer + buffer->length, buf, n); + buffer->length += n; + return (buffer); +} diff --git a/src/buffer/buffer.h b/src/buffer/buffer.h new file mode 100644 index 0000000..e4ce6bc --- /dev/null +++ b/src/buffer/buffer.h @@ -0,0 +1,45 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* buffer.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: kcolin +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/12/12 12:35:28 by kcolin #+# #+# */ +/* Updated: 2025/02/14 18:20:08 by khais ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef BUFFER_H +# define BUFFER_H + +# include + +typedef struct s_buffer +{ + size_t length; + size_t capacity; + char *buffer; +} t_buffer; + +# ifndef SL_BUFFER_SIZE +# define SL_BUFFER_SIZE 64 +# endif +# if SL_BUFFER_SIZE <= 0 +# error "SL_BUFFER_SIZE must be at least 1" +# endif + +# ifndef SL_READ_BUFFER_SIZE +# define SL_READ_BUFFER_SIZE 64 +# endif +# if SL_READ_BUFFER_SIZE <= 0 +# error "SL_READ_BUFFER_SIZE must be at least 1" +# endif + +// implemented in buffer.c +t_buffer *ft_buffer_new(void); +void ft_buffer_free(t_buffer *buffer); +t_buffer *ft_buffer_pushchar(t_buffer *buffer, char c); +t_buffer *ft_buffer_push_buf(t_buffer *buffer, char *buf, size_t n); + +#endif