Add qemu 2.4.0
[kvmfornfv.git] / qemu / roms / openbios / fs / iso9660 / iso9660_read.c
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
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 }