Added files - part of MS patch
This commit is contained in:
107
libisofs/data_source.c
Normal file
107
libisofs/data_source.c
Normal file
@ -0,0 +1,107 @@
|
||||
/*
|
||||
* Contains a simple implementation of a data source that reads from a
|
||||
* given file.
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "libisofs.h"
|
||||
|
||||
#define BLOCK_SIZE 2048
|
||||
|
||||
#define BLOCK_OUT_OF_FILE -1;
|
||||
#define READ_ERROR -2;
|
||||
#define SEEK_ERROR -3;
|
||||
|
||||
struct file_data_src {
|
||||
int fd;
|
||||
int nblocks;
|
||||
};
|
||||
|
||||
static int
|
||||
ds_read_block(struct data_source *src, int lba, unsigned char *buffer)
|
||||
{
|
||||
struct file_data_src *data;
|
||||
|
||||
assert(src && buffer);
|
||||
|
||||
data = (struct file_data_src*)src->data;
|
||||
|
||||
/* For block devices size is always 0, so this can't be used.
|
||||
* if (lba >= data->nblocks)
|
||||
* return BLOCK_OUT_OF_FILE;
|
||||
*/
|
||||
|
||||
/* goes to requested block */
|
||||
if ( lseek(data->fd, (off_t)lba * (off_t)BLOCK_SIZE, SEEK_SET) == (off_t) -1 )
|
||||
return SEEK_ERROR;
|
||||
|
||||
if ( read(data->fd, buffer, BLOCK_SIZE) != BLOCK_SIZE )
|
||||
return READ_ERROR;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ds_get_size(struct data_source *src)
|
||||
{
|
||||
struct file_data_src *data;
|
||||
|
||||
assert(src);
|
||||
|
||||
data = (struct file_data_src*)src->data;
|
||||
return data->nblocks;
|
||||
}
|
||||
|
||||
static void ds_free_data(struct data_source *src)
|
||||
{
|
||||
struct file_data_src *data;
|
||||
|
||||
assert(src);
|
||||
|
||||
data = (struct file_data_src*)src->data;
|
||||
|
||||
/* close the file */
|
||||
close(data->fd);
|
||||
free(data);
|
||||
}
|
||||
|
||||
struct data_source *data_source_from_file(const char *path)
|
||||
{
|
||||
int fd;
|
||||
struct stat info;
|
||||
struct file_data_src *data;
|
||||
struct data_source *ret;
|
||||
|
||||
assert(path);
|
||||
|
||||
fd = open(path, O_RDONLY);
|
||||
if (fd == -1)
|
||||
return NULL;
|
||||
|
||||
fstat(fd, &info);
|
||||
|
||||
data = malloc(sizeof(struct file_data_src));
|
||||
data->fd = fd;
|
||||
data->nblocks = info.st_size / BLOCK_SIZE;
|
||||
|
||||
ret = malloc(sizeof(struct data_source));
|
||||
ret->refcount = 1;
|
||||
ret->read_block = ds_read_block;
|
||||
ret->get_size = ds_get_size;
|
||||
ret->free_data = ds_free_data;
|
||||
ret->data = data;
|
||||
return ret;
|
||||
}
|
||||
|
||||
void data_source_free(struct data_source *src)
|
||||
{
|
||||
if (--src->refcount == 0) {
|
||||
src->free_data(src);
|
||||
free(src);
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user