diff --git a/src/dmdevfs.c b/src/dmdevfs.c index 999b0f8..9e2949d 100644 --- a/src/dmdevfs.c +++ b/src/dmdevfs.c @@ -56,6 +56,7 @@ typedef struct const char* path; // File path int mode; // File open mode int attr; // File attributes + size_t bytes_read; // Total bytes read (used for EOF calculation when driver has no eof API) } file_handle_t; /** @@ -253,6 +254,7 @@ dmod_dmfsi_dif_api_declaration( 1.0, dmdevfs, int, _fopen, (dmfsi_context_t ctx, handle->path = Dmod_StrDup(path); handle->mode = mode; handle->attr = attr; + handle->bytes_read = 0; *fp = handle; return DMFSI_OK; @@ -326,6 +328,7 @@ dmod_dmfsi_dif_api_declaration( 1.0, dmdevfs, int, _fread, (dmfsi_context_t ctx, // dmdrvi_read returns size_t (bytes read), not error code size_t bytes_read = dmdrvi_read(handle->driver->driver_context, handle->driver_handle, buffer, size); if(read) *read = bytes_read; + handle->bytes_read += bytes_read; return DMFSI_OK; } @@ -413,7 +416,9 @@ dmod_dmfsi_dif_api_declaration( 1.0, dmdevfs, long, _tell, (dmfsi_context_t ctx, /** * @brief Check if at end of file - * @note Device drivers typically operate in streaming mode - always return 0 (not at EOF) + * @note If the driver implements the eof API, it is used directly. + * Otherwise, EOF is determined by comparing bytes read against the file size. + * If file size is unavailable, 0 (not at EOF) is returned as EOF cannot be determined. */ dmod_dmfsi_dif_api_declaration( 1.0, dmdevfs, int, _eof, (dmfsi_context_t ctx, void* fp) ) { @@ -428,8 +433,24 @@ dmod_dmfsi_dif_api_declaration( 1.0, dmdevfs, int, _eof, (dmfsi_context_t ctx, v return 1; } - // Device drivers typically don't have EOF concept - // Return 0 (not at EOF) as devices can always potentially provide more data + file_handle_t* handle = (file_handle_t*)fp; + + // If the driver implements the eof API, delegate to it + dmod_dmdrvi_eof_t dmdrvi_eof = Dmod_GetDifFunction(handle->driver->driver, dmod_dmdrvi_eof_sig); + if(dmdrvi_eof != NULL) + { + return dmdrvi_eof(handle->driver->driver_context, handle->driver_handle); + } + + // Fallback: compare bytes read against file size reported by driver + dmdrvi_stat_t stat = {0}; + int result = driver_stat(handle->driver, handle->path, &stat); + if(result == 0) + { + return (handle->bytes_read >= (size_t)stat.size) ? 1 : 0; + } + + // Size not available - cannot determine EOF return 0; }