-
Notifications
You must be signed in to change notification settings - Fork 1
/
get_next_line.c
124 lines (114 loc) · 3.41 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
122
123
124
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* get_next_line.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: cvidon <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2022/08/15 18:00:00 by cvidon #+# #+# */
/* Updated: 2022/08/15 18:00:00 by cvidon ### ########.fr */
/* */
/* ************************************************************************** */
#include "get_next_line.h"
/*
** @brief Extract the first line from the string pointed to by temp and
** shift temp address to the beginning of the next line or NULL if
** the end of the string is reached.
**
** @param[in] temp a static pointer to the first line.
** @param[out] temp a static pointer to the next line: temp + ft_strlen(line)
** @return The first line that temp was pointing to or NULL.
*/
static char *ft_next(char **temp)
{
char *line;
char *ptr;
ptr = *temp;
while (*ptr && *ptr != '\n')
++ptr;
ptr += (*ptr == '\n');
line = ft_substr (*temp, 0, (size_t)(ptr - *temp));
if (!line)
{
free (*temp);
return (NULL);
}
ptr = ft_substr (ptr, 0, ft_strlen (ptr));
free (*temp);
*temp = ptr;
return (line);
}
/*
** @brief Read the content of the file pointed to by fd.
**
** @param[in] fd a file descriptor pointing to a file.
** @param[in] temp a static pointer to the content read.
** @return A pointer to:
** - a line, if BUFFER_SIZE is smaller than a line.
** - a line + more, if BUFFER_SIZE is bigger than a line
** or if it is not the first get_next_line call for this fd.
** - NULL if there is nothing left to be read on fd.
*/
static char *ft_read(char *temp, int fd, char *buf)
{
ssize_t r;
r = 1;
while (r && !ft_strchr (temp, '\n'))
{
r = read (fd, buf, BUFFER_SIZE);
if (r == -1)
{
free (buf);
free (temp);
return (NULL);
}
buf[r] = 0;
temp = ft_strjoin_free_s1 (temp, buf);
if (!temp)
{
free (buf);
return (NULL);
}
}
free (buf);
return (temp);
}
/*
** @brief Get the next line of text available on a file descriptor.
**
** Calling get_next_line in a loop will allow us to read the text available on
** the file descriptor one line at a time until the end of it.
**
** A line is defined as a NUL or LF terminated string.
**
** @param[in] fd the file descriptor.
** @param[out] temp a static pointer to the next line to be read or NULL.
** @return The first line to be read from temp.
*/
char *get_next_line(int fd)
{
static char *temp[OPEN_MAX];
char *buf;
if (fd == -1 || BUFFER_SIZE < 1)
return (NULL);
if (!temp[fd])
temp[fd] = ft_strdup("");
if (!temp[fd])
return (NULL);
buf = malloc (sizeof (*buf) * (BUFFER_SIZE + 1));
if (!buf)
{
free (temp[fd]);
return (NULL);
}
temp[fd] = ft_read (temp[fd], fd, buf);
if (!temp[fd])
return (NULL);
if (!*temp[fd])
{
free (temp[fd]);
temp[fd] = NULL;
return (NULL);
}
return (ft_next(&temp[fd]));
}