Untitled

 avatar
unknown
plain_text
3 years ago
3.3 kB
3
Indexable
/* ************************************************************************** */
/*                                                                            */
/*                                                        :::      ::::::::   */
/*   get_next_line.c                                    :+:      :+:    :+:   */
/*                                                    +:+ +:+         +:+     */
/*   By: joivanau <joivanau@student.hive.fi>        +#+  +:+       +#+        */
/*                                                +#+#+#+#+#+   +#+           */
/*   Created: 2021/11/17 14:05:39 by joivanau          #+#    #+#             */
/*   Updated: 2021/11/25 17:30:44 by joivanau         ###   ########.fr       */
/*                                                                            */
/* ************************************************************************** */

#include "get_next_line.h"

static char	*first_line_checking(int i, int errcheck, char *buf, int *error)
{
	int	strlength;

	strlength = ft_strlen(buf) - 1;
	if (i - 1 == 0 && strlength == 0)
		errcheck = -1;
	if (*error == 1)
	{
		if (i <= strlength)
			buf = ft_strsub(buf, i, strlength);
		if (i - 1 >= strlength)
			ft_strdel(&buf);
		*error = errcheck;
		return (buf);
	}
	if (i >= strlength && (errcheck == 1 || errcheck == -1))
		ft_strdel(&buf);
	if (i <= strlength)
		buf = ft_strsub(buf, i, strlength);
	*error = errcheck;
	return (buf);
}

static char	*get_first_line(char *buf, char **line, int *error)
{
	int	i;
	int	strlength;
	int	errcheck;

	i = 0;
	errcheck = 1;
	strlength = ft_strlen(buf) - 1;
	while (1)
	{
		if (buf[i] == '\0')
		{
			errcheck = 0;
			break ;
		}
		if (buf[i] == '\n')
		{
			if (i == 0)
				break ;
			*line = ft_strsub(buf, 0, i);
			break ;
		}
		i++;
	}
	buf = first_line_checking(i + 1, errcheck, buf, error);
	return (buf);
}

static int	read_line_while(const int fd, char **sbuf, char *buf, int *error)
{
	int		sz;
	char	*temp;

	sz = read(fd, buf, BUFF_SIZE);
	if (sz == 0 || sz == -1)
		return (sz);
	if (sz < BUFF_SIZE)
	{
		buf[sz] = '\n';
		buf[sz + 1] = '\0';
		*error = 2;
	}
	temp = ft_strjoin(*sbuf, buf);
	ft_strdel(sbuf);
	*sbuf = ft_strjoin(temp, "\0");
	ft_strdel(&temp);
	return (sz);
}

static char	*read_line(const int fd, char *sbuf, int *error)
{
	int		sz;
	char	*buf;

	buf = (char *) ft_calloc(BUFF_SIZE + 1, sizeof(char));
	sz = 0;
	while (1)
	{
		if (buf[sz - BUFF_SIZE] == '\n')
			break ;
		if (sz == 0)
		{
			sz = read_line_while(fd, &sbuf, buf, error);
			if (sz == 0 || sz == -1)
				break ;
		}
		sz--;
	}
	ft_strdel(&buf);
	if (sz == -1)
		*error = -1;
	if (ft_strlen(sbuf) == 0)
		return (NULL);
	if (sz == 0 && *error == 1)
		sbuf[ft_strlen(sbuf)] = '\n';
	return (sbuf);
}

int	get_next_line(const int fd, char **line)
{
	static char	*sbuf;
	int			error;

	if (line == NULL)
		return (-1);
	*line = "";
	error = 0;
	if (sbuf != NULL)
		sbuf = get_first_line(sbuf, line, &error);
	else
		sbuf = (char *) ft_calloc(BUFF_SIZE + 1, sizeof(char));
	if (error == 1 || error == -1)
		return (error);
	error = 1;
	sbuf = read_line(fd, sbuf, &error);
	if (sbuf == 0)
	{
		ft_strdel(&sbuf);
		if (error == -1)
			return (-1);
		return (0);
	}
	sbuf = get_first_line(sbuf, line, &error);
	return (1);
}