/* 
 * This file is subject to the terms and conditions of the GNU General Public
 * License.  See the file "COPYING" in the main directory of this archive
 * for more details.
 *
 * Copyright (C) Hewlett-Packard (Paul Bame) paul_bame@hp.com
 */
#include "bootloader.h"

/* this is the stupidest "file system" imaginable -- it applies an */
/* offset to the seek pointers and optionally checks against a length */

struct offsets {
    int fd;
    int start;
    int length;
} ofd [MAX_FD];

static int offset_read(int fd, char *buf, unsigned count, unsigned devaddr)
{
    struct offsets *o = &ofd[fd];

    if (Debug) printf("offset_read(%d, 0x%p, %d, %d)\r\n",
		    fd, buf, count, devaddr);

    /* truncate 'count' according to max device/file size */
    if (o->length > 0 && devaddr < o->length && devaddr + count > o->length)
	count = o->length - devaddr;
    else if (o->length > 0 && devaddr + count > o->length)
    {
	printf("offset_read(%d, 0x%p, %d, %d) can't seek past %d\r\n",
			fd, buf, count, devaddr, o->length);
	return -1;
    }

    return seekread(o->fd, buf, count, devaddr + o->start);
}

static void offset_describe(int fd, int *bufalign,
				int *blocksize)
{
    describe(ofd[fd].fd, bufalign, blocksize);
}

/* returns true if OK */
int offset_open(int otherfd, int offset, int length)
{
    int fd = fileio_open(offset_describe, offset_read);

    if (fd >= 0)
    {
	struct offsets *o = &ofd[fd];

	o->fd = otherfd;
	o->start = offset;
	o->length = length;
    }

     if (Debug) printf("offset_open(%d, %d, %d) = %d\n",
	otherfd, offset, length, fd);

    return fd;
}
