-
Notifications
You must be signed in to change notification settings - Fork 0
/
get_next_line.c
159 lines (148 loc) · 4.08 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
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* get_next_line.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: rjobert <rjobert@student.42barcelo> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2023/05/31 13:52:49 by rjobert #+# #+# */
/* Updated: 2023/06/13 20:54:06 by rjobert ### ########.fr */
/* */
/* ************************************************************************** */
#include "get_next_line.h"
char *get_next_line(int fd)
{
char *line;
static t_list *byte_list;
line = NULL;
if (fd < 0 || BUFFER_SIZE <= 0 || read(fd, &line, 0) < 0)
{
free_chain(byte_list);
byte_list = NULL;
return (NULL);
}
load_chain_list(&byte_list, fd);
if (!byte_list)
return (NULL);
get_all_line(byte_list, &line);
if (line[0] == '\0' || !line)
{
free_chain(byte_list);
byte_list = NULL;
if (line)
free(line);
return (NULL);
}
clean_chain(&byte_list);
return (line);
}
/*we create a node and char *s inside of size BUFFER + 1 -> protect both malloc
read into it -> free node and its content if reading issue
then null terminate the content and return the node */
t_list *read_to_node(int fd, int *byte_read)
{
t_list *node;
node = malloc(sizeof(t_list));
if (!node)
return (NULL);
node->buff = malloc(BUFFER_SIZE + 1);
if (!node->buff)
{
free(node);
return (NULL);
}
*byte_read = read(fd, node->buff, BUFFER_SIZE);
if (*byte_read < 0)
{
free(node->buff);
free(node);
return (NULL);
}
node->buff[*byte_read] = '\0';
node->next = NULL;
return (node);
}
//we receive a list - if it is null : we add a node to it,
//which will be the first bytes to be read
//else we just build on previous nodes
//then as long as we have byte to read or that we don't find the \n character :
//we load nodes with full buffer to the chain
void load_chain_list(t_list **list, int fd)
{
t_list *node;
t_list *head;
int byte_read;
byte_read = 1;
if (!*list)
*list = read_to_node(fd, &byte_read);
if (*list == NULL)
return ;
head = *list;
while (byte_read > 0 && !ft_search_nl(*list))
{
node = read_to_node(fd, &byte_read);
if (!node)
{
free_chain(head);
*list = NULL;
return ;
}
(*list)->next = node;
*list = (*list)->next;
}
*list = head;
}
//we will load all of the linked list content (until null or \n) into line
//1 - measure and malloc - see function descrition in utils
//2 - copy by char by char from *buff and rolling the nodes into the line
//from the linked list
void get_all_line(t_list *byte_list, char **line)
{
int i;
int j;
i = 0;
if (!byte_list)
return ;
measure_n_create(&byte_list, line, 0);
if (!*line)
return ;
while (byte_list && *line)
{
j = 0;
while (byte_list->buff[j] && byte_list->buff[j] != '\n')
{
(*line)[i] = byte_list->buff[j];
i++;
j++;
}
if (byte_list->buff[j] == '\n')
(*line)[i] = byte_list->buff[j];
byte_list = byte_list->next;
}
}
// 1 - we will clean the list and the nodes
// 2 - we go to the last node -> clone it and incorporate
// only the charcetrs after the next line
// 3 - we will clean the entire chain and set it to the new node
// containing only the characters remaining efter the \n
// byte_list being a static var the next read() will build on top
void clean_chain(t_list **buff_list)
{
t_list *handover_node;
t_list *byte_list;
byte_list = *buff_list;
if (!byte_list)
return ;
while (byte_list && byte_list->next)
byte_list = byte_list->next;
handover_node = malloc(sizeof(t_list));
if (!handover_node)
{
free_chain(*buff_list);
return ;
}
handover_node->next = NULL;
ft_passover(byte_list, &handover_node, 0, 0);
free_chain(*buff_list);
*buff_list = handover_node;
}