diff --git a/en.subject.pdf b/en.subject.pdf new file mode 100644 index 0000000..485830c Binary files /dev/null and b/en.subject.pdf differ diff --git a/get_next_line.c b/get_next_line.c new file mode 100644 index 0000000..6c34434 --- /dev/null +++ b/get_next_line.c @@ -0,0 +1,113 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* get_next_line.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: narnaud +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2021/10/25 10:00:41 by narnaud #+# #+# */ +/* Updated: 2021/11/19 17:41:09 by narnaud ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "get_next_line.h" + +int close_buffer(t_buffer **buffers) +{ + t_buffer *buffer; + + buffer = *buffers; + free(buffer->content); + free(buffer); + *buffers = NULL; + return (1); +} + +static t_buffer *load_buffer(t_buffer **buffers) +{ + t_buffer *buffer; + + buffer = *buffers; + if (buffer) + return (buffer); + buffer = ft_calloc(1, sizeof(*buffer)); + buffer->content = (char *)ft_calloc(BUFFER_SIZE + 1, sizeof(char)); + buffer->pos = 0; + buffer->read_length = 0; + return (buffer); +} + +int parse_buffer(t_buffer *buffer, t_split **line) +{ + t_split *split; + + split = ft_lstlast(*line); + while (buffer->content[buffer->pos]) + { + if (buffer->pos >= buffer->read_length) + break ; + if (split->i == SPLIT_SIZE) + { + split = ft_new_split(ft_calloc(SPLIT_SIZE + 1, sizeof(char))); + ft_lstadd_back(line, split); + } + (split->content)[split->i] = buffer->content[buffer->pos]; + if (buffer->content[buffer->pos++] == '\n') + return (1); + (split->i)++; + } + buffer->pos = 0; + return (0); +} + +char *merge_splits(t_split **split) +{ + t_split *next; + char *ret; + size_t i; + size_t count; + + next = ft_lstlast(*split); + count = next->count; + ret = (char *)ft_calloc((count * SPLIT_SIZE) + 1, sizeof(char)); + i = 0; + while (split && *split) + { + next = (*split)->next; + (*split)->i = 0; + while ((*split)->content[(*split)->i]) + { + ret[i] = (*split)->content[(*split)->i]; + i++; + ((*split)->i)++; + } + free((*split)->content); + free(*split); + *split = next; + } + ret[i] = '\0'; + return (ret); +} + +char *get_next_line(int fd) +{ + static t_buffer *buffer; + t_split *line; + char *ret; + + buffer = load_buffer(&buffer); + if (read(fd, buffer->content, 0) < 0 && close_buffer(&buffer)) + return (NULL); + line = ft_new_split((char *)ft_calloc(SPLIT_SIZE + 1, sizeof(char))); + while (!parse_buffer(buffer, &line)) + { + buffer->read_length = read(fd, buffer->content, BUFFER_SIZE); + if (!buffer->read_length && close_buffer(&buffer)) + break ; + } + ret = merge_splits(&line); + if (*ret) + return (ret); + free(ret); + return (NULL); +} diff --git a/get_next_line.h b/get_next_line.h new file mode 100644 index 0000000..bbcd4fc --- /dev/null +++ b/get_next_line.h @@ -0,0 +1,46 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* get_next_line.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: narnaud +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2021/10/29 08:44:57 by narnaud #+# #+# */ +/* Updated: 2021/11/19 17:48:45 by narnaud ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef GET_NEXT_LINE_H +# define GET_NEXT_LINE_H + +# define SPLIT_SIZE 512 + +# include +# include + +typedef struct s_buffer +{ + char *content; + size_t pos; + size_t read_length; +} t_buffer; + +typedef struct s_line_split +{ + char *content; + size_t i; + size_t count; + struct s_line_split *next; +} t_split; + +int parse_buffer(t_buffer *buffer, t_split **line); +char *get_next_line(int fd); + +void *ft_calloc(size_t count, size_t size); +t_split *ft_new_split(char *content); +t_split *ft_lstlast(t_split *lst); +void ft_lstadd_back(t_split **alst, t_split *new); + +void ft_putstr_fd(char *s, int fd); + +#endif diff --git a/get_next_line_bonus.c b/get_next_line_bonus.c new file mode 100644 index 0000000..84fa6da --- /dev/null +++ b/get_next_line_bonus.c @@ -0,0 +1,145 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* get_next_line_bonus.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: narnaud +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2021/10/25 10:00:41 by narnaud #+# #+# */ +/* Updated: 2021/11/19 17:27:43 by narnaud ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "get_next_line_bonus.h" + +int close_buffer(t_buffer **buffers, int fd) +{ + t_buffer *buffer; + t_buffer *previous; + + buffer = *buffers; + previous = NULL; + while (buffer) + { + if (buffer->fd == fd) + { + if (previous && buffer->next) + previous->next = buffer->next; + else if (previous) + previous->next = NULL; + else if (buffer->next) + *buffers = buffer->next; + else + *buffers = NULL; + free(buffer->content); + free(buffer); + return (1); + } + previous = buffer; + buffer = buffer->next; + } + return (1); +} + +static t_buffer *load_buffer(t_buffer **buffers, int fd) +{ + t_buffer *previous; + t_buffer *buffer; + + buffer = *buffers; + previous = NULL; + while (buffer) + { + if (buffer->fd == fd) + return (buffer); + previous = buffer; + buffer = buffer->next; + } + buffer = ft_calloc(1, sizeof(*buffer)); + buffer->content = (char *)ft_calloc(BUFFER_SIZE + 1, sizeof(char)); + buffer->pos = 0; + buffer->read_length = 0; + buffer->fd = fd; + buffer->next = NULL; + if (previous) + previous->next = buffer; + else + *buffers = buffer; + return (buffer); +} + +int parse_buffer(t_buffer *buffer, t_split **line) +{ + t_split *split; + + split = ft_lstlast(*line); + while (buffer->content[buffer->pos]) + { + if (buffer->pos >= buffer->read_length) + break ; + if (split->i == SPLIT_SIZE) + { + split = ft_new_split(ft_calloc(SPLIT_SIZE + 1, sizeof(char))); + ft_lstadd_back(line, split); + } + (split->content)[split->i] = buffer->content[buffer->pos]; + if (buffer->content[buffer->pos++] == '\n') + return (1); + (split->i)++; + } + buffer->pos = 0; + return (0); +} + +char *merge_splits(t_split **split) +{ + t_split *next; + char *ret; + size_t i; + size_t count; + + next = ft_lstlast(*split); + count = next->count; + ret = (char *)ft_calloc((count * SPLIT_SIZE) + 1, sizeof(char)); + i = 0; + while (split && *split) + { + next = (*split)->next; + (*split)->i = 0; + while ((*split)->content[(*split)->i]) + { + ret[i] = (*split)->content[(*split)->i]; + i++; + ((*split)->i)++; + } + free((*split)->content); + free(*split); + *split = next; + } + ret[i] = '\0'; + return (ret); +} + +char *get_next_line(int fd) +{ + static t_buffer *buffers; + t_buffer *buffer; + t_split *line; + char *ret; + + buffer = load_buffer(&buffers, fd); + if (read(fd, buffer->content, 0) < 0 && close_buffer(&buffers, fd)) + return (NULL); + line = ft_new_split(ft_calloc(SPLIT_SIZE + 1, sizeof(char))); + while (!parse_buffer(buffer, &line)) + { + buffer->read_length = read(fd, buffer->content, BUFFER_SIZE); + if (buffer->read_length <= 0 && close_buffer(&buffers, fd)) + break ; + } + ret = merge_splits(&line); + if (*ret) + return (ret); + free(ret); + return (NULL); +} diff --git a/get_next_line_bonus.h b/get_next_line_bonus.h new file mode 100644 index 0000000..97478af --- /dev/null +++ b/get_next_line_bonus.h @@ -0,0 +1,48 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* get_next_line_bonus.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: narnaud +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2021/10/29 08:44:57 by narnaud #+# #+# */ +/* Updated: 2021/11/19 17:48:44 by narnaud ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef GET_NEXT_LINE_BONUS_H +# define GET_NEXT_LINE_BONUS_H + +# define SPLIT_SIZE 512 + +# include +# include + +typedef struct s_buffer +{ + char *content; + size_t pos; + size_t read_length; + int fd; + struct s_buffer *next; +} t_buffer; + +typedef struct s_line_split +{ + char *content; + size_t i; + size_t count; + struct s_line_split *next; +} t_split; + +int parse_buffer(t_buffer *buffer, t_split **line); +char *get_next_line(int fd); + +void *ft_calloc(size_t count, size_t size); +t_split *ft_new_split(void *content); +t_split *ft_lstlast(t_split *lst); +void ft_lstadd_back(t_split **alst, t_split *new); + +void ft_putstr_fd(char *s, int fd); + +#endif diff --git a/get_next_line_utils.c b/get_next_line_utils.c new file mode 100644 index 0000000..14be156 --- /dev/null +++ b/get_next_line_utils.c @@ -0,0 +1,65 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* get_next_line_utils.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: narnaud +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2021/10/29 08:54:42 by narnaud #+# #+# */ +/* Updated: 2021/11/17 18:06:57 by narnaud ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "get_next_line.h" + +void *ft_calloc(size_t count, size_t size) +{ + void *ret; + size_t i; + + i = 0; + ret = malloc(count * size); + if (ret) + while (i < (count * size)) + *(char *)(ret + i++) = 0; + return (ret); +} + +t_split *ft_lstlast(t_split *lst) +{ + if (!lst) + return (NULL); + while (lst->next) + lst = lst->next; + return (lst); +} + +t_split *ft_new_split(char *content) +{ + t_split *empty_lst; + + empty_lst = (t_split *)malloc(sizeof(*empty_lst)); + if (!empty_lst) + return (NULL); + empty_lst->content = content; + empty_lst->next = NULL; + empty_lst->i = 0; + empty_lst->count = 1; + return (empty_lst); +} + +void ft_lstadd_back(t_split **alst, t_split *new) +{ + t_split *i_cell; + + if (!alst || !new) + return ; + if (*alst) + { + i_cell = ft_lstlast(*alst); + i_cell->next = new; + new->count = i_cell->count + 1; + } + else + *alst = new; +} diff --git a/get_next_line_utils_bonus.c b/get_next_line_utils_bonus.c new file mode 100644 index 0000000..7b660da --- /dev/null +++ b/get_next_line_utils_bonus.c @@ -0,0 +1,65 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* get_next_line_utils_bonus.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: narnaud +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2021/10/29 08:54:42 by narnaud #+# #+# */ +/* Updated: 2021/11/19 13:24:25 by narnaud ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "get_next_line_bonus.h" + +void *ft_calloc(size_t count, size_t size) +{ + void *ret; + size_t i; + + i = 0; + ret = malloc(count * size); + if (ret) + while (i < (count * size)) + *(char *)(ret + i++) = 0; + return (ret); +} + +t_split *ft_lstlast(t_split *lst) +{ + if (!lst) + return (NULL); + while (lst->next) + lst = lst->next; + return (lst); +} + +t_split *ft_new_split(void *content) +{ + t_split *empty_lst; + + empty_lst = (t_split *)ft_calloc(1, sizeof(*empty_lst)); + if (!empty_lst) + return (NULL); + empty_lst->content = (char *)content; + empty_lst->next = NULL; + empty_lst->i = 0; + empty_lst->count = 1; + return (empty_lst); +} + +void ft_lstadd_back(t_split **alst, t_split *new) +{ + t_split *i_cell; + + if (!alst || !new) + return ; + if (*alst) + { + i_cell = ft_lstlast(*alst); + i_cell->next = new; + new->count = i_cell->count + 1; + } + else + *alst = new; +}