📄 filerw.c
字号:
{ GotFile = TRUE; /* no change in cyclic case, open succeeded in others */ /* scan back in fixed-size chunks as a check against a similar error in both write and read with the pattern cancelling each other out to give a false pass */ ReadSize = RESCAN_CHUNK_SIZE; /* for all but last iteration */ for (AbsPos = 0; AbsPos < TotalSize; AbsPos += RESCAN_CHUNK_SIZE) { if (AbsPos >= TotalSize - RESCAN_CHUNK_SIZE) /* cf loop condition */ { /* final pass, and we need to use less than the full chunk size */ ReadSize = TotalSize - AbsPos; /* pos for next read is count of bytes read so far */ } if (TEST_PASSED != ReadTestData (FileHandle, AbsPos, ReadSize)) { /* append context information to the error message */ STTBX_Print (("rescan block %i\n", AbsPos / RESCAN_CHUNK_SIZE)); Result = TEST_FAILED; break; } } } if (Result == TEST_PASSED && Variant != TEST_VARIANT_B) { /* third pass, reading according to pattern, redundant in Variant B */ if ((OpenMode & STAVFS_CYCLIC_MODE) == 0) { /* close and reopen gives a cleaner test where possible (non-cyclic files) */ GotFile = FALSE; /* don't try a close if this one (or the open) fails */ if (ST_NO_ERROR != STAVFS_CloseFile (FileHandle)) { STTBX_Print (("Error closing file\n")); Result = TEST_FAILED; } else if (ST_NO_ERROR != STAVFS_OpenFile (DiskHandle, STAVFS_NULL_FILE_HANDLE, "rwtest", STAVFS_READ_MODE | OpenMode, FileSize, &FileHandle)) { STTBX_Print (("Error re-opening file for read (2)\n")); Result = TEST_FAILED; } } else { /* need to seek read position back to the start of the file in cyclic mode */ I64_SetValue (0, 0, RestartPos); if (ST_NO_ERROR != STAVFS_SeekFile(FileHandle, RestartPos, STAVFS_START, FALSE)) { STTBX_Print (("Error resetting read position for cyclic file\n")); Result = TEST_FAILED; } } if (Result == TEST_PASSED) { GotFile = TRUE; /* no change in cyclic case, open succeeded in others */ AbsPos = 0; if (TEST_PASSED != RunTestPattern (FileHandle, &AbsPos, Pattern_p, CntParts, FALSE)) { Result = TEST_FAILED; /* message already displayed */ } } } /* close file if we still have one open */ if (GotFile) { if (ST_NO_ERROR != STAVFS_CloseFile (FileHandle)) { STTBX_Print (("Error closing file\n")); Result = TEST_FAILED; } } /* delete file in all cases where we sucessfully created it */ if (ST_NO_ERROR != STAVFS_DeleteFile (DiskHandle, STAVFS_NULL_FILE_HANDLE, "rwtest")) { STTBX_Print (("Error deleting file\n")); Result = TEST_FAILED; } } if (TEST_PASSED != ClosePartition("Dev1", DiskHandle)) { Result = TEST_FAILED; /* message already displayed */ } } return(Result);}/******************************************************************************Function Name : FirstDiff Description : Variation on memcmp, returns index of first difference within Len, or NODIFF if none Parameters : buffers to compare (a, b), maximum number of bytes to compare******************************************************************************/static S32 FirstDiff(U8 * a_p, U8 * b_p, S32 Len){ assert (Len >= 0); /* failure: bad unsigned -> signed converersion? */ /* optimise for perfect match, by only doing written-out search if memcmp fails */ if (memcmp(a_p, b_p, Len)) { int i; for (i = 0; i < Len; ++i) { if (a_p[i] != b_p[i]) return i; } } return -1; /* no discrepency */}/******************************************************************************Function Name : RWTestTotalSize Description : Calculate total size of the test specified by the given RWTestPart_t array. nb This is always designed to be a whole number of clusters. Parameters : Array start, number of elements******************************************************************************/static U32 RWTestTotalSize(RWTestPart_t * PartsList_p, int CntParts){ int i; U32 TotalSize = 0; for (i = 0; i < CntParts; ++i) { TotalSize += PartsList_p[i].BlockSize * PartsList_p[i].BlockReps; } return (TotalSize);}/******************************************************************************Function Name : WriteTestData Description : Write data appropriate to the given overall file position. The caller should append context information to error messages Parameters : file handle, absolute position, size to write******************************************************************************/static TestResult_t WriteTestData(STAVFS_FileHandle_t FileHandle, U32 AbsPos, U32 Size){ TestResult_t Result = TEST_PASSED; U32 DataPos = AbsPos % sizeof(StdData); /* where to start within StdData */ U32 MaxInitSize = sizeof(StdData) - DataPos; /* max that can be copied on first go */ U32 BuffPos = 0; /* position within Buffer for next compare (== count of bytes compared so far) */ U32 DataWritten; if (Size > MaxInitSize) { memcpy (Buffer, StdData + DataPos, MaxInitSize); DataPos = 0; /* remaining copies all start from StdData[0] */ /* loop whilst size left to write > sizeof(StdData) */ for (BuffPos += MaxInitSize; Size - BuffPos > sizeof(StdData); BuffPos += sizeof(StdData)) { memcpy(Buffer + BuffPos, StdData, sizeof(StdData)); } } memcpy(Buffer + BuffPos, StdData + DataPos, Size - BuffPos); if (ST_NO_ERROR != STAVFS_WriteFile (FileHandle, Buffer, Size, &DataWritten)) { STTBX_Print (("Error writing file: ")); Result = TEST_FAILED; } return (Result);}/******************************************************************************Function Name : ReadTestData Description : Read and compare data appropriate to the given overall file position. The caller should append context information to error messages Parameters : file handle, absolute position, size to read and compare******************************************************************************/static TestResult_t ReadTestData(STAVFS_FileHandle_t FileHandle, U32 AbsPos, U32 Size){ TestResult_t Result = TEST_PASSED; U32 DataPos = AbsPos % sizeof(StdData); /* where to start within StdData */ U32 MaxInitSize = sizeof(StdData) - DataPos; /* max that can be compared on first go */ U32 BuffPos = 0; /* position within Buffer for next compare (== count of bytes compared so far) */ S32 DiscrOffset = NODIFF; /* offset of first discrepency within compare, or NODIFF if none */ U32 DataRead; if (ST_NO_ERROR != STAVFS_ReadFile (FileHandle, Buffer, Size, &DataRead)) { STTBX_Print (("Error reading file: ")); Result = TEST_FAILED; } else { if (Size > MaxInitSize) { DiscrOffset = FirstDiff (Buffer, StdData + DataPos, MaxInitSize); if (DiscrOffset == NODIFF) { DataPos = 0; /* remaining compares all start on StdData[0] */ /* loop whilst size left to compare > sizeof(StdData) */ for (BuffPos += MaxInitSize; Size - BuffPos > sizeof(StdData); BuffPos += sizeof(StdData)) { DiscrOffset = FirstDiff(Buffer + BuffPos, StdData, sizeof(StdData)); if (DiscrOffset != NODIFF) break; } } } if (DiscrOffset == NODIFF) /* no discrepency so far */ DiscrOffset = FirstDiff(Buffer + BuffPos, StdData + DataPos, Size - BuffPos); if (DiscrOffset != NODIFF) { STTBX_Print (("Write-Read mismatch at %i: ", BuffPos + DiscrOffset)); Result = TEST_FAILED; } } return (Result);}/******************************************************************************Function Name : RunTestPattern Description : Write, or Read/Compare, according to the given test pattern Parameters : file handle, absolute position (will be updated if sucessful), test pattern start, number of elements, whether to write or read******************************************************************************/static TestResult_t RunTestPattern(STAVFS_FileHandle_t FileHandle, U32 * AbsPos_p, RWTestPart_t * Pattern_p, int CntParts, BOOL DoWrite){ TestResult_t Result = TEST_PASSED, TransferResult; int PartIdx, RepIdx; for (PartIdx = 0; PartIdx < CntParts; ++PartIdx) { for (RepIdx = 0; RepIdx < Pattern_p[PartIdx].BlockReps; ++RepIdx) { TransferResult = DoWrite ? WriteTestData(FileHandle, *AbsPos_p, Pattern_p[PartIdx].BlockSize) : ReadTestData(FileHandle, *AbsPos_p, Pattern_p[PartIdx].BlockSize); if (TransferResult == TEST_FAILED) { /* append context information to the error message */ STTBX_Print(("part %i repetition %i\n", PartIdx, RepIdx)); Result = TEST_FAILED; break; /* from inner loop */ } *AbsPos_p += Pattern_p[PartIdx].BlockSize; } if (Result == TEST_FAILED) { break; /* from outer loop */ } } return (Result);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -