📄 file.c
字号:
/* Ensure that we have space to write to */ Error = stavfs_MoreDiskSpace(FileHandle_p, Pos_p, TRUE, Size); if (Error == ST_NO_ERROR) { /* Get the Sectors LBA */ INT_I64_AddLit(Pos_p->BlockLBA, Pos_p->Offset/DISK_SECTOR_SIZE, LBA); /* Read the data */ if (ST_NO_ERROR != stavfs_SetRWBuffer(Device_p, &LBA, &(Pos_p->Buffer), StreamFile)) { Error = STAVFS_ERROR_UNREADABLE_DISK; } else if (ST_NO_ERROR != stavfs_RWBufferWrite (Device_p, Pos_p->Buffer, 0, Size, Address, EndOfFile)) { Error = STAVFS_ERROR_UNWRITABLE_DISK; } else { Address += Size; Pos_p->Offset += Size; WrittenData += Size; Size -= Size; } } } } /* Update file size */ if (Error == ST_NO_ERROR) { stavfs_GetPos(Device_p, Pos_p, &FilePos); if (DirEntry_p->Flags & FILE_FLAG_CYCLIC_FILE) { /* Cyclic file */ if ( (DirEntry_p->Size.Cyclic.LoopCount == FileHandle_p->LoopCount-1) || ((DirEntry_p->Size.Cyclic.LoopCount == FileHandle_p->LoopCount) && DirEntry_p->Size.Cyclic.TopOffset < FilePos.LSW)) { DirEntry_p->Size.Cyclic.LoopCount = FileHandle_p->LoopCount; DirEntry_p->Size.Cyclic.TopOffset = FilePos.LSW; stavfs_ModifyDirEntry(Device_p, DirEntry_p); } } else { /* Regular file */ if (I64_IsLessThan(DirEntry_p->Size.File, FilePos)) { DirEntry_p->Size.File = FilePos; stavfs_ModifyDirEntry(Device_p, DirEntry_p); } } } /* Report the data actually written */ if (NULL != BytesWritten) { *BytesWritten = WrittenData; } if ((Error == ST_NO_ERROR) && ReachedEOF) { Error = STAVFS_ERROR_OVERFLOW; } return (Error);}/******************************************************************************Function Name : stavfs_ReadFile Description : Parameters :******************************************************************************/static ST_ErrorCode_t stavfs_ReadFile (int Handle, U32 Size, char *Address, U32 *BytesRead){ ST_ErrorCode_t Error = ST_NO_ERROR; stavfs_OpenFileHandle_t *FileHandle_p = FileHandleTable+Handle; stavfs_Device_t *Device_p = FileHandle_p->Device_p; stavfs_DirEntry_t *DirEntry_p = FileHandle_p->DirEntry_p; stavfs_FilePos_t *Pos_p = &(FileHandle_p->Read); U32 Offset = 0; BOOL ReachedEOF = FALSE; U32 ReadData = 0; BOOL StreamFile = (DirEntry_p->Flags & FILE_FLAG_STREAM_MODE); assert(Device_p != NULL); assert(DirEntry_p != NULL); assert(Pos_p != NULL); /* Check for file underflow/EOF */ if (DirEntry_p->Flags & FILE_FLAG_CYCLIC_FILE) { /* Cyclic file */ U32 Diff = 0; U64 FilePos; stavfs_GetPos(Device_p, Pos_p, &FilePos); if (FilePos.LSW > DirEntry_p->Size.Cyclic.TopOffset) { Diff = DirEntry_p->AllocSize.LSW * Device_p->ClusterSize * DISK_SECTOR_SIZE; Diff -= FilePos.LSW; Diff += DirEntry_p->Size.Cyclic.TopOffset; } else { Diff = DirEntry_p->Size.Cyclic.TopOffset; Diff -= FilePos.LSW; } /* Check that we have space for the read */ if (Diff < Size) { Size = Diff; ReachedEOF = TRUE; } } else { /* Regular file */ U64 FilePos; stavfs_GetPos(Device_p, Pos_p, &FilePos); I64_Sub(DirEntry_p->Size.File, FilePos, FilePos); if ((FilePos.MSW == 0) && (FilePos.LSW < Size)) { Size = FilePos.LSW; ReachedEOF = TRUE; } } /* If there is any data to read then read it from disk */ if ((Size > 0) && (Error == ST_NO_ERROR)) { U32 ReadSectors = 0; U32 ThisSize; U64 LBA; /* Read within the first block */ if (0 != (Offset = Pos_p->Offset%DISK_SECTOR_SIZE)) { /* Get the Sectors LBA */ INT_I64_AddLit(Pos_p->BlockLBA, Pos_p->Offset/DISK_SECTOR_SIZE, LBA); /* Are we reading only part of the sector */ ThisSize = DISK_SECTOR_SIZE - Pos_p->Offset%DISK_SECTOR_SIZE; if (Size < ThisSize) { ThisSize = Size; } /* Read the data */ if (ST_NO_ERROR != stavfs_SetRWBuffer(Device_p, &LBA, &(Pos_p->Buffer), StreamFile)) { Error = STAVFS_ERROR_UNREADABLE_DISK; } else if (ST_NO_ERROR != stavfs_RWBufferRead (Device_p, Pos_p->Buffer, Offset, ThisSize, Address)) { Error = STAVFS_ERROR_UNREADABLE_DISK; } else { Size -= ThisSize; Address += ThisSize; Pos_p->Offset += ThisSize; ReadData += ThisSize; } } /* Read Blocks */ ReadSectors = Size/DISK_SECTOR_SIZE; while ((ReadSectors > 0) && (Error == ST_NO_ERROR)) { /* Ensure that we have space to read from */ Error = stavfs_MoreDiskSpace(FileHandle_p, Pos_p, FALSE, Size); if (Error == ST_NO_ERROR) { U32 ThisSectors = Pos_p->BlockSize*Device_p->ClusterSize - Pos_p->Offset/DISK_SECTOR_SIZE; /* Get the Sectors LBA */ INT_I64_AddLit(Pos_p->BlockLBA, Pos_p->Offset/DISK_SECTOR_SIZE, LBA); /* Are we reading only part of the sectors */ if (ReadSectors < ThisSectors) { ThisSectors = ReadSectors; } /* Read the data */ if (ST_NO_ERROR != stavfs_RWCacheBlockRead (Device_p, &LBA, ThisSectors, Address, StreamFile)) { Error = STAVFS_ERROR_UNREADABLE_DISK; } else { ReadSectors -= ThisSectors; Size -= ThisSectors*DISK_SECTOR_SIZE; Address += ThisSectors*DISK_SECTOR_SIZE; Pos_p->Offset += ThisSectors*DISK_SECTOR_SIZE; ReadData += ThisSectors*DISK_SECTOR_SIZE; } } } /* Read within the last sector */ if ((Size > 0) && (Error == ST_NO_ERROR)) { /* Ensure that we have space to read from */ Error = stavfs_MoreDiskSpace(FileHandle_p, Pos_p, FALSE, Size); if (Error == ST_NO_ERROR) { /* Get the Sectors LBA */ INT_I64_AddLit(Pos_p->BlockLBA, Pos_p->Offset/DISK_SECTOR_SIZE, LBA); /* Read the data */ if (ST_NO_ERROR != stavfs_SetRWBuffer(Device_p, &LBA, &(Pos_p->Buffer), StreamFile)) { Error = STAVFS_ERROR_UNREADABLE_DISK; } else if (ST_NO_ERROR != stavfs_RWBufferRead (Device_p, Pos_p->Buffer, 0, Size, Address)) { Error = STAVFS_ERROR_UNREADABLE_DISK; } else { Address += Size; Pos_p->Offset += Size; ReadData += Size; Size -= Size; } } } } /* Report any End Of File */ if (ReachedEOF && (Error == ST_NO_ERROR)) { if (DirEntry_p->Flags & FILE_FLAG_CYCLIC_FILE) { Error = STAVFS_ERROR_UNDERFLOW; } else { Error = STAVFS_ERROR_EOF; } } /* Report the data actually read */ if (NULL != BytesRead) { *BytesRead = ReadData; } return (Error);}/******************************************************************************Function Name : STAVFS_GetFilePosition Description : Return the current position within the file relative to the start of file. Parameters :******************************************************************************/static ST_ErrorCode_t stavfs_GetFilePosition (stavfs_OpenFileHandle_t *FileHandle_p, BOOL WritePosition, U64 * Position_p){ ST_ErrorCode_t Error = ST_NO_ERROR; stavfs_Device_t *Device_p = FileHandle_p->Device_p; stavfs_DirEntry_t *DirEntry_p = FileHandle_p->DirEntry_p; assert(NULL != Position_p); if (WritePosition) { /* Return current write offset */ stavfs_GetPos(Device_p, &(FileHandle_p->Write), Position_p); } else { /* Return current read offset */ stavfs_GetPos(Device_p, &(FileHandle_p->Read), Position_p); } /* Is this a cyclic file */ if (DirEntry_p->Flags & FILE_FLAG_CYCLIC_FILE) { /* Add in the loops */ U64 LoopSize = DirEntry_p->AllocSize; /* If the pointer is a loop behind */ if (Position_p->LSW > DirEntry_p->Size.Cyclic.TopOffset) { /* We are one loop behind */ INT_I64_MulLit(DirEntry_p->AllocSize, DirEntry_p->Size.Cyclic.LoopCount-1, LoopSize); } else { /* We are in the same loop */ INT_I64_MulLit(DirEntry_p->AllocSize, DirEntry_p->Size.Cyclic.LoopCount, LoopSize); } /* Get the size in bytes */ INT_I64_MulLit(LoopSize, Device_p->ClusterSize, LoopSize); /* Multiply by the sector size */ I64_ShiftLeft(9, LoopSize); /* Add it in */ I64_Add(*Position_p, LoopSize, *Position_p); } return (Error);}/******************************************************************************Function Name : stavfs_SeekRegularFile Description : Parameters :******************************************************************************/ST_ErrorCode_t stavfs_SeekRegularFile (STAVFS_FileHandle_t Handle, S64 Position, STAVFS_TypePosition_t Mode, BOOL WritePosition){ ST_ErrorCode_t Error = ST_NO_ERROR; int FileId = (int)Handle; stavfs_OpenFileHandle_t *FileHandle_p = FileHandleTable+FileId; stavfs_Device_t *Device_p = FileHandle_p->Device_p; stavfs_DirEntry_t *DirEntry_p = FileHandle_p->DirEntry_p; U64 CurrentPos; assert (FileHandle_p->Device_p != NULL); assert (FileHandle_p->DirEntry_p != NULL); /* Move relative to a given position */ switch (Mode) { case STAVFS_START : CurrentPos = Position; break; case STAVFS_END : I64_Sub(DirEntry_p->Size.File, Position, CurrentPos); break; case STAVFS_CURRENT : Error = stavfs_GetFilePosition (FileHandle_p, WritePosition, &CurrentPos); I64_Add(CurrentPos, Position, CurrentPos); break; default : Error = ST_ERROR_BAD_PARAMETER; break; } if (Error == ST_NO_ERROR) { if (I64_IsNegative(CurrentPos)) { /* Off the bottom */ Error = STAVFS_ERROR_OUT_OF_RANGE; } else if (I64_IsLessThan(DirEntry_p->Size.File, CurrentPos)) { /* Off the top */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -