diff --git a/src/builder.h b/src/builder.h new file mode 100644 index 0000000..c3bf15f --- /dev/null +++ b/src/builder.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2007 Vreixo Formoso + * + * This file is part of the libisofs project; you can redistribute it and/or + * modify it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. See COPYING file for details. + */ + +#ifndef LIBISO_BUILDER_H_ +#define LIBISO_BUILDER_H_ + +/* + * Definitions for IsoNode builders. + */ + +/* + * Some functions here will be moved to libisofs.h when we expose + * Builder. + */ + +#include "node.h" + +typedef struct Iso_Node_Builder IsoNodeBuilder; + +struct Iso_Node_Builder +{ + + /** + * + * @return + * 1 on success, < 0 on error + */ + int (*create_file)(const IsoFileSource *src, IsoFile **file); + + + + int refcount; + void *data; +}; + + + +#endif /*LIBISO_BUILDER_H_*/ diff --git a/src/filesrc.h b/src/filesrc.h new file mode 100644 index 0000000..de67a8a --- /dev/null +++ b/src/filesrc.h @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2007 Vreixo Formoso + * + * This file is part of the libisofs project; you can redistribute it and/or + * modify it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. See COPYING file for details. + */ +#ifndef LIBISO_FILESRC_H_ +#define LIBISO_FILESRC_H_ + +/* + * FIXME definitions here shouldn't be used for now!!! + * + */ + + +/* + * Definitions of streams. + */ + +/* + * Some functions here will be moved to libisofs.h when we expose + * Streams. + */ + +//typedef struct Iso_Stream IsoStream; +// +//struct Iso_Stream +//{ +// /** +// * Opens the stream. +// * +// * @return +// * 1 on success, < 0 on error, 2 file is smaller than expect, +// * 3 file is larger than expected (2 and 3 are not errors, they're +// * handled by read_block, see there. Moreover, IsooStream +// * implementations doesn't need to check that) +// */ +// int (*open)(IsoStream *stream); +// +// /** +// * Close the Stream. +// * @return 1 on success, < 0 on error +// */ +// int (*close)(IsoStream *stream); +// +// /** +// * Get the size (in bytes) of the stream. This function must return +// * always the same size, even if the underlying source file has changed. +// */ +// off_t (*get_size)(IsoStream *stream); +// +// /** +// * Read a block (2048 bytes) from the stream. +// * +// * This function should always read the full 2048 bytes, blocking if +// * needed. When it reaches EOF, the buf is filled with 0's, if needed. +// * Note that the EOF is not reported in that call, but in the next call. +// * I.e., when the EOF is reported you can be sure that the function +// * has not written anything to the buffer. If the file size is a multiple +// * of block size, i.e N*2048, the read_block reports the EOF just when +// * reading the N+1 block. +// * +// * Note that EOF refers to the original size as reported by get_size. +// * If the underlying source size has changed, this function should take +// * care of this, truncating the file, or filling the buffer with 0s. I.e. +// * this function return 0 (EOF) only when get_size() bytes have been +// * readed. +// * +// * On an I/O error, or a file smaller than the expected size, this +// * function returns a [specific error code], and the buffer is filled +// * with 0s. Subsequent calls will still return an error code and fill +// * buffer with 0's, until EOF (as defined above) is reached, and then +// * the function will return 0. +// * +// * Note that if the current size is larger than expected, you don't get +// * any error on reading. +// * +// * @param buf +// * Buffer where data fill be copied, with at least 2048 bytes. +// * @return +// * 1 sucess, 0 EOF, < 0 error (buf is filled with 0's) +// */ +// int (*read_block)(IsoStream *stream, void *buf); +// +// /** +// * Whether this Stram can be read several times, with the same results. +// * For example, a regular file is repeatable, you can read it as many +// * times as you want. However, a pipe isn't. +// * +// * This function doesn't take into account if the file has been modified +// * between the two reads. +// */ +// int (*is_repeatable)(IsoStream *stream); +// +// int refcount; +// void *data; +//} + +#endif /*LIBISO_FILESRC_H_*/ diff --git a/src/fs_local.c b/src/fs_local.c index 576d295..1272207 100644 --- a/src/fs_local.c +++ b/src/fs_local.c @@ -24,6 +24,11 @@ #include #include +/* + * We can share a local filesystem object, as it has no private atts. + */ +IsoFilesystem *lfs = NULL; + typedef struct { /* IsoFilesystem *fs; It seems not needed */ @@ -314,6 +319,12 @@ int lfs_readlink(IsoFileSource *src, char *buf, size_t bufsiz) return ISO_SUCCESS; } +static +IsoFilesystem* lfs_get_filesystem(IsoFileSource *src) +{ + return src == NULL ? NULL : lfs; +} + static void lfs_free(IsoFileSource *src) { @@ -328,6 +339,7 @@ void lfs_free(IsoFileSource *src) free(data->path); free(data); + iso_filesystem_unref(lfs); } /** @@ -344,6 +356,11 @@ int iso_file_source_new_lfs(const char *path, IsoFileSource **src) return ISO_NULL_POINTER; } + if (lfs == NULL) { + /* this should never happen */ + return ISO_ERROR; + } + /* allocate memory */ data = malloc(sizeof(_LocalFsFileSource)); if (data == NULL) { @@ -379,7 +396,11 @@ int iso_file_source_new_lfs(const char *path, IsoFileSource **src) lfs_src->read = lfs_read; lfs_src->readdir = lfs_readdir; lfs_src->readlink = lfs_readlink; + lfs_src->get_filesystem = lfs_get_filesystem; lfs_src->free = lfs_free; + + /* take a ref to local filesystem */ + iso_filesystem_ref(lfs); /* return */ *src = lfs_src; @@ -413,24 +434,27 @@ void lfs_fs_free(IsoFilesystem *fs) int iso_local_filesystem_new(IsoFilesystem **fs) { - IsoFilesystem *lfs; - if (fs == NULL) { return ISO_NULL_POINTER; } - lfs = malloc(sizeof(IsoFilesystem)); - if (lfs == NULL) { - return ISO_OUT_OF_MEM; + if (lfs != NULL) { + /* just take a new ref */ + iso_filesystem_ref(lfs); + } else { + + lfs = malloc(sizeof(IsoFilesystem)); + if (lfs == NULL) { + return ISO_OUT_OF_MEM; + } + + /* fill struct */ + lfs->refcount = 1; + lfs->data = NULL; /* we don't need private data */ + lfs->get_root = lfs_get_root; + lfs->get_by_path = lfs_get_by_path; + lfs->free = lfs_fs_free; } - - /* fill struct */ - lfs->refcount = 1; - lfs->data = NULL; /* we don't need private data */ - lfs->get_root = lfs_get_root; - lfs->get_by_path = lfs_get_by_path; - lfs->free = lfs_fs_free; - *fs = lfs; return ISO_SUCCESS; } diff --git a/src/fsource.h b/src/fsource.h index 4542c87..f72eb1e 100644 --- a/src/fsource.h +++ b/src/fsource.h @@ -42,7 +42,9 @@ struct Iso_Filesystem void (*free)(IsoFilesystem *fs); - int refcount; + /* TODO each file will take a ref to IsoFilesystem, so maybe a 64bits + * integer is a better choose for this */ + unsigned int refcount; void *data; }; @@ -170,6 +172,15 @@ struct Iso_File_Source * */ int (*readlink)(IsoFileSource *src, char *buf, size_t bufsiz); + + /** + * Get the filesystem for this source. No extra ref is added, so you + * musn't unref the IsoFilesystem. + * + * @return + * The filesystem, NULL on error + */ + IsoFilesystem* (*get_filesystem)(IsoFileSource *src); /** * Free implementation specific data. Should never be called by user. diff --git a/src/libisofs.h b/src/libisofs.h index d754306..755542e 100644 --- a/src/libisofs.h +++ b/src/libisofs.h @@ -13,6 +13,8 @@ typedef struct Iso_Node IsoNode; typedef struct Iso_Dir IsoDir; typedef struct Iso_Symlink IsoSymlink; +typedef struct Iso_File IsoFile; + typedef struct Iso_Dir_Iter IsoDirIter; /** diff --git a/src/node.h b/src/node.h index deff24e..a7e2cf3 100644 --- a/src/node.h +++ b/src/node.h @@ -13,6 +13,7 @@ */ #include "libisofs.h" +#include "stream.h" #include #include @@ -97,7 +98,7 @@ struct Iso_File * Higher weighting filesare written at the beginning of image */ int sort_weight; - + IsoStream *stream; }; struct Iso_Symlink diff --git a/src/stream.h b/src/stream.h index 3a89c5e..ca5cab1 100644 --- a/src/stream.h +++ b/src/stream.h @@ -25,10 +25,7 @@ struct Iso_Stream * Opens the stream. * * @return - * 1 on success, < 0 on error, 2 file is smaller than expect, - * 3 file is larger than expected (2 and 3 are not errors, they're - * handled by read_block, see there. Moreover, IsooStream - * implementations doesn't need to check that) + * 1 on success, < 0 on error */ int (*open)(IsoStream *stream); @@ -39,44 +36,22 @@ struct Iso_Stream int (*close)(IsoStream *stream); /** - * Get the size (in bytes) of the stream. This function must return - * always the same size, even if the underlying source file has changed. + * Get the size (in bytes) of the stream. */ off_t (*get_size)(IsoStream *stream); /** - * Read a block (2048 bytes) from the stream. + * Attempts to read up to count bytes from the given stream into + * the buffer starting at buf. * - * This function should always read the full 2048 bytes, blocking if - * needed. When it reaches EOF, the buf is filled with 0's, if needed. - * Note that the EOF is not reported in that call, but in the next call. - * I.e., when the EOF is reported you can be sure that the function - * has not written anything to the buffer. If the file size is a multiple - * of block size, i.e N*2048, the read_block reports the EOF just when - * reading the N+1 block. + * The stream must be open() before calling this, and close() when no + * more needed. * - * Note that EOF refers to the original size as reported by get_size. - * If the underlying source size has changed, this function should take - * care of this, truncating the file, or filling the buffer with 0s. I.e. - * this function return 0 (EOF) only when get_size() bytes have been - * readed. - * - * On an I/O error, or a file smaller than the expected size, this - * function returns a [specific error code], and the buffer is filled - * with 0s. Subsequent calls will still return an error code and fill - * buffer with 0's, until EOF (as defined above) is reached, and then - * the function will return 0. - * - * Note that if the current size is larger than expected, you don't get - * any error on reading. - * - * @param buf - * Buffer where data fill be copied, with at least 2048 bytes. - * @return - * 1 sucess, 0 EOF, < 0 error (buf is filled with 0's) + * @return + * number of bytes read, 0 if EOF, < 0 on error */ - int (*read_block)(IsoStream *stream, void *buf); - + int (*read)(IsoStream *stream, void *buf, size_t count); + /** * Whether this Stram can be read several times, with the same results. * For example, a regular file is repeatable, you can read it as many @@ -89,6 +64,6 @@ struct Iso_Stream int refcount; void *data; -} +}; #endif /*STREAM_H_*/