-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathget_next_line.c
165 lines (154 loc) · 4.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
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
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* get_next_line.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: yfurutat <[email protected]> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2022/12/30 20:07:31 by yuske #+# #+# */
/* Updated: 2023/01/20 20:28:11 by yfurutat ### ########.fr */
/* */
/* ************************************************************************** */
#include "get_next_line.h"
static void id_initializer(t_id *id);
static char *read_and_save(int fd, char *save, t_id *id);
static char *line_arranger(char *save, t_id *id);
static char *save_the_rest(char *save, t_id *id);
//13L
/**
* @brief Get the lines from fd by the BUFFER_SIZE,
* and arrange them with '\n' if needed.
*
* @param fd : file descriptor number from which to read lines.
* @return char* : line created through line_arranger().
* @note you might need to use open() and close() in main().
*/
char *get_next_line(int fd)
{
static char *save;
char *line_to_print;
t_id id;
if (fd < 0 || BUFFER_SIZE <= 0)
return (NULL);
id_initializer(&id);
save = read_and_save(fd, save, &id);
if (!save)
return (NULL);
line_to_print = line_arranger(save, &id);
save = save_the_rest(save, &id);
return (line_to_print);
}
/**
* @brief initialize all the elements in the struct.
*
* @param id the struct contains index to make funcs more concise & go easier.
*/
static void id_initializer(t_id *id)
{
id->terminal = '\0';
id->rd_len = 0;
id->len = 0;
id->i = 0;
}
//22L
/**
* @brief read lines from the fd by the BUFFER_SIZE,
* and put them into *buf, before copying them into save.
* if any lines remain in *save, put them before the new lines
* into save and combine them altogether.
*
* @param fd file descriptor given through the input of g_n_l()
* @param save if a line remains after the last process,
* it is carried over in this array.
* @param id set of index, including rd_len
* @return char*
*/
static char *read_and_save(int fd, char *save, t_id *id)
{
char *buf;
buf = (char *)malloc(sizeof(char) * BUFFER_SIZE + 1UL);
if (!buf)
return (NULL);
id->rd_len = 1;
while (1)
{
id->rd_len = read(fd, buf, BUFFER_SIZE);
if (id->rd_len <= 0)
break ;
buf[id->rd_len] = '\0';
save = ft_strjoin(save, buf);
if (save == NULL || ft_strchr(save, '\n') != NULL)
break ;
}
free(buf);
if (id->rd_len == -1)
return (NULL);
else if (ft_strchr(save, '\n') != NULL)
id->terminal = '\n';
return (save);
}
//21L
/**
* @brief create the actual line to output, out of *save.
*
* @param save array saved in the previous func.
* @param id set of index, including len and i.
* @return char* line created through this func,
* which will be returned in the end of g_n_l(), too.
*/
static char *line_arranger(char *save, t_id *id)
{
char *line;
id->i = 0;
if (save[id->i] == '\0' || save == NULL)
return (NULL);
id->len = 0;
while (save[id->len] != id->terminal)
id->len++;
if (id->terminal == '\n')
line = (char *)malloc(sizeof(char) * (id->len + 2));
else
line = (char *)malloc(sizeof(char) * (id->len + 1));
if (line == NULL)
free(save);
else
{
while (id->i < id->len + 1)
{
line[id->i] = save[id->i];
id->i += 1;
}
if (id->terminal == '\n')
line[id->i] = '\0';
}
return (line);
}
//17L
/**
* @brief if the line saved in *save contains any '\n',
* this func keep the rest after creating the line
* in the previous func.
* @param save array saved and carried over.
* @param id set of index including len and i.
* @return char* the rest of the lines saved
* after creating the line to output.
*/
static char *save_the_rest(char *save, t_id *id)
{
char *for_next;
for_next = NULL;
if (save && id->terminal == '\n')
{
for_next = (char *)malloc(ft_strlen(save) - id->len + 1);
if (for_next)
{
id->len++;
id->i = 0;
while (save[id->len] != '\0')
for_next[id->i++] = save[id->len++];
for_next[id->i] = '\0';
}
}
free(save);
return (for_next);
}