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