/* ************************************************************************** */ /* */ /* ::: :::::::: */ /* get_next_line.c :+: :+: :+: */ /* +:+ +:+ +:+ */ /* By: bchanot +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2015/12/13 15:04:06 by bchanot #+# #+# */ /* Updated: 2018/04/17 11:47:45 by bchanot ### ########.fr */ /* */ /* ************************************************************************** */ #include "libft.h" #include static t_gnl *gnl_add(int fd) { t_gnl *tmp; if (!(tmp = (t_gnl *)ft_memalloc(sizeof(t_gnl)))) return (NULL); tmp->tmp = NULL; tmp->eof = 0; tmp->fd = fd; tmp->next = NULL; return (tmp); } static t_gnl *gnl_find_reader(t_gnl **list, int fd) { t_gnl *tmp; tmp = *list; while (tmp) { if (tmp->fd == fd) { if (!tmp->tmp && tmp->eof == 1) tmp->eof = 0; return (tmp); } tmp = tmp->next; } tmp = *list; if (!(*list)) return ((*list = gnl_add(fd))); while (tmp->next) tmp = tmp->next; return ((tmp->next = gnl_add(fd))); } static int gnl_check_already(t_gnl *rdr, char **line) { char *chr; if ((chr = ft_strdup(ft_strchr(rdr->tmp, '\n')))) { *line = ft_strndup(rdr->tmp, ft_strlen(rdr->tmp) - ft_strlen(chr)); ft_memdel((void **)&(rdr->tmp)); rdr->tmp = ft_strdup(chr + 1); ft_memdel((void **)&chr); return (1); } if (rdr->eof == 1 && (!rdr->tmp || !(*(rdr->tmp)))) return (0); if (rdr->eof == 1) { *line = ft_strdup(rdr->tmp); ft_memdel((void **)&(rdr->tmp)); return (0); } return (-1); } static int gnl_read(t_gnl *rdr, char **chr) { char *tmp; char c[BUFF_SIZE + 1]; int ret; tmp = NULL; ft_bzero(c, BUFF_SIZE + 1); while ((ret = read(rdr->fd, c, BUFF_SIZE))) { if (rdr->tmp) { tmp = ft_strnew(ft_strlen(rdr->tmp) + ft_strlen(c)); ft_memcpy(tmp, rdr->tmp, ft_strlen(rdr->tmp)); ft_memcpy(tmp + ft_strlen(rdr->tmp), c, ft_strlen(c)); ft_memdel((void **)&(rdr->tmp)); rdr->tmp = tmp; } else rdr->tmp = ft_strdup(c); ft_bzero(c, BUFF_SIZE + 1); if ((*chr = ft_strdup(ft_strchr(rdr->tmp, '\n')))) break ; } return (ret); } int get_next_line(const int fd, char **line) { static t_gnl *readers = NULL; t_gnl *rdr; char *chr; int ret; if (fd < 0 || !line || !(rdr = gnl_find_reader(&readers, fd))) return (-1); if ((ret = gnl_check_already(rdr, line)) > -1) return (ret); chr = NULL; ret = gnl_read(rdr, &chr); if (ret < BUFF_SIZE && fd != 0) rdr->eof = 1; if (!chr) { if (rdr->tmp && *(rdr->tmp)) *line = ft_strdup(rdr->tmp); ft_memdel((void **)&(rdr->tmp)); return (0); } *line = ft_strndup(rdr->tmp, ft_strlen(rdr->tmp) - (ft_strlen(chr))); ft_memdel((void **)&(rdr->tmp)); rdr->tmp = ft_strdup(chr + 1); ft_memdel((void **)&chr); return (rdr->eof == 1 && !rdr->tmp ? 0 : 1); }