Add qemu 2.4.0
[kvmfornfv.git] / qemu / roms / openbios / fs / iso9660 / iso9660_read.c
diff --git a/qemu/roms/openbios/fs/iso9660/iso9660_read.c b/qemu/roms/openbios/fs/iso9660/iso9660_read.c
new file mode 100644 (file)
index 0000000..22cc463
--- /dev/null
@@ -0,0 +1,74 @@
+/*
+ *
+ * (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;
+}