aboutsummaryrefslogtreecommitdiffstats
path: root/libft/src/get_next_line.c
blob: ae641250ae987893703d0f65b92310f7e1c4a86a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
/* ************************************************************************** */
/*                                                                            */
/*                                                        :::      ::::::::   */
/*   get_next_line.c                                    :+:      :+:    :+:   */
/*                                                    +:+ +:+         +:+     */
/*   By: rbousset <marvin@42.fr>                    +#+  +:+       +#+        */
/*                                                +#+#+#+#+#+   +#+           */
/*   Created: 2020/02/14 17:07:20 by rbousset          #+#    #+#             */
/*   Updated: 2020/02/14 17:07:20 by rbousset         ###   ########lyon.fr   */
/*                                                                            */
/* ************************************************************************** */

#include <libft.h>
#include <stdlib.h>
#include <stddef.h>
#include <stdint.h>
#include <unistd.h>

static char
	*ft_strjoin_gnl(char *s1, char *s2)
{
	size_t	i;
	size_t	j;
	char	*dst;
	size_t	size1;
	size_t	size2;

	i = -1;
	j = -1;
	size1 = ft_strlen_gnl(s1, 10);
	size2 = ft_strlen_gnl(s2, 10);
	if (!(dst = (char*)malloc((size1 + size2 + 1) * sizeof(char))))
		return (NULL);
	while (++i < size1)
		dst[i] = s1[i];
	while (++j < size2)
		dst[i + j] = s2[j];
	dst[i + j] = '\0';
	ft_memdel((void**)&s1);
	return (dst);
}

static int
	ft_read_gnl(int fd, char **line, t_gnl *curr)
{
	char	*buf;
	char	*end;
	int64_t	size;

	if (!(buf = malloc(BUFFER_SIZE + 1)))
		return (-1);
	*buf = 0;
	*line = ft_strjoin_gnl(*line, curr->rest);
	size = BUFFER_SIZE;
	while ((end = ft_strchr_gnl(buf, 10)) == NULL && size == BUFFER_SIZE)
	{
		*line = ft_strjoin_gnl(*line, buf);
		if ((size = read(fd, buf, BUFFER_SIZE)) == -1)
			ft_memdel((void**)&buf);
		if (size == -1)
			return (-1);
		buf[size] = 0;
	}
	*line = ft_strjoin_gnl(*line, buf);
	if (end)
		curr->rest = ft_swap_gnl(end + 1, curr->rest);
	ft_memdel((void**)&buf);
	if (!end)
		return (0);
	return (size);
}

int
	get_next_line(int fd, char **line)
{
	static t_gnl	*list;
	t_gnl			*curr;
	char			*end;
	int				size;

	if (fd < 0 || BUFFER_SIZE <= 0)
		return (-1);
	if (!(*line = (char *)malloc(1 * sizeof(char))))
		return (-1);
	**line = 0;
	curr = ft_find_fd(fd, &list);
	if (ft_strchr_gnl(curr->rest, 10) == NULL)
		size = ft_read_gnl(fd, line, curr);
	else
	{
		end = ft_strchr_gnl(curr->rest, 10);
		*line = ft_strjoin_gnl(*line, curr->rest);
		curr->rest = ft_swap_gnl(end + 1, curr->rest);
		size = 1;
	}
	if (size > 0)
		return (1);
	ft_free_gnl(fd, &list);
	return ((size == -1) ? -1 : 0);
}