/* * Contains a simple implementation of a data source that reads from a * given file. */ #include #include #include #include #include #include #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); } }