| 820 | } |
| 821 | |
| 822 | static DWORD ReadFile_FrameCached(TCascFile * hf, LPBYTE pbBuffer, ULONGLONG StartOffset, ULONGLONG EndOffset) |
| 823 | { |
| 824 | PCASC_CKEY_ENTRY pCKeyEntry = hf->pCKeyEntry; |
| 825 | PCASC_FILE_SPAN pFileSpan = hf->pFileSpan; |
| 826 | PCASC_FILE_FRAME pFileFrame = NULL; |
| 827 | LPBYTE pbSaveBuffer = pbBuffer; |
| 828 | LPBYTE pbEncoded = NULL; |
| 829 | LPBYTE pbDecoded = NULL; |
| 830 | DWORD dwBytesRead = 0; |
| 831 | DWORD dwErrCode = ERROR_SUCCESS; |
| 832 | bool bNeedFreeDecoded = true; |
| 833 | |
| 834 | // Parse all file spans |
| 835 | for(DWORD SpanIndex = 0; SpanIndex < hf->SpanCount; SpanIndex++, pCKeyEntry++, pFileSpan++) |
| 836 | { |
| 837 | if(pFileSpan->StartOffset <= StartOffset && StartOffset < pFileSpan->EndOffset) |
| 838 | { |
| 839 | for(DWORD FrameIndex = 0; FrameIndex < pFileSpan->FrameCount; FrameIndex++) |
| 840 | { |
| 841 | // Get the current file frame |
| 842 | pFileFrame = pFileSpan->pFrames + FrameIndex; |
| 843 | |
| 844 | // Check the frame byte range |
| 845 | if(pFileFrame->StartOffset <= StartOffset && StartOffset < pFileFrame->EndOffset) |
| 846 | { |
| 847 | // Check bytes read overflow |
| 848 | if((dwBytesRead + pFileFrame->ContentSize) < dwBytesRead) |
| 849 | { |
| 850 | SetCascError(ERROR_BUFFER_OVERFLOW); |
| 851 | return 0; |
| 852 | } |
| 853 | |
| 854 | // Pick the buffer for decoded data. If we are going to read the entire frame, |
| 855 | // there is a little chance that the caller will read the same file range again |
| 856 | // So we can as well just unpack the entire frame into the output buffer |
| 857 | if(pFileFrame->StartOffset < StartOffset || EndOffset < pFileFrame->EndOffset) |
| 858 | { |
| 859 | if((pbDecoded = CASC_ALLOC<BYTE>(pFileFrame->ContentSize)) == NULL) |
| 860 | { |
| 861 | SetCascError(ERROR_NOT_ENOUGH_MEMORY); |
| 862 | return 0; |
| 863 | } |
| 864 | bNeedFreeDecoded = true; |
| 865 | } |
| 866 | else |
| 867 | { |
| 868 | bNeedFreeDecoded = false; |
| 869 | pbDecoded = pbBuffer; |
| 870 | } |
| 871 | |
| 872 | // Allocate the encoded frame |
| 873 | if((pbEncoded = CASC_ALLOC<BYTE>(pFileFrame->EncodedSize)) == NULL) |
| 874 | { |
| 875 | CASC_FREE(pbDecoded); |
| 876 | SetCascError(ERROR_NOT_ENOUGH_MEMORY); |
| 877 | return 0; |
| 878 | } |
| 879 |
no test coverage detected