get_next_line.c 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. /* ************************************************************************** */
  2. /* */
  3. /* ::: :::::::: */
  4. /* get_next_line.c :+: :+: :+: */
  5. /* +:+ +:+ +:+ */
  6. /* By: bchanot <bchanot@student.42.fr> +#+ +:+ +#+ */
  7. /* +#+#+#+#+#+ +#+ */
  8. /* Created: 2015/12/13 15:04:06 by bchanot #+# #+# */
  9. /* Updated: 2018/04/17 11:47:45 by bchanot ### ########.fr */
  10. /* */
  11. /* ************************************************************************** */
  12. #include "libft.h"
  13. #include <unistd.h>
  14. static t_gnl *gnl_add(int fd)
  15. {
  16. t_gnl *tmp;
  17. if (!(tmp = (t_gnl *)ft_memalloc(sizeof(t_gnl))))
  18. return (NULL);
  19. tmp->tmp = NULL;
  20. tmp->eof = 0;
  21. tmp->fd = fd;
  22. tmp->next = NULL;
  23. return (tmp);
  24. }
  25. static t_gnl *gnl_find_reader(t_gnl **list, int fd)
  26. {
  27. t_gnl *tmp;
  28. tmp = *list;
  29. while (tmp)
  30. {
  31. if (tmp->fd == fd)
  32. {
  33. if (!tmp->tmp && tmp->eof == 1)
  34. tmp->eof = 0;
  35. return (tmp);
  36. }
  37. tmp = tmp->next;
  38. }
  39. tmp = *list;
  40. if (!(*list))
  41. return ((*list = gnl_add(fd)));
  42. while (tmp->next)
  43. tmp = tmp->next;
  44. return ((tmp->next = gnl_add(fd)));
  45. }
  46. static int gnl_check_already(t_gnl *rdr, char **line)
  47. {
  48. char *chr;
  49. if ((chr = ft_strdup(ft_strchr(rdr->tmp, '\n'))))
  50. {
  51. *line = ft_strndup(rdr->tmp, ft_strlen(rdr->tmp) - ft_strlen(chr));
  52. ft_memdel((void **)&(rdr->tmp));
  53. rdr->tmp = ft_strdup(chr + 1);
  54. ft_memdel((void **)&chr);
  55. return (1);
  56. }
  57. if (rdr->eof == 1 && (!rdr->tmp || !(*(rdr->tmp))))
  58. return (0);
  59. if (rdr->eof == 1)
  60. {
  61. *line = ft_strdup(rdr->tmp);
  62. ft_memdel((void **)&(rdr->tmp));
  63. return (0);
  64. }
  65. return (-1);
  66. }
  67. static int gnl_read(t_gnl *rdr, char **chr)
  68. {
  69. char *tmp;
  70. char c[BUFF_SIZE + 1];
  71. int ret;
  72. tmp = NULL;
  73. ft_bzero(c, BUFF_SIZE + 1);
  74. while ((ret = read(rdr->fd, c, BUFF_SIZE)))
  75. {
  76. if (rdr->tmp)
  77. {
  78. tmp = ft_strnew(ft_strlen(rdr->tmp) + ft_strlen(c));
  79. ft_memcpy(tmp, rdr->tmp, ft_strlen(rdr->tmp));
  80. ft_memcpy(tmp + ft_strlen(rdr->tmp), c, ft_strlen(c));
  81. ft_memdel((void **)&(rdr->tmp));
  82. rdr->tmp = tmp;
  83. }
  84. else
  85. rdr->tmp = ft_strdup(c);
  86. ft_bzero(c, BUFF_SIZE + 1);
  87. if ((*chr = ft_strdup(ft_strchr(rdr->tmp, '\n'))))
  88. break ;
  89. }
  90. return (ret);
  91. }
  92. int get_next_line(const int fd, char **line)
  93. {
  94. static t_gnl *readers = NULL;
  95. t_gnl *rdr;
  96. char *chr;
  97. int ret;
  98. if (fd < 0 || !line || !(rdr = gnl_find_reader(&readers, fd)))
  99. return (-1);
  100. if ((ret = gnl_check_already(rdr, line)) > -1)
  101. return (ret);
  102. chr = NULL;
  103. ret = gnl_read(rdr, &chr);
  104. if (ret < BUFF_SIZE && fd != 0)
  105. rdr->eof = 1;
  106. if (!chr)
  107. {
  108. if (rdr->tmp && *(rdr->tmp))
  109. *line = ft_strdup(rdr->tmp);
  110. ft_memdel((void **)&(rdr->tmp));
  111. return (0);
  112. }
  113. *line = ft_strndup(rdr->tmp, ft_strlen(rdr->tmp) - (ft_strlen(chr)));
  114. ft_memdel((void **)&(rdr->tmp));
  115. rdr->tmp = ft_strdup(chr + 1);
  116. ft_memdel((void **)&chr);
  117. return (rdr->eof == 1 && !rdr->tmp ? 0 : 1);
  118. }