/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
//
// textfile.c
//
// Text file functions
//
// Copyright (c) 1995-96 Jim Nelson.  Permission to distribute
// granted by the author.  No warranties are made on the fitness of this
// source code.
//
*/

#include "htp.h"
#include "option.h"

BOOL OpenFile(const char *filename, const char *openFlags, TEXTFILE *textFile)
{
    char *os_filename;
    assert(filename != NULL);
    assert(openFlags != NULL);
    assert(textFile != NULL);

    /* convert the filename to the native machine's format */
    /* (MS-DOS to UNIX and vice-versa) */
    /* this returns an allocated copy of the string, so it must be freed */
    /* when the structure is destroyed */
    if((os_filename = ConvertDirDelimiter(filename)) == NULL)
    {
        DEBUG_PRINT(("unable to convert dir delimiter"));
        return FALSE;
    }

    /* initialize the rest of the structure */
    textFile->emptyLine     = TRUE;
    textFile->pendingSpaces = 0;
    textFile->flags = TEXTFILE_FLAG_NONE;
    textFile->file  = fopen(os_filename, openFlags);
    FreeMemory(os_filename);

    if(textFile->file == NULL)
    {
        DEBUG_PRINT(("unable to open file %s", filename));
        return FALSE;
    }

    return TRUE;
}   


BOOL OpenFD(int filedes, const char *openFlags, TEXTFILE *textFile)
{
    assert(openFlags != NULL);
    assert(textFile != NULL);

    /* initialize the rest of the structure */
    textFile->emptyLine     = TRUE;
    textFile->pendingSpaces = 0;
    textFile->flags = TEXTFILE_FLAG_NONE;
    textFile->file = fdopen(filedes, openFlags);

    if(textFile->file == NULL)
    {
        DEBUG_PRINT(("unable to open fd %d", filedes));
        return FALSE;
    }

    return TRUE;
}   

void CloseFile(TEXTFILE *textFile)
{
    assert(textFile != NULL);
    assert(textFile->file != NULL);

    fclose(textFile->file);
    textFile->file = NULL;
}   

BOOL GetFileChar(TEXTFILE *textFile, char *ch)
{
    int getCh;

    assert(textFile != NULL);
    assert(ch != NULL);
    assert(textFile->file != NULL);

    if((getCh = fgetc(textFile->file)) == EOF)
    {
        return FALSE;
    }
    
    *ch = (char) getCh;
    return TRUE;
}   

BOOL PutFileString(TEXTFILE *textFile, const char *str)
{
    char ch;
    uint pendingSpaces;
    uint condensing;
    BOOL emptyLine;

    assert(textFile != NULL);
    assert(textFile->file != NULL);

    condensing = 
        (textFile->flags & TEXTFILE_FLAG_FORCE_CR) != 0 ? OPT_V_FALSE
        : GetOptionValue(OPT_I_CONDENSE);
    emptyLine     = textFile->emptyLine;
    pendingSpaces = textFile->pendingSpaces;

    while ((ch = *str++) != NUL) {
        if (ch == '\r')
            continue;
        
        if (ch == ' ')
        {
            pendingSpaces++;
            continue;
        }
        
        if (ch == '\n')
        {
            /* suppress linefeeds? */

            if (condensing == OPT_V_TRUE)
            {
                /* Handle newline just as a space.
                 * C/R being dropped between words
                 */
                pendingSpaces++;
                continue;
            } 

            if (condensing == OPT_V_SEMI)
            {
                /* Remove spaces at end of line */
                pendingSpaces = 0;
                
                /* Remove empty lines */
                if (emptyLine) 
                    continue;
            }

            emptyLine = TRUE;
        }
        else
        {
            emptyLine = FALSE;
        }

        while (pendingSpaces > 0) {
            fputc(' ', textFile->file);
            pendingSpaces--;
            if (condensing == OPT_V_TRUE)
                pendingSpaces = 0;
        }

        fputc(ch, textFile->file);
    }
    textFile->emptyLine = emptyLine;
    textFile->pendingSpaces = pendingSpaces;
    return TRUE;
}   

