-
Notifications
You must be signed in to change notification settings - Fork 0
/
get_next_line.c
169 lines (158 loc) · 4.64 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
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* get_next_line.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: jschott <jschott@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2023/06/20 11:32:02 by jschott #+# #+# */
/* Updated: 2024/08/08 10:41:59 by jschott ### ########.fr */
/* */
/* ************************************************************************** */
#include "get_next_line.h"
/**
* Shortens a string by removing the content up to and including the first newline character.
*
* @param line The original string to be shortened.
* @return A new string that starts after the first newline in `line`, or NULL under certain conditions.
*/
char *shorten(char *line)
{
char *rest;
int rest_len;
rest = NULL;
if (!ft_strchr(line, '\n') || ft_strlen(line) == 1)
{
free (line);
return (NULL);
}
if (0 == ft_strchr(line, '\n') - line - ft_strlen(line) + 1)
{
free (line);
return (NULL);
}
rest_len = ft_strlen(ft_strchr(line, '\n'));
rest = (char *) malloc (rest_len + 1);
if (!rest)
return (NULL);
ft_strlcpy(rest, ft_strchr(line, '\n') + 1, rest_len);
free (line);
return (rest);
}
/**
* Extracts a line from a string, including the newline character.
*
* @param line The original string from which to extract the line.
* @return A new string containing the extracted line, or NULL if memory allocation fails.
*/
char *extract(char *line)
{
char *result;
result = NULL;
if (!ft_strchr(line, '\n') || (ft_strlen(line) == 1 && BUFFER_SIZE > 1))
{
result = (char *) malloc (ft_strlen(line) + 1);
if (!result)
return (NULL);
ft_strlcpy(result, line, ft_strlen(line) + 1);
}
else
{
result = (char *) malloc (ft_strchr(line, '\n') - line + 2);
if (!result)
return (NULL);
ft_strlcpy(result, line, ft_strchr(line, '\n') - line + 2);
}
return (result);
}
/**
* Helper function to append buffer content to a line until a newline is found.
* returns the updated line.
*
* @param fd The file descriptor from which to read.
* @param r_len Pointer to an integer that stores the read length.
* @param line The initial line to which buffer content is appended.
* @param buffer The buffer used for reading from `fd`.
* @return The updated line after appending buffer content, or NULL if memory allocation fails.
*/
char *al_helper(int fd, int *r_len, char *line, char *buffer)
{
char *new_line;
if (!line)
{
line = (char *) malloc (1);
if (!line)
return (NULL);
line[0] = '\0';
}
while ((*r_len) > 0)
{
buffer[(*r_len)] = '\0';
new_line = ft_strjoin(line, buffer);
free (line);
if (ft_strchr(new_line, '\n'))
break ;
line = new_line;
(*r_len) = read(fd, buffer, BUFFER_SIZE);
}
return (new_line);
}
/**
* Reads from a file descriptor and appends the content to a line until a newline is found.
*
* @param fd The file descriptor from which to read.
* @param r_len Pointer to an integer that stores the read length.
* @param line The initial line to which the read content is appended.
* @return The updated line after reading and appending content, or NULL in case of errors.
*/
char *add_line(int fd, int *r_len, char *line)
{
char *buffer;
char *new_line;
new_line = 0;
buffer = (char *) malloc(BUFFER_SIZE + 1);
if (!buffer)
return (NULL);
(*r_len) = read(fd, buffer, BUFFER_SIZE);
if ((*r_len) == 0)
new_line = line;
else if ((*r_len) > 0)
new_line = al_helper(fd, r_len, line, buffer);
if ((*r_len) < 0)
{
free (line);
free (new_line);
free (buffer);
return (NULL);
}
free(buffer);
return (new_line);
}
/**
* Retrieves the next line from a file descriptor, including the newline character.
*
* @param fd The file descriptor from which to read.
* @return The next line from the file descriptor, or NULL if no more lines are available or in case of errors.
*/
char *get_next_line(int fd)
{
static char *line;
int *r_len;
int read_len;
char *result;
result = NULL;
if (fd < 0 || BUFFER_SIZE <= 0)
return (NULL);
r_len = &read_len;
read_len = 1;
if (!line || !ft_strchr(line, '\n'))
line = add_line(fd, r_len, line);
if (line && read_len >= 0)
{
result = extract(line);
line = shorten(line);
}
else if (read_len < 0)
free (line);
return (result);
}