Re: [AD] Clarifying and revising filesystem API

[ Thread Index | Date Index | More lists.liballeg.org/allegro-developers Archives ]


On 2009-04-16, Elias Pschernig <elias.pschernig@xxxxxxxxxx> wrote:
> Peter Hull wrote:
> > I thought the intent was that each add-in provided a function that
> > returned a directory-style AL_FS_ENTRY and then other entries
> > contained within could opened using that as the root.
> > e.g AL_FS_ENTRY* open_zipfile(const char* filename);
> > 
> > Regarding chdir, on osx we had a 'magic chdir' which started us off in
> > the resource dir of the application bundle. That was quite useful I
> > thought.
> 
> I like that. We will need a function like this then:
> 
> AL_FS_ENTRY *al_create_fs_entry_from_archive(AL_FS_ENTRY *archive, char const *path)
> 
> so e.g.
> 
> zip = al_open_zipfile("my.zip")
> picture_file = al_create_fs_entry_from_archive(zip, "mysha.png")
> picture = al_load_bitmap_entry(picture)
> 
> I think I could live with that. However, it means al_load_bitmap() would never 
> be able to use anything but the stdio filesystem - which is very different from 
> the original intent.

One of the problems with the PACKFILE extensions was that you *needed*
the _pf functions.  That was a deliberate decision at the time, but we
shouldn't do that again.  The _pf/_entry functions are still useful
for working with files-in-files.

Let me propose again a URI-like scheme, and strip the API down to
stream operations only.


## API: al_register_stream_handler

    bool al_register_stream_handler(const char *scheme,
	ALLEGRO_FILE_VTABLE *vtable);

Register a handler for a particular scheme.  The scheme must be a
non-empty string, not containing any colon characters, e.g. "file".
vtable is a pointer to a table of function pointers.  The functions will
be used to operate on the streams which were opened with the particular
scheme.

By default, the scheme "file" is registered and is handled using the C
library stdio functions.

Returns true on success, false on failure.  If the scheme was already
registered then the function fails.


## API: al_unregister_stream_handler

    bool al_unregister_stream_handler(const char *scheme);

Unregister a previously registered scheme.

Returns true on success, false on failure.


We have open/close and the various stream operations as before.

## API: al_fopen
## API: al_fclose
## API: al_fread
## API: al_fwrite
etc.


Sample usage:

# Local disk

    ALLEGRO_FILE *fp;

    /* No surprises */
    fp = al_fopen("relative/path", "r");
    fp = al_fopen("/absolute/path", "r");

    /* Using the scheme */
    fp = al_fopen("file:relative/path", "r");
    fp = al_fopen("file:/absolute/path", "r");

# PhysicsFS

    /* outside the API */
    PHYSFS_init(argv[0]);
    PHYSFS_addToSearchPath("myzip.zip", 1);
    PHYSFS_addToSearchPath("myzip2.zip", 1);
    PHYSFS_setWriteDir("mywritedir");

    /* in addon */
    al_register_stream_handler("phys", physfs_vtable);

    /* This will search the archives you added. */
    ALLEGRO_FILE *fp = al_fopen("phys:myfile.txt", "rb");

    /* Writing */
    fp = al_fopen("phys:myfile2.txt", "wb");

# Memory files

## Reading from a memory block

    /* Inside an addon */
    al_register_stream_handler("mem", memfile_vtable);

    /* Register a block of memory with the addon.  The addon returns a
     * token, which is a unique string to identify the memory block.
     * It's like a filename.  The token begins with "mem:" so you can
     * pass it directly to al_fopen().
     */
    const char *token = al_add_memfile(buf, bufsize);

    /* Pass the token to al_fopen. */
    bmp = al_load_bitmap(token);

    /* Remove the memory block from internal tables. */
    al_delete_memfile(token);

## Writing to a memory block

    /* You need to generate a unique token somehow.
     * The addon could help you, or you could follow a convention
     * like Java package names.
     */
    const char *token = "mem:b3457c95-db59-480d-91d0-9d0f61a6e7d1";

    /* Pass the token to al_fopen.  The memory file will be
     * automatically created ("w" mode) and grow as needed.
     */
    al_save_bitmap(token, bmp);

    /* Get a pointer to the memory block and its size. */
    size_t bufsize;
    const void *buf = al_search_memfile(token, &bufsize);

    dostuff(buf, bufsize);

    /* Free the memory block */
    al_delete_memfile(token);


Directory operations are outside of this API.  Use libc, PhysicsFS
or some VFS layer as you like.


Peter





Mail converted by MHonArc 2.6.19+ http://listengine.tuxfamily.org/