in ev3-api/src/ev3api_fs.c [14:79]
ER ev3_memfile_load(const char *path, memfile_t *p_memfile) {
ER ercd;
memfile_t memfile;
FILE *fin;
fin = NULL;
memfile.buffer = NULL;
CHECK_COND(path != NULL, E_PAR);
CHECK_COND(p_memfile != NULL, E_NOMEM);
/**
* Open file
*/
fin = fopen(path, "rb");
if (fin == NULL) {
API_WARN("Path '%s' is invalid.", path);
CHECK_COND(false, E_PAR);
}
/**
* Get file size & allocate memory
*/
long filesz;
CHECK_COND(fseek(fin, 0, SEEK_END) == 0, E_OBJ);
CHECK_COND((filesz = ftell(fin)) >= 0, E_OBJ); // TODO: Check when filesz == 0
CHECK_COND(fseek(fin, 0, SEEK_SET) == 0, E_OBJ);
memfile.buffersz = memfile.filesz = filesz;
assert((long)memfile.filesz == filesz);
CHECK_COND((memfile.buffer = malloc(memfile.buffersz)) != NULL, E_NOMEM);
/**
* Perform reading
*/
uint8_t *bufptr = memfile.buffer;
while (1) {
size_t bytesleft = (uint8_t*)memfile.buffer + memfile.filesz - bufptr;
if (bytesleft > 512) bytesleft = 512; // TODO: Check if this is really needed
size_t bytesread = fread(bufptr, 1, bytesleft, fin);
if (bytesread > 0) {
bufptr += bytesread;
} else {
break;
}
}
if (ferror(fin)) {
API_WARN("I/O failure when reading.");
CHECK_COND(false, E_PAR);
}
assert(bufptr == memfile.buffer + memfile.filesz);
*p_memfile = memfile;
ercd = E_OK;
/* Fall through */
error_exit:
if (ercd != E_OK) { // On error
if (p_memfile != NULL) p_memfile->buffer = NULL;
free(memfile.buffer);
}
if (fin != NULL) fclose(fin);
return ercd;
}