| 54 | } |
| 55 | |
| 56 | static void ReadCallback(s32 chan, s32 result) { |
| 57 | CARDControl* card; |
| 58 | CARDCallback callback; |
| 59 | u16* fat; |
| 60 | CARDFileInfo* fileInfo; |
| 61 | s32 length; |
| 62 | |
| 63 | card = &__CARDBlock[chan]; |
| 64 | if (result < 0) { |
| 65 | goto error; |
| 66 | } |
| 67 | |
| 68 | fileInfo = card->fileInfo; |
| 69 | if (fileInfo->length < 0) { |
| 70 | result = CARD_RESULT_CANCELED; |
| 71 | goto error; |
| 72 | } |
| 73 | |
| 74 | length = (s32)TRUNC(fileInfo->offset + card->sectorSize, card->sectorSize) - fileInfo->offset; |
| 75 | fileInfo->length -= length; |
| 76 | if (fileInfo->length <= 0) { |
| 77 | goto error; |
| 78 | } |
| 79 | |
| 80 | fat = __CARDGetFatBlock(card); |
| 81 | fileInfo->offset += length; |
| 82 | fileInfo->iBlock = fat[fileInfo->iBlock]; |
| 83 | if (!CARDIsValidBlockNo(card, fileInfo->iBlock)) { |
| 84 | result = CARD_RESULT_BROKEN; |
| 85 | goto error; |
| 86 | } |
| 87 | |
| 88 | result = __CARDRead(chan, card->sectorSize * (u32)fileInfo->iBlock, |
| 89 | (fileInfo->length < card->sectorSize) ? fileInfo->length : card->sectorSize, |
| 90 | card->buffer, ReadCallback); |
| 91 | if (result < 0) { |
| 92 | goto error; |
| 93 | } |
| 94 | |
| 95 | return; |
| 96 | |
| 97 | error: |
| 98 | callback = card->apiCallback; |
| 99 | card->apiCallback = 0; |
| 100 | __CARDPutControlBlock(card, result); |
| 101 | callback(chan, result); |
| 102 | } |
| 103 | |
| 104 | s32 CARDReadAsync(CARDFileInfo* fileInfo, void* buf, s32 length, s32 offset, |
| 105 | CARDCallback callback) { |
nothing calls this directly
no test coverage detected