I’ve been tasked with updating a function which currently reads in a configuration file from disk and populates a structure:
static int LoadFromFile(FILE *Stream, ConfigStructure *cs)
{
int tempInt;
...
if ( fscanf( Stream, "Version: %d\n",&tempInt) != 1 )
{
printf("Unable to read version number\n");
return 0;
}
cs->Version = tempInt;
...
}
to one which allows us to bypass writing the configuration to disk and instead pass it directly in memory, roughly equivalent to this:
static int LoadFromString(char *Stream, ConfigStructure *cs)
A few things to note:
- The current LoadFromFile function is incredibly dense and complex, reading dozens of versions of the config file in a backward compatible manner, which makes duplication of the overall logic quite a pain.
- The functions that generate the config file and those that read it originate in totally different parts of the old system and therefore don’t share any data structures so I can’t pass those directly. I could potentially write a wrapper, but again, it would need to handle any structure passed in in a backwards compatible manner.
- I’m tempted to just pass the file as is in as a string (as in the prototype above) and convert all the fscanf’s to sscanf’s but then I have to handle incrementing the pointer along (and potentially dealing with buffer overrun errors) manually.
- This has to remain in C, so no C++ functionality like streams can help here
Am I missing a better option? Is there some way to create a FILE * that actually just points to a location in memory instead of on disk? Any pointers, suggestions or other help is greatly appreciated.
Since you are trying to keep the file data in memory, you should be able to use shared memory. POSIX shared memory is actually a variation of mapped memory. The shared memory object can be mapped into the process address space using mmap() if necessary. Shared memory is usually used as an IPC mechanism, but you should be able to use it for your situation.
The following example code uses POSIX shared memory (shm_open() & shm_unlink()) in conjunction with a
FILE *to write text to the shared memory object and then read it back.Note: I had to pass
-lrtto the linker when compiling this example with gcc on Linux.