/* * * (c) 2005-2009 Laurent Vivier * * 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; }