Search code examples
c++windowsvisual-studiofile-ioembedded-resource

Resource instead of external file C++


I am reusing some old code(originally developed on c, not c++) with some functions to open/read/manipulate text-files. The path to the text-files is passed to the functions as a string (char*) then opened using: FileToUse = fopen(filename, "rb"); then multiple calls to fread() and fseek() are used. This code is known to work for external text-files, but now I would like to include the textfiles as resources in my project (MFC C++ in visual studio).

I found some examples on the web on how to use resources rusulting in this code:

HINSTANCE hInst = AfxGetResourceHandle();
HRSRC hResource = FindResource(hInst, MAKEINTRESOURCE(IDR_TEXTFILE1), "TEXTFILE");

if (hResource){
  HGLOBAL hLoadedResource = LoadResource(hInst, hResource);
  if (hLoadedResource){
    const char* pResource = LockResource(hLoadedResource);
    if (pResource){
      DWORD dwResourceSize = SizeofResource(hInst, hResource);
      if (0 != dwResourceSize){                            // if(FileToUse){
        memcpy(&Buffer, pResource, (15 * 2));              //   fread($Buffer, 15, 2, FileToUse);
        pTemp = pResource + 200;                           //   fseek(FileToUse, 200, SEEK_SET);
        pTemp = pTemp + 100;                               //   fseek(FileToUse, 100, SEEK_CUR);
        pTemp = pResource + (dwResourceSize - 1) - 40;     //   fseek(FileToUse, -40, SEEK_END);
      }
    }
  }
}

I replaced the fread call by memcpy() as shown, but I'm missing the return value of fread (actual read items) and in the original code the filepointer was moved by fseek, I wonder whether my approach using a temporary pointer is correct.

My ultimate goal is to simulate the fread and fseek calls for resources with similar function prototypes:

size_t resread( void* buffer, size_t size, size_t count, char* resource );

int resseek( char* resource, long offset, int origin );

Any suggestions are much appreciated.


Solution

  • Thanks for your help, based on the Agent_L's suggestion this is what I came up with:

    Text-resource type:

    struct _resource {
        const char * content;      // File content
        size_t size;               // File size
        size_t ptrloc;             // 'Pointer' location
    };
    typedef struct _resource RES_TXT;
    

    resread based on fread:

    size_t resread( void* buffer, size_t size, size_t count, RES_TXT * resource)
    {
        size_t actualCount = ( resource->size - resource->ptrloc ) / size;
        actualCount = min( count, actualCount );
        if ( actualCount <= 0 ) return 0;
        memcpy(buffer, (resource->_ptr + resource->ptrloc), (actualCount * size) );
        resource->ptrloc += (actualCount * size);
        return actualCount;
    }
    

    and to complete resseek based on fseek:

    int resseek( RES_TXT * resource, long offset, int origin ) {
        size_t nextloc;
        switch ( origin ) {
            case SEEK_SET: nextloc = 0;
                break;
            case SEEK_CUR: nextloc = resource->ptrloc;
                break;
            case SEEK_END: nextloc = resource->size;
                break;
            default: return -1;
        }
        nextloc += offset;
        if ( nextloc >= 0  && nextloc < resource->size )
            resource->ptrloc = nextloc;
        else
            return -1;
        return 0;
    }
    

    Any call to fseek and fread can now be replaced to use a resource instead of an external file.