tgrekov-pipex
HIVE pipex May 2024
Loading...
Searching...
No Matches
get_next_line_bonus.c
Go to the documentation of this file.
1/* ************************************************************************** */
2/* */
3/* ::: :::::::: */
4/* get_next_line_bonus.c :+: :+: :+: */
5/* +:+ +:+ +:+ */
6/* By: tgrekov <tgrekov@student.hive.fi> +#+ +:+ +#+ */
7/* +#+#+#+#+#+ +#+ */
8/* Created: 2023/10/28 02:23:33 by tgrekov #+# #+# */
9/* Updated: 2024/04/22 05:42:40 by tgrekov ### ########.fr */
10/* */
11/* ************************************************************************** */
12
20#include "libft.h"
21#include "get_next_line_bonus.h"
22
33static char *consume_and_resize(char **s1, size_t len)
34{
35 size_t new_s1_len;
36 char *new_s1;
37 char *s2;
38
39 s2 = malloc(len + 1);
40 if (!s2)
41 return (0);
42 ft_memcpy(s2, *s1, len);
43 s2[len] = '\0';
44 new_s1_len = ft_strlen(*s1 + len);
45 new_s1 = 0;
46 if (new_s1_len)
47 {
48 new_s1 = malloc(new_s1_len + 1);
49 if (!new_s1)
50 {
51 free(s2);
52 return (0);
53 }
54 ft_memcpy(new_s1, *s1 + len, new_s1_len + 1);
55 }
56 free(*s1);
57 *s1 = new_s1;
58 return (s2);
59}
60
70static size_t find_line_end(char *s, size_t *len)
71{
72 *len = 0;
73 if (!s)
74 return (0);
75 while (s[*len])
76 {
77 if (s[(*len)++] == '\n')
78 return (*len);
79 }
80 return (*len = 0);
81}
82
95static size_t fill_line_buf(int fd, char **line_buf, size_t *first_line_len)
96{
97 char read_buf[BUFFER_SIZE + 1];
98 ssize_t read_len;
99 char *old;
100
101 read_len = BUFFER_SIZE;
102 while (!find_line_end(*line_buf, first_line_len) && read_len == BUFFER_SIZE)
103 {
104 read_len = read(fd, read_buf, BUFFER_SIZE);
105 if (read_len < 0)
106 return (*first_line_len = 0);
107 read_buf[read_len] = '\0';
108 if (!*line_buf)
109 *line_buf = ft_strdup(read_buf);
110 else
111 {
112 old = *line_buf;
113 *line_buf = ft_strjoin(*line_buf, read_buf);
114 free(old);
115 }
116 if (!*line_buf)
117 return (*first_line_len = 0);
118 }
119 if (read_len != BUFFER_SIZE && !*first_line_len)
120 *first_line_len = ft_strlen(*line_buf);
121 return (*first_line_len);
122}
123
132char *get_next_line(int fd)
133{
134 static char *line_buf[MAX_FD + 1] = {0};
135 size_t first_line_len;
136 char *out;
137
138 if (fd < 0 || fd > MAX_FD || BUFFER_SIZE < 1)
139 return (0);
140 fill_line_buf(fd, line_buf + fd, &first_line_len);
141 if (!first_line_len)
142 {
143 if (line_buf[fd])
144 free(line_buf[fd]);
145 return (line_buf[fd] = 0);
146 }
147 out = consume_and_resize(line_buf + fd, first_line_len);
148 if (!out)
149 {
150 free(line_buf[fd]);
151 line_buf[fd] = 0;
152 }
153 return (out);
154}
#define BUFFER_SIZE
Set default BUFFER_SIZE if it is not defined at compile time.
#define MAX_FD
Max open file descriptors per process.
void * ft_memcpy(void *dst, const void *src, size_t n)
Copies n bytes from byte string src to byte string dst.
Definition ft_memcpy.c:36
char * ft_strdup(const char *s1)
Allocates memory for, copies to, and returns a duplicate of s1.
Definition ft_strdup.c:28
char * ft_strjoin(char const *s1, char const *s2)
Allocates enough space for and appends string s2 to string s1 and returns the new string.
Definition ft_strjoin.c:30
size_t ft_strlen(const char *str)
Get length of str.
Definition ft_strlen.c:28
static char * consume_and_resize(char **s1, size_t len)
Allocate and return a new string of size len + 1 containing len characters from string pointed to by ...
static size_t find_line_end(char *s, size_t *len)
Find the first newline in string s and write its index + 1 into len.
char * get_next_line(int fd)
Return the next segment of text ending in a newline or EOF from file descriptor fd.
static size_t fill_line_buf(int fd, char **line_buf, size_t *first_line_len)
Reading from fd, fill and / or allocate line buffer at line_buf, set first_line_len to the length of ...