Files | |
file | memfs.h |
Simple API for managing an in-memory, virtual file system. | |
file | memfs.c |
Implementation of an input/output device tied to in-memory data. | |
Data Structures | |
struct | _MFSFILE |
Describes a file. More... | |
struct | _MFSDIR |
Describes a directory. More... | |
struct | _MFSNODE |
Describes a node, which is a named entry within the filesystem, and is either a file or a directory. More... | |
struct | _MFSITERELEMENT |
Helper structure for storing the state of an iteration. More... | |
struct | _MFSITERSTATE |
Encapsulates the current state of an iteration. More... | |
Macros | |
#define | COMPRESS_NEW_FILES TRUE |
Tune this to decide whether compression should be applied to new files created at run-time. More... | |
Typedefs | |
typedef struct _MFSFILE | MFSFILE |
Describes a file. | |
typedef struct _MFSDIR | MFSDIR |
Describes a directory. | |
typedef struct _MFSNODE | MFSNODE |
Describes a node, which is a named entry within the filesystem, and is either a file or a directory. More... | |
typedef struct _MFSFILEDESC | MFSFILEDESC |
Encapsulates the information required to control access to an open file. | |
typedef struct _MFSITERELEMENT | MFSITERELEMENT |
Helper structure for storing the state of an iteration. | |
typedef struct _MFSITERSTATE | MFSITERSTATE |
Encapsulates the current state of an iteration. More... | |
Enumerations | |
enum | { MFS_File , MFS_Directory } |
A node within the filesystem is either a file or a directory, and we use these markers to indicate which. More... | |
Functions | |
MFSNODE * | MFSFindRelative (MFSNODE *pRoot, char *pszFilename, MFSNODE **ppParent, uint32 *pIndex, DEVICE_result *err) |
Locate a file node, relative to the given root, according to its pathname. More... | |
HqBool | MFSOpen (MFSNODE *pRoot, char *pszFilename, int32 openFlags, MFSFILEDESC **ppDesc, DEVICE_result *err) |
Open or create a file for reading and/or writing. More... | |
HqBool | MFSClose (MFSFILEDESC *pDesc) |
Close a file that was previously opened with MFSOpen(). More... | |
MFSFILE * | MFSGetFile (MFSFILEDESC *pDesc) |
Return the underlying file from its open descriptor. More... | |
int32 | MFSRead (MFSFILEDESC *pDesc, uint8 *buffer, int32 cbLen, DEVICE_result *err) |
Read a specified number of bytes from the current location of an open file. More... | |
int32 | MFSWrite (MFSFILEDESC *pDesc, uint8 *buffer, int32 cbLen, DEVICE_result *err) |
Write a specified number of bytes to an open file at the current location, expanding the file as necessary. More... | |
int32 | MFSWriteString (MFSFILEDESC *pDesc, char *pszString, DEVICE_result *err) |
Write a specified NUL-terminated character string to an open file at the current location, expanding the file as necessary. The terminating NUL character itself is not written. More... | |
HqBool | MFSSeek (MFSFILEDESC *pDesc, Hq32x2 *pDestination, int32 flags, DEVICE_result *err) |
Set (or query) the current the position in an open file. More... | |
HqBool | MFSAvail (MFSFILEDESC *pDesc, Hq32x2 *pAvail, int32 reasonFlag) |
Determine the number of bytes that are currently available to be read from an open file. More... | |
HqBool | MFSSetCompression (MFSFILEDESC *pDesc, HqBool fCompress) |
Controls whether the file's data buffer will be compressed (or re-compressed) when the file is closed. More... | |
int32 | MFSDelete (MFSNODE *pRoot, char *pszFilename, DEVICE_result *err) |
Delete a file or directory, and completely release all of its associated memory resources. More... | |
int32 | MFSRename (MFSNODE *pRoot, char *pszFromName, char *pszToName, DEVICE_result *err) |
Rename a file, preserving all of its contents and other properties. More... | |
MFSITERSTATE * | MFSIterBegin (MFSNODE *pRoot, void *pPrivate) |
Begin an iteration over all or part of the file system. More... | |
HqBool | MFSIterNext (MFSITERSTATE *pState) |
Proceed to the first (or next) file in an iteration sequence. More... | |
void | MFSIterEnd (MFSITERSTATE *pState) |
Close an iteration sequence. More... | |
MFSNODE * | MFSIterNode (MFSITERSTATE *pState) |
Obtain a direct pointer to the MFS_File node of the current iteration step. More... | |
uint32 | MFSIterNameLength (MFSITERSTATE *pState, HqBool fLeadingSlash) |
Obtain the pathname length of the file at the current iteration step. More... | |
HqBool | MFSIterName (MFSITERSTATE *pState, char *pszFilenameBuf, uint32 bufLen, HqBool fLeadingSlash) |
Obtain the pathname of the file at the current iteration step. More... | |
MFSNODE * | MFSNewRoot (char *pszRootName) |
Construct and return a completely new root directory node. More... | |
MFSNODE * | MFSCopyTree (MFSNODE *pMFSRoot, HqBool fCopyFileData) |
Construct and return a completely new filesystem tree by making a recursive copy of the given tree. More... | |
void | MFSReleaseRoot (MFSNODE *pMFSRoot) |
Destroy the given root node, and the entire virtual filesystem descended from it. More... | |
void | MFSMemUsage (MFSNODE *pNode, uint32 *pROMSize, uint32 *pRAMSize) |
Calculate the amount of memory currently in use by the virtual filesystem descended from the given node. More... | |
This API specifies a simple tree data structure for representing one or more virtual file systems. Each system is modelled as a tree of MFSNODE objects, where each node represents either a file or a directory. A file is always a leaf node, whereas a directory contains pointers down to child nodes. As with any filesystem, each node is assigned a name, meaning that nodes may be addressed using a path. Currently, only 8-bit ASCII filenames are supported. The tree may be arbitrarily nested. (Pathnames are expressed using a forward-slash /
character as the separator).
These data structures are designed to be statically-declarable, but dynamically-growable. A filesystem need not start off as empty, although it can do. It is possible to write (or generate) a series of static C data declarations to describe the initial state of a whole tree. Global Graphics provides an "Import Tool", which can scan an existing directory on disk, and represent it as a virtual filesystem within the application's memory. This can eliminate avoid the need for configuration files on disk.
Whether from an empty initial state, or from a pre-declared static state, it is possible to access and modify files, and to create new ones. Such modifications, of course, persist only for the lifetime of the application, since the entire filesystem is held in process-local memory. Functions are provided to open and create files, and for reading and writing data. There are also functions for managing the tree: such as locating, deleting and renaming files. See the individual function descriptions for further details in each case.
The API supports compression and decompression via the ZLIB interface. This happens transparently, but a file's data stream can only be in a compressed state when the file is closed. In order to keep the code simple, live stream-based compression/decompression of open files is not supported. As soon as a file is opened with MFSOpen(), its data stream will become uncompressed in its entirety, and will remain so until the file is closed, whereupon the data will be re-compressed.
When a file system has a statically-declared initial state (as might be generated by the Import Tool), it is likely that the Import Tool will apply compression to the data buffers where possible. If it does so, it must do so via the ZLIB interface. Statically-declared filesystems are expected to be the typical case for compression. However, a policy of compressing dynamically-created MFS files can also be put in place by tuning the COMPRESS_NEW_FILES macro, defined in this header file. If this macro is set to FALSE
, no compression will be applied to fresh files created at runtime.
The implementation of this API is thread-safe, to the extent that there is no undocumented global state within the implementation that might prevent concurrent use. However, the tree structures themselves are not protected by this layer. Broadly, this means that concurrent use of this API should be limited to disjoint filesystem trees, or disjoint portions of a single tree. For convenience, there are some exceptions to this general rule, particularly when read-only access is required to files and directories.
This API is primarily aimed at implementing a device in terms of the Core RIP Device Interface. Some of the flags and return codes used here are deliberately specified to match the contracts of the Device Interface. However, this API can also be used standalone, instead of (or even as well as) just providing the support for a device implementation.
#define COMPRESS_NEW_FILES TRUE |
Tune this to decide whether compression should be applied to new files created at run-time.
See also the MFSSetCompression() function, which allows the caller to decide whether to apply compression for individual files.
typedef struct _MFSITERSTATE MFSITERSTATE |
Encapsulates the current state of an iteration.
Describes a node, which is a named entry within the filesystem, and is either a file or a directory.
If this node is a file, then it is a leaf node. If it is a directory, then it contains an array of pointers to the child MFSNODE structures.
Nodes do not contain parent pointers.
anonymous enum |
A node within the filesystem is either a file or a directory, and we use these markers to indicate which.
Enumerator | |
---|---|
MFS_File | Denotes an ordinary file. |
MFS_Directory | Denotes a directory. |
HqBool MFSAvail | ( | MFSFILEDESC * | pDesc, |
Hq32x2 * | pAvail, | ||
int32 | reasonFlag | ||
) |
Determine the number of bytes that are currently available to be read from an open file.
It is never permissible to call this function concurrently with the same descriptor. It is, however, permissible to call the function concurrently with different descriptors on the same underlying file, provided that there are no open descriptors with write access on the file.
[in] | pDesc | A pointer to the file descriptor, obtained from an earlier call to MFSOpen(). |
[out] | pAvail | Receives a count of available bytes upon successful return. |
[in] | reasonFlag | One of SW_BYTES_AVAIL_REL or SW_BYTES_TOTAL_ABS, as per the Core RIP Device Interface. Since files are stored in memory, the maximum extent of the data is always known, so precise information can be returned in both cases. |
TRUE
upon success; FALSE
upon failure. This return convention is directly compatible with DEVICETYPE::bytes_file() in the Core RIP Device Interface. HqBool MFSClose | ( | MFSFILEDESC * | pDesc | ) |
Close a file that was previously opened with MFSOpen().
[in] | pDesc | A pointer to the file descriptor, obtained from an earlier call to MFSOpen(). |
TRUE
upon success; FALSE
upon failure. Note that the Core RIP Device Interfaces uses a different return convention for the DEVICETYPE::open_file() function. When implementing such a function in terms of MFSOpen(), you must convert TRUE
to 0, and FALSE
to -1 respectively. Construct and return a completely new filesystem tree by making a recursive copy of the given tree.
Use MFSReleaseRoot() to recursively destroy the copy when it is no longer needed.
MFSNewRoot() and MFSCopyTree() are the only two functions that can be used to create a completely fresh virtual filesystem tree. All other functions operate on nodes that are already linked into an existing tree.
The directory node returned by this function is stand-alone, and completely unlinked from any existing virtual filesystems being managed by MFS.
[in] | pMFSRoot | Pointer to the root of the tree to be copied. |
[in] | fCopyFileData | Controls whether the underlying file data buffers are copied into the new tree. If you pass TRUE , then fresh copies of the file data will be made in the new tree. Otherwise, the underlying file data will be shared by the new tree and the original tree. Sharing the file data will use less memory, but it means that modifications to files in the new tree can potentially have side-effects on the files in the original tree. |
NULL
, which is best interpreted as being due to memory exhaustion. int32 MFSDelete | ( | MFSNODE * | pRoot, |
char * | pszFilename, | ||
DEVICE_result * | err | ||
) |
Delete a file or directory, and completely release all of its associated memory resources.
This function can be used to delete a single file, or to recursively delete a directory and all of its descendants, regardless of their contents. If you consider this function as being like the UNIX rm
command, then there is an implicit -rf
.
This function will fail if the specified file is currently open with any level of access. In the recursive case, the function will similarly fail if any open files are included amongst the directory's descendants.
It is permissible to call this function concurrently, provided that all concurrent calls are given disjoint (sub-)trees as the first argument.
[in] | pRoot | Root of the file system or sub-tree. This can be any directory node, as long as the filename is expressed relative to it. |
[in] | pszFilename | The pathname of the required file or directory, expressed relative to pRoot, and with forward-slash characters separating the path elements. |
[out] | err | Pointer to an integer error code, specified according to the Core RIP Device Interface. If the function fails, this will receive the appropriate device error code. |
MFSNODE* MFSFindRelative | ( | MFSNODE * | pRoot, |
char * | pszFilename, | ||
MFSNODE ** | ppParent, | ||
uint32 * | pIndex, | ||
DEVICE_result * | err | ||
) |
Locate a file node, relative to the given root, according to its pathname.
This function may be called concurrently, even on shared directory trees. However, it should not be called concurrently with MFSOpen(), MFSRename() or MFSDelete(), unless such concurrent calls are operating on disjoint (sub-)trees, otherwise race conditions result.
[in] | pRoot | The root of the search. |
[in] | pszFilename | The pathname of the required file, expressed relative to pRoot, and with forward-slash characters separating the path elements. |
[out] | ppParent | If the function succeeds, this output parameter receives a pointer to the target node's parent node, which will be of type MFS_Directory. |
[out] | pIndex | If the function succeeds, this output parameter receives the index of the target node within its parent directory's child array. |
[out] | err | Pointer to an integer error code, specified according to the Core RIP Device Interface. If the function fails, this will receive the appropriate device error code. |
MFSFILE* MFSGetFile | ( | MFSFILEDESC * | pDesc | ) |
Return the underlying file from its open descriptor.
[in] | pDesc | A pointer to the file descriptor, obtained from an earlier call to MFSOpen(). |
MFSITERSTATE* MFSIterBegin | ( | MFSNODE * | pRoot, |
void * | pPrivate | ||
) |
Begin an iteration over all or part of the file system.
This function can be used to visit file nodes beneath the given directory. The iteration will recursively enter all nested directories, but the directories themselves are not visited as an explicit iteration step.
The function returns a pointer to an internally-allocated MFSITERSTATE structure, which maintains information about the current iteration state. This structure is initialized at a notional position before the first file. To visit the first file, you must make an initial call to MFSIterNext(), and so on to visit subsequent files.
At each iteration step, you can call MFSIterNameLength() and MFSIterName() to obtain the pathname of the current file, expressed relative to pRoot. You can also call MFSIterNode() to obtain a direct pointer to the current file node.
To avoid resource leaks, all calls to MFSIterBegin() must be matched by a later call to MFSIterEnd().
The following code fragment demonstrates the basic call pattern for iteration.
{ char filename[ MAXFILENAMELENGTH ]; MFSITERSTATE *pState = MFSIterBegin( pRoot, NULL ); while ( MFSIterNext( pState ) ) { if ( MFSIterName( pState, filename, sizeof( filename ), TRUE ) ) printf( "Visiting %s\n", filename ); else printf( "<Filename too long>\n" ); } MFSIterEnd( pState ); }
Backwards iteration is not supported, and no assumption should be made that files are visited in any particular order, such as alphabetical order.
It is legal to call MFSDelete() on the current file during iteration. It is also legal to call MFSRename(), although it is then undefined whether the destination file will then be visited later in the iteration.
The iteration function can be used to support an implementation of the DEVICETYPE::start_file_list() and DEVICETYPE::next_file() functions in the Core RIP Device Interface.
In general, iteration functions may be called concurrently, provided that they are "separate" iterations - that is, using different MFSITERSTATE structures.
[in] | pRoot | Root of the file system, or directory sub-tree to be traversed. |
[in] | pPrivate | Arbitrary pointer to caller-managed memory. This pointer will be installed into the MFSITERSTATE::pPrivate field. |
void MFSIterEnd | ( | MFSITERSTATE * | pState | ) |
Close an iteration sequence.
For more information, see MFSIterBegin().
[in] | pState | The current iteration state, as previously obtained from a call to MFSIterBegin(). This pointer becomes invalid upon return. |
HqBool MFSIterName | ( | MFSITERSTATE * | pState, |
char * | pszFilenameBuf, | ||
uint32 | bufLen, | ||
HqBool | fLeadingSlash | ||
) |
Obtain the pathname of the file at the current iteration step.
For more information, see MFSIterBegin().
[in] | pState | The current iteration state, as previously obtained from a call to MFSIterBegin(). |
[out] | pszFilenameBuf | A pointer to caller-managed memory, which will receive the pathname. The pathname will be expressed relative to the directory that was specified to MFSIterBegin(), and will use forward-slash characters as path separators. A leading foward-slash and a terminating NUL character are included. |
[in] | bufLen | The number of bytes available in the buffer. If this does not accommodate the pathname (including its NUL terminator), the function will fail, and no bytes will be written into the buffer. Use MFSIterNameLength() to obtain the required buffer length, and remember to use the same value for fLeadingSlash. |
[in] | fLeadingSlash | Flag indicating whether a leading slash should be included in the name. |
TRUE
upon success; FALSE
upon failure. uint32 MFSIterNameLength | ( | MFSITERSTATE * | pState, |
HqBool | fLeadingSlash | ||
) |
Obtain the pathname length of the file at the current iteration step.
For more information, see MFSIterBegin().
[in] | pState | The current iteration state, as previously obtained from a call to MFSIterBegin(). |
[in] | fLeadingSlash | Flag indicating whether a leading slash should be taken into account when computing the filename. This will just increase the returned value by 1 character, but the parameterization is in order to be consistent with MFSIterName(). |
HqBool MFSIterNext | ( | MFSITERSTATE * | pState | ) |
Proceed to the first (or next) file in an iteration sequence.
For more information, see MFSIterBegin().
[in] | pState | The current iteration state, as previously obtained from a call to MFSIterBegin(). |
TRUE
if the iteration has proceeded; FALSE
if the iteration has been exhausted. MFSNODE* MFSIterNode | ( | MFSITERSTATE * | pState | ) |
Obtain a direct pointer to the MFS_File node of the current iteration step.
For more information, see MFSIterBegin().
[in] | pState | The current iteration state, as previously obtained from a call to MFSIterBegin(). |
Calculate the amount of memory currently in use by the virtual filesystem descended from the given node.
This function recursively walks over the tree, and totals up the file data buffer space being used. The result is approximate, since the memory consumption of MFS internal data structures is not included, but this is generally small in comparison with the actual file data.
The function produces separate totals for ROM consumption and RAM consumption. ROM consumption extends to initial file data that was imported from an external source and embedded in the compiled binaries. RAM consumption extends to all further space that was allocated at runtime. RAM consumption will tend to fluctuate with usage of the filesystem, whereas ROM consumption is fixed (effectively at application link time).
[in] | pNode | Root node of the virtual filesystem to be examined. This is allowed to be NULL , in which case the function does nothing. |
[out] | pROMSize | This number is increased by the number of bytes of ROM being consumed by the filesystem. The caller should initialize this to zero to obtain a total for just the given node. There is no handling for overflow. If files have been deleted from the tree, their ROM consumption is no longer included by this function, although the memory is effectively "leaked" and cannot be recovered. (RAM space, by comparison, is never leaked). |
[out] | pRAMSize | This number is increased by the number of bytes of dynamic heap memory being consumed by the filesystem. The caller should initialize this to zero to obtain a total for just the given node. There is no handling for overflow. |
MFSNODE* MFSNewRoot | ( | char * | pszRootName | ) |
Construct and return a completely new root directory node.
Use MFSReleaseRoot() to destroy this root and the entire virtual filesystem descended from it.
MFSNewRoot() and MFSCopyTree() are the only two functions that can be used to create a completely fresh virtual filesystem tree. All other functions operate on nodes that are already linked into an existing tree.
The directory node returned by this function is stand-alone, and completely unlinked from any existing virtual filesystems being managed by MFS.
[in] | pszRootName | The identifier to use for the root node, since all nodes must have a name. Note that this name does not form a part of any path relative to this root. |
NULL
if there has been a failure to allocate the necessary memory. HqBool MFSOpen | ( | MFSNODE * | pRoot, |
char * | pszFilename, | ||
int32 | openFlags, | ||
MFSFILEDESC ** | ppDesc, | ||
DEVICE_result * | err | ||
) |
Open or create a file for reading and/or writing.
This function can be called concurrently, provided that all concurrent calls are given disjoint (sub-)trees as the first argument. Similar caveats apply with concurrent calls to MFSDelete() and MFSRename().
[in] | pRoot | Root of the file system or sub-tree. This may be any directory node within the tree, as long as the filename is expressed relative to it. |
[in] | pszFilename | The pathname of the required file, expressed relative to pRoot, and with forward-slash characters separating the path elements. |
[in] | openFlags | Specified as per the Core RIP Device Interface, indicating the required level of access to the file. The Memory File System allows concurrent read access, but write access is always exclusive. This parameter can also indicate whether to create a new file. |
[out] | ppDesc | If the function succeeds, receives a pointer to the file descriptor. This pointer must subsequently be passed into all functions used to access the file while it is open. Ultimately, the pointer must be passed to MFSClose() in order to close the file. |
[out] | err | Pointer to an integer error code, specified according to the Core RIP Device Interface. If the function fails, this will receive the appropriate device error code. |
TRUE
upon success; FALSE
upon failure. Note that the Core RIP Device Interfaces uses a different return convention for the DEVICETYPE::open_file() function. When implementing such a function in terms of MFSOpen(), you must convert TRUE
to 0, and FALSE
to -1 respectively. int32 MFSRead | ( | MFSFILEDESC * | pDesc, |
uint8 * | buffer, | ||
int32 | cbLen, | ||
DEVICE_result * | err | ||
) |
Read a specified number of bytes from the current location of an open file.
This function has no side-effects on the underlying file. Therefore, it is permissible to call this function concurrently for different descriptors on the same file, but not with identical descriptors.
[in] | pDesc | A pointer to the file descriptor, obtained from an earlier call to MFSOpen(). The file must have been opened with read access: SW_RDONLY or SW_RDWR. |
[out] | buffer | Pointer to caller-managed data buffer, which will receive the bytes. |
[in] | cbLen | The maximum number of bytes to read. |
[out] | err | Pointer to an integer error code, specified according to the Core RIP Device Interface. If the function fails, this will receive the appropriate device error code. |
void MFSReleaseRoot | ( | MFSNODE * | pMFSRoot | ) |
Destroy the given root node, and the entire virtual filesystem descended from it.
[in] | pMFSRoot | The root node, which must have previously been allocated with either MFSNewRoot() or MFSCopyTree(). Never call MFSReleaseRoot() with a non-root node from within another virtual filesystem. Use MFSDelete() instead. |
int32 MFSRename | ( | MFSNODE * | pRoot, |
char * | pszFromName, | ||
char * | pszToName, | ||
DEVICE_result * | err | ||
) |
Rename a file, preserving all of its contents and other properties.
It is permissible to call this function concurrently, provided that all concurrent calls are given disjoint (sub-)trees as the first argument.
[in] | pRoot | Root of the file system or sub-tree. This can be any directory node, as long as the filenames are expressed relative to it. |
[in] | pszFromName | The pathname of the source file, expressed relative to pRoot, and with forward-slash characters separating the path elements. The function will fail if this pathname designates a file that is currently open with any level of access. The function will also fail if this pathname does not exist, or if it designates a directory. |
[in] | pszToName | The pathname of the destination file, expressed relative to pRoot, and with forward-slash characters separating the path elements. If this pathname denotes any file or directory that already exists, the function will fail. |
[out] | err | Pointer to an integer error code, specified according to the Core RIP Device Interface. If the function fails, this will receive the appropriate device error code. |
HqBool MFSSeek | ( | MFSFILEDESC * | pDesc, |
Hq32x2 * | pDestination, | ||
int32 | flags, | ||
DEVICE_result * | err | ||
) |
Set (or query) the current the position in an open file.
It is never permissible to call this function concurrently with the same file descriptor. It is, however, permissible to call the function concurrently with different descriptors on the same underlying file, provided that there are no open descriptors with write access on the file.
[in] | pDesc | A pointer to the file descriptor, obtained from an earlier call to MFSOpen() (with any level of access). |
[in] | pDestination | Specifies the file pointer adjustment, and receives the absolute file position if the function returns successfully. |
[in] | flags | One of SW_SET, SW_INCR or SW_XTND, as per the Core RIP Device Interface. This determines how the pDestination argument is treated on entry. However, the updated pDestination is always an absolute file pointer on exit. To query the current file pointer without modifying it, use SW_INCR and supply a pointer to a zero-valued Hq32x2 (note that this does not mean a NULL pointer). |
[out] | err | Pointer to an integer error code, specified according to the Core RIP Device Interface. If the function fails, this will receive the appropriate device error code. |
TRUE
upon success, in which case pDestination is updated with the current file pointer. FALSE
upon failure, in which case pDestination is not updated. This return convention is directly compatible with DEVICETYPE::seek_file() in the Core RIP Device Interface HqBool MFSSetCompression | ( | MFSFILEDESC * | pDesc, |
HqBool | fCompress | ||
) |
Controls whether the file's data buffer will be compressed (or re-compressed) when the file is closed.
This function can only be called when the file's data buffer is currently in an uncompressed state. This will be the case if the file was opened for writing, or for random-access reading. In other cases, it is less certain.
Normally, when a file is closed, its data buffer is retained in a compressed state to save on memory usage. There might be cases where this is undesirable. For instance, if a large file is opened and closed many times in rapid succession, a runtime expense will be incurred in decompression (and re-compression) of the data. The caller might use this function to de-activate the compression for periods of such activity. The caller might also use this function when storing data that has already been compressed, in which case there is little point in trying to compress it again.
The most typical use of this function is immediately after creation of a new file with MFSOpen().
[in] | pDesc | A pointer to the file descriptor, obtained from an earlier call to MFSOpen(). |
[in] | fCompress | Supply TRUE to indicate that the file buffer should be compressed when the file is closed, or FALSE to indicate that it shouldn't. |
TRUE
if the function succeeds, otherwise FALSE
. int32 MFSWrite | ( | MFSFILEDESC * | pDesc, |
uint8 * | buffer, | ||
int32 | cbLen, | ||
DEVICE_result * | err | ||
) |
Write a specified number of bytes to an open file at the current location, expanding the file as necessary.
This function has side-effects on the underlying file. Therefore, it is never permissible to call this function concurrently with descriptors on the same file. It is also never permissible to call MFSRead() concurrently with MFSWrite() with descriptors on the same underlying file.
[in] | pDesc | A pointer to the file descriptor, obtained from an earlier call to MFSOpen(). The file must have been opened with write access: SW_WRONLY or SW_RDWR. |
[in] | buffer | Pointer to caller-managed data buffer, from which bytes will be copied into the file. |
[in] | cbLen | The maximum number of bytes to write. |
[out] | err | Pointer to an integer error code, specified according to the Core RIP Device Interface. If the function fails, this will receive the appropriate device error code. |
int32 MFSWriteString | ( | MFSFILEDESC * | pDesc, |
char * | pszString, | ||
DEVICE_result * | err | ||
) |
Write a specified NUL-terminated character string to an open file at the current location, expanding the file as necessary. The terminating NUL character itself is not written.
This function has side-effects on the underlying file. Therefore, it is never permissible to call this function concurrently with descriptors on the same file. It is also never permissible to call MFSRead() or MFSWrite() concurrently with MFSWriteString(), with descriptors on the same underlying file.
[in] | pDesc | A pointer to the file descriptor, obtained from an earlier call to MFSOpen(). The file must have been opened with write access: SW_WRONLY or SW_RDWR. |
[in] | pszString | A pointer to caller-managed string memory. The string should be NUL-terminated, and should be an ANSI or multi-byte encoded character string. |
[out] | err | Pointer to an integer error code, specified according to the Core RIP Device Interface. If the function fails, this will receive the appropriate device error code. |