Reputation: 31
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.
Upvotes: 1
Views: 1480
Reputation: 31
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.
Upvotes: 2
Reputation: 23614
Let me notify you that fread
shifts current file position. This means that you don't need invoke fseek
each time. From this perspective may be you code can avoid implementation of resseek
by simple increasing Buffer
pointer
Upvotes: 0
Reputation: 5411
The file handle contains not only the data but also it's length and current position. You have to duplicate that. (handwirtten code, unproven):
struct resFile
{
char* pData;
int iLenght;
int iCurrPosition;
};
size_t resread( void* buffer, size_t size, size_t count, resFile* resource)
{
int ActualRead = min(size*count, resource->iLenght - resource->iCurrPosition);
memcpy(buffer, resource->pData + resource->iCurrPosition, ActualRead);
resource->iCurrPostion += ActualRead;
return ActualRead;
}
Upvotes: 1