/* Copyright (C) 2011 The Android Open Source Project
**
** This software is licensed under the terms of the GNU General Public
** License version 2, as published by the Free Software Foundation, and
** may be copied, distributed, and modified under those terms.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
** GNU General Public License for more details.
*/
#include <errno.h>
#include "android/utils/system.h"
#include "android/utils/assert.h"
#include "android/utils/lineinput.h"

struct LineInput {
    char*   line;
    size_t  line_size;
    int     line_num;
    int     error;
    int     eof;

    struct {
        FILE*  file;
    } std;

    char    line0[128];
};

/* Error codes returned by the internal line reading function(s) */
enum {
    LINEINPUT_ERROR = -1,
    LINEINPUT_EOF = -2,
};


static LineInput*
_lineInput_new( void )
{
    LineInput*  input;

    ANEW0(input);
    input->line      = input->line0;
    input->line_size = sizeof(input->line0);

    return input;
}

/* Create a LineInput object that reads from a FILE* object */
LineInput*
lineInput_newFromStdFile( FILE* file )
{
    LineInput* input = _lineInput_new();

    input->std.file = file;
    return input;
}

/* Grow the line buffer a bit */
static void
_lineInput_grow( LineInput* input )
{
    char*  line;
    char grow_from_line0 = 0;

    input->line_size += input->line_size >> 1;
    line = input->line;
    if (line == input->line0) {
        grow_from_line0 = 1;
        line = NULL;
    }
    AARRAY_RENEW(line, input->line_size);
    if (grow_from_line0) {
        memcpy(line, input->line0, sizeof(input->line0));
    }
    input->line = line;
}

/* Forward declaration */
static int _lineInput_getLineFromStdFile( LineInput* input, FILE* file );

const char*
lineInput_getLine( LineInput* input )
{
    return lineInput_getLineAndSize(input, NULL);
}

const char*
lineInput_getLineAndSize( LineInput* input, size_t *pSize )
{
    int ret;

    /* be safe */
    if (pSize)
        *pSize = 0;

    /* check parameters */
    if (input == NULL) {
        errno = EINVAL;
        return NULL;
    }

    /* check state */
    if (input->error) {
        return NULL;
    }
    if (input->eof) {
        return NULL;
    }

    ret = _lineInput_getLineFromStdFile(input, input->std.file);
    if (ret >= 0) {
        input->line_num += 1;
        if (pSize != NULL) {
            *pSize = ret;
            return input->line;
        }
        return input->line;
    }
    if (ret == LINEINPUT_EOF) {
        input->line_num += 1;
        input->eof = 1;
        return NULL;
    }
    if (ret == LINEINPUT_ERROR) {
        input->error = errno;
        return NULL;
    }
    AASSERT_UNREACHED();
    return NULL;
}

/* Returns the number of the last line read by lineInput_getLine */
int
lineInput_getLineNumber( LineInput* input )
{
    return input->line_num;
}

/* Returns TRUE iff the end of file was reached */
int
lineInput_isEof( LineInput* input )
{
    return (input->eof != 0);
}

/* Return the error condition of a LineInput object.
 * These are standard errno code for the last operation.
 * Note: EOF corresponds to 0 here.
 */
int
lineInput_getError( LineInput* input )
{
    return input->error;
}

void
lineInput_free( LineInput* input )
{
    if (input != NULL) {
        if (input->line != NULL) {
            if (input->line != input->line0)
                AFREE(input->line);
            input->line = NULL;
            input->line_size = 0;
        }
        AFREE(input);
    }
}


/* Internal function used to read a new line from a FILE* using fgets().
 * We assume that this is more efficient than calling fgetc() in a loop.
 *
 * Return length of line, or either LINEINPUT_EOF / LINEINPUT_ERROR
 */
static int
_lineInput_getLineFromStdFile( LineInput* input, FILE* file )
{
    int   offset = 0;
    char* p;

    input->line[0] = '\0';

    for (;;) {
        char* buffer = input->line + offset;
        int   avail  = input->line_size - offset;

        if (!fgets(buffer, avail, file)) {
            /* We either reached the end of file or an i/o error occured.
             * If we already read line data, just return it this time.
             */
            if (offset > 0) {
                return offset;
            }
            goto INPUT_ERROR;
        }

        /* Find the terminating zero */
        p = memchr(buffer, '\0', avail);
        AASSERT(p != NULL);

        if (p == buffer) {
            /* This happens when the file has an embedded '\0', treat it
             * as an eof, or bad things usually happen after that. */
            input->eof = 1;
            if (offset > 0)
                return offset;
            else
                return LINEINPUT_EOF;
        }

        if (p[-1] != '\n' && p[-1] != '\r') {
            /* This happens when the line is longer than our current buffer,
            * so grow its size and try again. */
            offset = p - input->line;
            _lineInput_grow(input);
            continue;
        }

        break;
    }

    /* Get rid of trailing newline(s). Consider: \n, \r, and \r\n */
    if (p[-1] == '\n') {
        p -= 1;
        if (p > input->line && p[-1] == '\r') {
            p -= 1;
        }
        p[0] = '\0';
    }
    else if (p[-1] == '\r') {
        p -= 1;
        p[0] = '\0';
    }

    /* We did it */
    return (p - input->line);

INPUT_ERROR:
    if (feof(file)) {
        input->eof = 1;
        return LINEINPUT_EOF;
    }
    input->error = errno;
    return LINEINPUT_ERROR;
}

