PHYSFS_Io(3)

πŸ“¦
version 3.2.0 Β· 5 versions
, in arch rolling, fedora 44

🌸 PHYSFS_Io β€” bestie edition 🌸

okay so real talk, this is PHYSFS_Io(3) straight out of the Library Functions Manual, and it's the abstract i/o interface in physfs. advanced stuff. buckle up. πŸŽ€


✨ NAME ✨

PHYSFS_Io β€” an abstract i/o interface. that's it, that's the whole name section. πŸ’…


πŸ¦‹ SYNOPSIS πŸ¦‹

#include <physfs.h>

πŸ“¦ Data Fields

  • PHYSFS_uint32 version β€” binary compatibility information. the receipts of "which version are we even on". 🧾
  • void * opaque β€” instance data for this struct. your little secret stash per-instance.
  • PHYSFS_sint64(* read )(struct PHYSFS_Io *io, void *buf, PHYSFS_uint64 len) β€” read more data. gimme bytes pls. πŸ“–
  • PHYSFS_sint64(* write )(struct PHYSFS_Io *io, const void *buffer, PHYSFS_uint64 len) β€” write more data. putting bytes out into the world. ✍️
  • int(* seek )(struct PHYSFS_Io *io, PHYSFS_uint64 offset) β€” move i/o position to a given byte offset from start. teleport but for a cursor. ⭐
  • PHYSFS_sint64(* tell )(struct PHYSFS_Io *io) β€” report current i/o position. "where am i" energy. πŸ“
  • PHYSFS_sint64(* length )(struct PHYSFS_Io *io) β€” determine size of the i/o instance's dataset. how big is the vibe. πŸ“
  • struct PHYSFS_Io *(* duplicate )(struct PHYSFS_Io *io) β€” duplicate this i/o instance. clone arc. πŸ‘―
  • int(* flush )(struct PHYSFS_Io *io) β€” flush resources to media, or wherever. "or wherever" is so real. 🚰
  • void(* destroy )(struct PHYSFS_Io *io) β€” cleanup and deallocate i/o instance. rest in peace bestie. πŸ•ŠοΈ

πŸ’– Detailed Description πŸ’–

An abstract i/o interface. literally the whole point. 🌈

⚠️ Warning β€” this is advanced, hardcore stuff. you don't need this unless you really know what you're doing. most apps will not need this. if you're reading this and going "hmm should i use this for my todo app", the answer is no, queen. step away. πŸ™ˆ

so like, historically, PhysicsFS gave you access to the physical filesystem and the archives within that filesystem. cute. normal. but sometimes you need more power. maybe you need to provide an archive that's entirely contained in RAM 🧠, or you need to bridge some other file i/o API to PhysicsFS, or you need to translate the bits β€” like, perhaps you have a standard .zip file that's encrypted, and you need to decrypt on the fly for the unsuspecting zip archiver. sneaky. iconic. πŸ‘‘

a PHYSFS_Io is the interface that Archivers use to get archive data. historically this has mapped to file i/o on the physical filesystem, but as of PhysicsFS 2.1, applications can provide their own i/o implementations at runtime. glow up era fr. ✨

this interface isn't necessarily a good universal fit for i/o. there are a few requirements of note, and we're listing them because we love you:

  • they only do blocking i/o (at least, for now). no multitasking girlbossery. πŸ›‘
  • they need to be able to duplicate. if you have a file handle from fopen(), you need to be able to create a unique clone of it (so we have two handles to the same file that can both seek/read/etc without stepping on each other). no shared toothbrushes. πŸͺ₯
  • they need to know the size of their entire data set.
  • they need to be able to seek and rewind on demand. βͺ

…in short, you're probably not going to write an HTTP implementation. πŸ’€ correct. don't.

Thread safety: PHYSFS_Io implementations are not guaranteed to be thread safe in themselves. under the hood where PhysicsFS uses them, the library provides its own locks. so if you plan to use them directly from separate threads, you should either use mutexes to protect them, or just don't use the same PHYSFS_Io from two threads at the same time. pick a struggle. πŸ”’

See also

PHYSFS_mountIo β€” go read that one next, bestie. 🫢


πŸŽ€ Field Documentation πŸŽ€

πŸ•ŠοΈ void(* PHYSFS_Io::destroy) (struct PHYSFS_Io *io)

cleanup and deallocate i/o instance. free associated resources, including (opaque) if applicable.

this function must always succeed: as such, it returns void. the system may call your flush() method before this. you may report failure there if necessary. this method may still be called if flush() fails, in which case you'll have to abandon unflushed data and other failing conditions and clean up. messy but you gotta. 🧹

once this method is called for a given instance, the system will assume it is unsafe to touch that instance again and will discard any references to it. it's over, don't text it back. πŸ’€

Parameters

  • s β€” the i/o instance to destroy.

πŸ‘― struct PHYSFS_Io *(* PHYSFS_Io::duplicate) (struct PHYSFS_Io *io)

