blob: 22cc463f04a8744ea0c5d87832d39d4be7d0093f [file] [log] [blame]
/*
*
* (c) 2005-2009 Laurent Vivier <Laurent@vivier.eu>
*
* This file has been copied from EMILE, http://emile.sf.net
*
*/
#include "libiso9660.h"
#include "libopenbios/bindings.h"
#include "libc/diskio.h"
size_t iso9660_read(iso9660_FILE *_file, char *buf, size_t count)
{
iso9660_FILE *file = (iso9660_FILE*)_file;
size_t read = 0;
if ( count > (file->size - file->offset) )
count = file->size - file->offset;
while (count > 0)
{
size_t part;
int offset_extent;
int offset_index;
offset_extent = file->base +
(file->offset / ISOFS_BLOCK_SIZE);
offset_index = file->offset % ISOFS_BLOCK_SIZE;
if (file->current != offset_extent)
{
if ( (offset_index == 0) &&
(count >= ISOFS_BLOCK_SIZE) )
{
/* direct i/o */
int extents_nb;
extents_nb = count / ISOFS_BLOCK_SIZE;
part = extents_nb * ISOFS_BLOCK_SIZE;
seek_io(file->volume->fd,
offset_extent * ISOFS_BLOCK_SIZE);
read_io(file->volume->fd, buf + read, part);
file->offset += part;
count -= part;
read += part;
continue;
}
file->current = offset_extent;
seek_io(file->volume->fd,
offset_extent * ISOFS_BLOCK_SIZE);
read_io(file->volume->fd, file->buffer,
ISOFS_BLOCK_SIZE);
}
part = ISOFS_BLOCK_SIZE - offset_index;
if (count < part)
part = count;
memcpy(buf + read, file->buffer + offset_index, part);
file->offset += part;
count -= part;
read += part;
}
return read;
}