narnaud
3 years ago
7 changed files with 482 additions and 0 deletions
Binary file not shown.
@ -0,0 +1,113 @@ |
|||
/* ************************************************************************** */ |
|||
/* */ |
|||
/* ::: :::::::: */ |
|||
/* get_next_line.c :+: :+: :+: */ |
|||
/* +:+ +:+ +:+ */ |
|||
/* By: narnaud <narnaud@student.42.fr> +#+ +:+ +#+ */ |
|||
/* +#+#+#+#+#+ +#+ */ |
|||
/* 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); |
|||
} |
@ -0,0 +1,46 @@ |
|||
/* ************************************************************************** */ |
|||
/* */ |
|||
/* ::: :::::::: */ |
|||
/* get_next_line.h :+: :+: :+: */ |
|||
/* +:+ +:+ +:+ */ |
|||
/* By: narnaud <narnaud@student.42.fr> +#+ +:+ +#+ */ |
|||
/* +#+#+#+#+#+ +#+ */ |
|||
/* 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 <stdlib.h> |
|||
# include <unistd.h> |
|||
|
|||
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 |
@ -0,0 +1,145 @@ |
|||
/* ************************************************************************** */ |
|||
/* */ |
|||
/* ::: :::::::: */ |
|||
/* get_next_line_bonus.c :+: :+: :+: */ |
|||
/* +:+ +:+ +:+ */ |
|||
/* By: narnaud <narnaud@student.42.fr> +#+ +:+ +#+ */ |
|||
/* +#+#+#+#+#+ +#+ */ |
|||
/* 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); |
|||
} |
@ -0,0 +1,48 @@ |
|||
/* ************************************************************************** */ |
|||
/* */ |
|||
/* ::: :::::::: */ |
|||
/* get_next_line_bonus.h :+: :+: :+: */ |
|||
/* +:+ +:+ +:+ */ |
|||
/* By: narnaud <narnaud@student.42.fr> +#+ +:+ +#+ */ |
|||
/* +#+#+#+#+#+ +#+ */ |
|||
/* 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 <stdlib.h> |
|||
# include <unistd.h> |
|||
|
|||
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 |
@ -0,0 +1,65 @@ |
|||
/* ************************************************************************** */ |
|||
/* */ |
|||
/* ::: :::::::: */ |
|||
/* get_next_line_utils.c :+: :+: :+: */ |
|||
/* +:+ +:+ +:+ */ |
|||
/* By: narnaud <narnaud@student.42.fr> +#+ +:+ +#+ */ |
|||
/* +#+#+#+#+#+ +#+ */ |
|||
/* 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; |
|||
} |
@ -0,0 +1,65 @@ |
|||
/* ************************************************************************** */ |
|||
/* */ |
|||
/* ::: :::::::: */ |
|||
/* get_next_line_utils_bonus.c :+: :+: :+: */ |
|||
/* +:+ +:+ +:+ */ |
|||
/* By: narnaud <narnaud@student.42.fr> +#+ +:+ +#+ */ |
|||
/* +#+#+#+#+#+ +#+ */ |
|||
/* 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; |
|||
} |
Loading…
Reference in new issue