mirror of
https://github.com/vivier/EMILE.git
synced 2024-12-22 10:29:31 +00:00
first revision
This commit is contained in:
parent
155c1089b1
commit
ee35f84292
22
libcontainer/container_close.c
Normal file
22
libcontainer/container_close.c
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
/*
|
||||||
|
*
|
||||||
|
* (c) 2005 Laurent Vivier <LaurentVivier@wanadoo.fr>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include "libcontainer.h"
|
||||||
|
|
||||||
|
int container_close(container_FILE *file)
|
||||||
|
{
|
||||||
|
if (file == NULL)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (file->container)
|
||||||
|
free(file->container);
|
||||||
|
|
||||||
|
free(file);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
19
libcontainer/container_fstat.c
Normal file
19
libcontainer/container_fstat.c
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
/*
|
||||||
|
*
|
||||||
|
* (c) 2005 Laurent Vivier <LaurentVivier@wanadoo.fr>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "libcontainer.h"
|
||||||
|
|
||||||
|
int container_fstat(container_FILE *file, struct stream_stat *buf)
|
||||||
|
{
|
||||||
|
if (buf == NULL)
|
||||||
|
return -1;
|
||||||
|
if (file->container->size == -1)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
buf->st_size = file->container->size;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
34
libcontainer/container_lseek.c
Normal file
34
libcontainer/container_lseek.c
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
/*
|
||||||
|
*
|
||||||
|
* (c) 2005 Laurent Vivier <LaurentVivier@wanadoo.fr>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include "libcontainer.h"
|
||||||
|
|
||||||
|
int container_lseek(container_FILE *file, off_t offset, int whence)
|
||||||
|
{
|
||||||
|
long new_offset;
|
||||||
|
|
||||||
|
switch(whence)
|
||||||
|
{
|
||||||
|
case SEEK_SET:
|
||||||
|
new_offset = offset;
|
||||||
|
break;
|
||||||
|
case SEEK_CUR:
|
||||||
|
new_offset = file->offset + offset;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (new_offset < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
file->offset = new_offset;
|
||||||
|
|
||||||
|
return new_offset;
|
||||||
|
}
|
50
libcontainer/container_open.c
Normal file
50
libcontainer/container_open.c
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
/*
|
||||||
|
*
|
||||||
|
* (c) 2005 Laurent Vivier <LaurentVivier@wanadoo.fr>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include "libcontainer.h"
|
||||||
|
|
||||||
|
container_FILE *container_open(device_io_t *device, char *path)
|
||||||
|
{
|
||||||
|
container_FILE *file;
|
||||||
|
int block_size = device->get_blocksize(device->data);
|
||||||
|
unsigned long first, nbblocs;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
first = strtol(path, &path, 0);
|
||||||
|
if (*path != ',')
|
||||||
|
return NULL;
|
||||||
|
path++;
|
||||||
|
nbblocs = strtol(path, &path, 0);
|
||||||
|
if (*path != 0)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
file = (container_FILE *)malloc(sizeof(container_FILE) + block_size);
|
||||||
|
if (file == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
file->container = (struct emile_container*)malloc(sizeof(struct emile_container) + block_size * nbblocs);
|
||||||
|
if (file->container == NULL)
|
||||||
|
{
|
||||||
|
free(file);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = device->read_sector(device->data, first, file->container, block_size * nbblocs);
|
||||||
|
if (ret == -1)
|
||||||
|
{
|
||||||
|
free(file->container);
|
||||||
|
free(file);
|
||||||
|
}
|
||||||
|
|
||||||
|
file->offset = 0;
|
||||||
|
file->current_block = 0;
|
||||||
|
file->last_current = 0;
|
||||||
|
file->last_index = 0;
|
||||||
|
|
||||||
|
return file;
|
||||||
|
}
|
98
libcontainer/container_read.c
Normal file
98
libcontainer/container_read.c
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
/*
|
||||||
|
*
|
||||||
|
* (c) 2005 Laurent Vivier <LaurentVivier@wanadoo.fr>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "libcontainer.h"
|
||||||
|
|
||||||
|
static unsigned long seek_block(container_FILE *file)
|
||||||
|
{
|
||||||
|
struct emile_container *container = file->container;
|
||||||
|
ssize_t current;
|
||||||
|
int i;
|
||||||
|
unsigned long offset = file->offset;
|
||||||
|
int block_size = file->device.get_blocksize(file->device.data);
|
||||||
|
|
||||||
|
/* search forward */
|
||||||
|
|
||||||
|
for (i = file->last_index,
|
||||||
|
current = file->last_current;
|
||||||
|
i < container->blocks[i].count; i++)
|
||||||
|
{
|
||||||
|
int extent_size = block_size *
|
||||||
|
container->blocks[i].count;
|
||||||
|
|
||||||
|
if ( (current <= offset) && (offset < current + extent_size) )
|
||||||
|
{
|
||||||
|
file->last_current = current;
|
||||||
|
file->last_index = i;
|
||||||
|
return container->blocks[i].offset +
|
||||||
|
(offset - current) / block_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
current += extent_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* search backward */
|
||||||
|
|
||||||
|
for (i = file->last_index,
|
||||||
|
current = file->last_current;
|
||||||
|
i > 0; i--)
|
||||||
|
{
|
||||||
|
int extent_size = block_size *
|
||||||
|
container->blocks[i - 1].count;
|
||||||
|
|
||||||
|
current -= extent_size;
|
||||||
|
|
||||||
|
if ( (current <= offset) && (offset < current + extent_size) )
|
||||||
|
{
|
||||||
|
file->last_current = current;
|
||||||
|
file->last_index = i - 1;
|
||||||
|
return container->blocks[i].offset +
|
||||||
|
(offset - current) / block_size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ssize_t container_read(container_FILE *file, void *ptr, size_t size)
|
||||||
|
{
|
||||||
|
int err;
|
||||||
|
ssize_t read = 0;
|
||||||
|
int part;
|
||||||
|
int block_size = file->device.get_blocksize(file->device.data);
|
||||||
|
|
||||||
|
while (size != 0)
|
||||||
|
{
|
||||||
|
unsigned long block_nb = seek_block(file);
|
||||||
|
int block_offset = file->offset % block_size;
|
||||||
|
|
||||||
|
if (block_nb != file->current_block)
|
||||||
|
{
|
||||||
|
err = file->device.read_sector(
|
||||||
|
file->device.data,
|
||||||
|
block_nb,
|
||||||
|
file->buffer,
|
||||||
|
block_size);
|
||||||
|
if (err == -1)
|
||||||
|
return -1;
|
||||||
|
file->current_block = block_nb;
|
||||||
|
}
|
||||||
|
|
||||||
|
part = block_size - block_offset;
|
||||||
|
if (part > size)
|
||||||
|
part = size;
|
||||||
|
memcpy(ptr, file->buffer + block_offset, part);
|
||||||
|
|
||||||
|
size -= part;
|
||||||
|
ptr = (char*)ptr + part;
|
||||||
|
file->offset += part;
|
||||||
|
read += part;
|
||||||
|
}
|
||||||
|
|
||||||
|
return read;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user