-
Notifications
You must be signed in to change notification settings - Fork 0
/
get_next_line.c
121 lines (111 loc) · 3.04 KB
/
get_next_line.c
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
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* get_next_line.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: yochered <[email protected]> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2018/11/03 10:59:02 by yochered #+# #+# */
/* Updated: 2018/12/14 10:04:53 by yochered ### ########.fr */
/* */
/* ************************************************************************** */
#include <libft.h>
#include <unistd.h>
#include <stdlib.h>
static char *get_line(char *src, t_gnl *gnl, int size)
{
char *src_tmp;
char *res;
char *res_tmp;
CHECK((res = ft_strnew((size_t)(size + gnl->r_size))));
res_tmp = res;
src_tmp = src;
while (size--)
*res_tmp++ = *src_tmp++;
free(src);
while (gnl->buf[gnl->i] != '\n' && gnl->i < gnl->r_size)
*res_tmp++ = gnl->buf[gnl->i++];
return (res);
}
static char *read_file(char *res, t_gnl *gnl)
{
while ((gnl->r_size = (int)read(gnl->fd, gnl->buf, BUFF_SIZE)))
{
gnl->i = 0;
CHECK((res = get_line(res, gnl, (int)ft_strlen(res))));
if (gnl->i < gnl->r_size)
break ;
}
return (res);
}
static t_gnl *del_create_node(t_gnl *gnl, int fd)
{
t_gnl *node;
if (fd == -1)
{
if (gnl->prev)
gnl->prev->next = gnl->next;
if (gnl->next)
gnl->next->prev = gnl->prev;
free(gnl);
return (NULL);
}
CHECK((node = (t_gnl *)malloc(sizeof(t_gnl))));
node->fd = fd;
node->i = 0;
node->r_size = 0;
node->next = NULL;
node->prev = gnl ? gnl : NULL;
return (node);
}
static t_gnl *find_fd(t_gnl *search_fd, int fd)
{
t_gnl *tmp;
t_gnl *cur;
cur = search_fd;
while (cur && cur->fd != fd)
{
tmp = cur;
cur = cur->prev;
}
while (!cur && search_fd && search_fd->fd != fd)
{
tmp = search_fd;
search_fd = search_fd->next;
}
search_fd = cur ? cur : search_fd;
if (!search_fd)
{
CHECK((tmp->next = del_create_node(tmp, fd)));
return (tmp->next);
}
if (read(fd, 0, 0) < 0)
del_create_node(search_fd, -1);
return (search_fd);
}
int get_next_line(const int fd, char **line)
{
char *res;
static t_gnl *gnl;
if (!line || fd < 0 || (!gnl && !(gnl = del_create_node(NULL, fd))))
return (-1);
if (!(gnl = find_fd(gnl, fd)) || read(gnl->fd, gnl->buf, 0) < 0
|| !(res = ft_strnew(0)))
return (-1);
if (gnl->i < gnl->r_size)
{
gnl->i++;
if (!(res = get_line(res, gnl, 0)))
return (-1);
}
if (gnl->i >= gnl->r_size && !(res = read_file(res, gnl)))
return (-1);
if (!gnl->r_size && !(ft_strlen(res)))
{
*line = NULL;
free(res);
return (0);
}
*line = res;
return (1);
}