Project de l'école 42 : Get_next_line
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

113 lines
2.8 KiB

/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* 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);
}