1 /*
2 *
3 * (c) 2005-2009 Laurent Vivier <Laurent@vivier.eu>
4 *
5 * This file has been copied from EMILE, http://emile.sf.net
6 *
7 */
8
9 #include "libiso9660.h"
10 #include "libopenbios/bindings.h"
11 #include "libc/diskio.h"
12
iso9660_read(iso9660_FILE * _file,char * buf,size_t count)13 size_t iso9660_read(iso9660_FILE *_file, char *buf, size_t count)
14 {
15 iso9660_FILE *file = (iso9660_FILE*)_file;
16 size_t read = 0;
17
18 if ( count > (file->size - file->offset) )
19 count = file->size - file->offset;
20
21 while (count > 0)
22 {
23 size_t part;
24 int offset_extent;
25 int offset_index;
26
27 offset_extent = file->base +
28 (file->offset / ISOFS_BLOCK_SIZE);
29 offset_index = file->offset % ISOFS_BLOCK_SIZE;
30
31 if (file->current != offset_extent)
32 {
33 if ( (offset_index == 0) &&
34 (count >= ISOFS_BLOCK_SIZE) )
35 {
36 /* direct i/o */
37
38 int extents_nb;
39
40 extents_nb = count / ISOFS_BLOCK_SIZE;
41
42 part = extents_nb * ISOFS_BLOCK_SIZE;
43
44 seek_io(file->volume->fd,
45 offset_extent * ISOFS_BLOCK_SIZE);
46 read_io(file->volume->fd, buf + read, part);
47
48 file->offset += part;
49 count -= part;
50 read += part;
51
52 continue;
53 }
54
55 file->current = offset_extent;
56 seek_io(file->volume->fd,
57 offset_extent * ISOFS_BLOCK_SIZE);
58 read_io(file->volume->fd, file->buffer,
59 ISOFS_BLOCK_SIZE);
60 }
61
62 part = ISOFS_BLOCK_SIZE - offset_index;
63 if (count < part)
64 part = count;
65
66 memcpy(buf + read, file->buffer + offset_index, part);
67
68 file->offset += part;
69 count -= part;
70 read += part;
71 }
72
73 return read;
74 }
75