/*
** BufIO.c - 
** Copyright (C) 1996-97 Serge Emond
**
** This program is free software; you can redistribute it and/or
** modify it under the terms of the GNU General Public License
** as published by the Free Software Foundation; either version 2
** of the License, or (at your option) any later version.
**
** 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.
**
** You should have received a copy of the GNU General Public License
** along with this program; if not, write to the Free Software
** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
*/

#include <proto/exec.h>
#include <exec/memory.h>

#include <proto/dos.h>

#include "BufIO.h"

/*
** accessmode: MODE_OLDFILE, MODE_NEWFILE, MODE_READWRITE
** MUST BE MODE_NEWFILE for now
*/

bfile *BOpen(STRPTR name, LONG accessmode, ULONG bufsize)
{
    bfile *hand;

    if (!bufsize)
        return(NULL);
    if (accessmode != MODE_NEWFILE)
        return(NULL);

    if (hand = (bfile *)AllocMem(sizeof(bfile), MEMF_PUBLIC)) {
        if (hand->buf = AllocMem(bufsize, NULL)) {
            hand->bufsiz = bufsize;
            hand->bufful = 0;

            if (hand->doshan = Open(name, MODE_NEWFILE)) {
                return(hand);
            }
            FreeMem(hand->buf, hand->bufsiz);
        }
        FreeMem((void *)hand, sizeof(bfile));
    }

    return(NULL);
}

void BClose(bfile *hand)
{
    if (hand) {
        if (hand->bufful)
            Write(hand->doshan, hand->buf, hand->bufful);
        Close(hand->doshan);
        FreeMem(hand->buf, hand->bufsiz);
        FreeMem(hand, sizeof(bfile));
    }
}

void BFlush(bfile *hand)
{
    if (hand) {
        if (hand->bufful) {
            Write(hand->doshan, hand->buf, hand->bufful);
            hand->bufful = 0L;
        }
    }
}

/* File MUST be BOpenned... */
/* MUST NOT WRITE MORE THAN ->bufsiz AT ONCE! */

void BWrite(bfile *hand, void *buf, ULONG len)
{
    if (hand->bufful + len <= hand->bufsiz) {
        CopyMem((APTR)buf, (APTR)((ULONG)hand->buf + hand->bufful), len);
        hand->bufful += len;
        if (hand->bufful == hand->bufsiz) {
            Write(hand->doshan, hand->buf, hand->bufsiz);
            hand->bufful = 0L;
        }
    }
    else {
        ULONG empty;
        empty = hand->bufsiz - hand->bufful;

        CopyMem((APTR)buf, (APTR)((ULONG)hand->buf + hand->bufful), empty);

        Write(hand->doshan, hand->buf, hand->bufsiz);

        hand->bufful = len - empty;

        CopyMem((APTR)((ULONG)buf + empty), (APTR)hand->buf, hand->bufful);
    }
}

