-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathget_next_line_utils.c
More file actions
93 lines (84 loc) · 2.4 KB
/
get_next_line_utils.c
File metadata and controls
93 lines (84 loc) · 2.4 KB
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
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* get_next_line_utils.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: dlesieur <dlesieur@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/10/21 00:55:35 by dlesieur #+# #+# */
/* Updated: 2025/10/21 02:56:49 by dlesieur ### ########.fr */
/* */
/* ************************************************************************** */
#include "get_next_line.h"
t_state ensure_cap(char **line, size_t *cap, size_t need)
{
void *tmp;
size_t new_cap;
if (*cap >= need)
return (ST_OK);
if (*cap)
new_cap = *cap;
else
new_cap = DFLT_CAP;
while (new_cap <= need)
new_cap *= 2;
tmp = ft_realloc(*line, *cap, new_cap);
if (!tmp)
return (ST_ERR_ALLOC);
*cap = new_cap;
*line = (char *)tmp;
return (ST_OK);
}
t_state append_from_buffer(t_file *scan, t_dynstr *line)
{
char *nl;
size_t chunk;
size_t avail;
avail = (size_t)(scan->end - scan->cur);
nl = ft_strnchr(scan->cur, '\n', avail);
if (nl)
chunk = (size_t)(nl - scan->cur + 1);
else
chunk = avail;
if (ensure_cap(&line->buf, &line->cap, line->size + chunk + 1)
== ST_ERR_ALLOC)
return (ST_ERR_ALLOC);
ft_memmove(line->buf + line->size, scan->cur, chunk);
line->size += chunk;
line->buf[line->size] = '\0';
scan->cur += chunk;
return (nl != NULL);
}
t_state refill(t_file *scan, int fd)
{
ssize_t readn;
readn = read(fd, scan, BUFFER_SIZE);
if (readn <= 0)
return ((int)readn);
scan->cur = scan->buf;
scan->end = scan->buf + readn;
return (ST_FILLED);
}
t_state scan_nl(t_file *scan, t_dynstr *line, int fd)
{
t_state st;
while (ST_SCANNING)
{
if (scan->cur >= scan->end)
{
st = refill(scan, fd);
if (st == ST_FILE_NOT_FOUND)
return (ST_FILE_NOT_FOUND);
if (st == 0)
return (ST_EOF);
if (st != ST_FILLED)
return (st);
}
st = append_from_buffer(scan, line);
if (st == ST_ERR_ALLOC)
return (ST_ERR_ALLOC);
if (st)
break ;
}
return (ST_FOUND_NL);
}