duplicate this i/o instance. this needs to result in a full copy of this PHYSFS_Io, that can live completely independently. the copy needs to be able to perform all its operations without altering the original, including either object being destroyed separately (so, for example: they can't share a file handle; they each need their own). no codependency, we're healing. 🌱

if you can't duplicate a handle, it's legal to return NULL, but you almost certainly need this functionality if you want to use this PHYSFS_Io to back an archive. like. you need it. fr fr.

Parameters

  • io β€” the i/o instance to duplicate.

Returns

  • a new value for a stream's (opaque) field, or NULL on error.

🚰 int(* PHYSFS_Io::flush) (struct PHYSFS_Io *io)

flush resources to media, or wherever. this is the chance to report failure for writes that had claimed success earlier, but still had a chance to actually fail. accountability era. πŸ’… this method can be NULL if flushing isn't necessary.

this function may be called before destroy(), as it can report failure and destroy() can not. it may be called at other times, too. surprise visits. 🎁

Parameters

  • io β€” the i/o instance to flush.

Returns

  • zero on error, non-zero on success. (yes, that's the right way round, read it again 😭)

πŸ“ PHYSFS_sint64(* PHYSFS_Io::length) (struct PHYSFS_Io *io)

determine size of the i/o instance's dataset. return number of bytes available in the file, or -1 if you aren't able to determine. a failure will almost certainly be fatal to further use of this stream, so you may not leave this unimplemented. no skipping, this one's mandatory. 🚨

Parameters

  • io β€” the i/o instance to query.

Returns

  • total size, in bytes, of the dataset.

πŸ«™ void* PHYSFS_Io::opaque

instance data for this struct. each instance has a pointer associated with it that can be used to store anything it likes. this pointer is per-instance of the stream, so presumably it will change when calling duplicate(). this can be deallocated during the destroy() method. it's your little backpack. πŸŽ’

πŸ“– PHYSFS_sint64(* PHYSFS_Io::read) (struct PHYSFS_Io *io, void *buf, PHYSFS_uint64 len)

read more data. read (len) bytes from the interface, at the current i/o position, and store them in (buffer). the current i/o position should move ahead by the number of bytes successfully read. walking forward while snacking. πŸ“

you don't have to implement this; set it to NULL if not implemented. this will only be used if the file is opened for reading. if set to NULL, a default implementation that immediately reports failure will be used. it's giving "i simply will not". πŸ™…

Parameters

  • io β€” the i/o instance to read from.
  • buf β€” the buffer to store data into. it must be at least (len) bytes long and can't be NULL.
  • len β€” the number of bytes to read from the interface.

Returns

  • number of bytes read from file, 0 on EOF, -1 if complete failure.

⭐ int(* PHYSFS_Io::seek) (struct PHYSFS_Io *io, PHYSFS_uint64 offset)

move i/o position to a given byte offset from start. this method moves the i/o position, so the next read/write will be of the byte at (offset) offset. seeks past the end of file should be treated as an error condition. don't reach past the edge, bestie. πŸ›‘

Parameters

  • io β€” the i/o instance to seek.
  • offset β€” the new byte offset for the i/o position.

Returns

  • non-zero on success, zero on error.

πŸ“ PHYSFS_sint64(* PHYSFS_Io::tell) (struct PHYSFS_Io *io)

report current i/o position. return bytes offset, or -1 if you aren't able to determine. a failure will almost certainly be fatal to further use of this stream, so you may not leave this unimplemented. mandatory again, sorry babe. 🚨

Parameters

  • io β€” the i/o instance to query.

Returns

  • the current byte offset for the i/o position, -1 if unknown.

🧾 PHYSFS_uint32 PHYSFS_Io::version

binary compatibility information. this must be set to zero at this time. future versions of this struct will increment this field, so we know what a given implementation supports. we'll presumably keep supporting older versions as we offer new features, though. legacy support, we love her. πŸ‘‘

✍️ PHYSFS_sint64(* PHYSFS_Io::write) (struct PHYSFS_Io *io, const void *buffer, PHYSFS_uint64 len)

write more data. write (len) bytes from (buffer) to the interface at the current i/o position. the current i/o position should move ahead by the number of bytes successfully written. ✨

you don't have to implement this; set it to NULL if not implemented. this will only be used if the file is opened for writing. if set to NULL, a default implementation that immediately reports failure will be used. same energy as read β€” optional but judge-y. πŸ™ˆ

you are allowed to buffer; a write can succeed here and then later fail when flushing. note that PHYSFS_setBuffer() may be operating a level above your i/o, so you should usually not implement your own buffering routines. let the library cook. 🍳

Parameters

  • io β€” the i/o instance to write to.
  • buffer β€” the buffer to read data from. it must be at least (len) bytes long and can't be NULL.
  • len β€” the number of bytes to read from (buffer).

Returns

  • number of bytes written to file, -1 if complete failure.

πŸ’œ Author πŸ’œ

generated automatically by Doxygen for physfs from the source code. so no, a human didn't lovingly hand-type this, the robots did. respect the robots. πŸ€–


okay that's the whole page!! πŸ’– this was PHYSFS_Io from physfs, Version 3.2.0 β€” go forth, implement your abstract i/o, and remember: only blocking i/o, always be duplicatable, and never seek past EOF. slay responsibly. πŸ’…βœ¨πŸŒˆπŸ¦‹πŸŽ€

πŸ“¦ where this page comes from