From c4564566b0b308f88f3664ec124a8557bdc278f0 Mon Sep 17 00:00:00 2001 From: Shauren Date: Thu, 3 Nov 2022 01:15:30 +0100 Subject: Dep/CascLib: Update to ladislav-zezula/CascLib@136c6e05537bd7123620ddb28671d1f2cf060e0b --- dep/CascLib/src/common/FileStream.cpp | 101 +++++++++++++++++++++++----------- 1 file changed, 70 insertions(+), 31 deletions(-) (limited to 'dep/CascLib/src/common/FileStream.cpp') diff --git a/dep/CascLib/src/common/FileStream.cpp b/dep/CascLib/src/common/FileStream.cpp index 498729bab6f..622af421a82 100644 --- a/dep/CascLib/src/common/FileStream.cpp +++ b/dep/CascLib/src/common/FileStream.cpp @@ -182,7 +182,7 @@ static bool BaseFile_Read( pStream->Base.File.FilePos = ByteOffset; // Read the data - if (dwBytesToRead != 0) + if(dwBytesToRead != 0) { OVERLAPPED Overlapped; @@ -204,9 +204,9 @@ static bool BaseFile_Read( // If the byte offset is different from the current file position, // we have to update the file position - if (ByteOffset != pStream->Base.File.FilePos) + if(ByteOffset != pStream->Base.File.FilePos) { - if (lseek64((intptr_t)pStream->Base.File.hFile, (off64_t)(ByteOffset), SEEK_SET) == (off64_t)-1) + if(lseek64((intptr_t)pStream->Base.File.hFile, (off64_t)(ByteOffset), SEEK_SET) == (off64_t)-1) { CascUnlock(pStream->Lock); SetCascError(errno); @@ -216,10 +216,10 @@ static bool BaseFile_Read( } // Perform the read operation - if (dwBytesToRead != 0) + if(dwBytesToRead != 0) { bytes_read = read((intptr_t)pStream->Base.File.hFile, pvBuffer, (size_t)dwBytesToRead); - if (bytes_read == -1) + if(bytes_read == -1) { CascUnlock(pStream->Lock); SetCascError(errno); @@ -282,7 +282,7 @@ static bool BaseFile_Write(TFileStream * pStream, ULONGLONG * pByteOffset, const pStream->Base.File.FilePos = ByteOffset; // Read the data - if (dwBytesToWrite != 0) + if(dwBytesToWrite != 0) { OVERLAPPED Overlapped; @@ -304,9 +304,9 @@ static bool BaseFile_Write(TFileStream * pStream, ULONGLONG * pByteOffset, const // If the byte offset is different from the current file position, // we have to update the file position - if (ByteOffset != pStream->Base.File.FilePos) + if(ByteOffset != pStream->Base.File.FilePos) { - if (lseek64((intptr_t)pStream->Base.File.hFile, (off64_t)(ByteOffset), SEEK_SET) == (off64_t)-1) + if(lseek64((intptr_t)pStream->Base.File.hFile, (off64_t)(ByteOffset), SEEK_SET) == (off64_t)-1) { CascUnlock(pStream->Lock); SetCascError(errno); @@ -317,7 +317,7 @@ static bool BaseFile_Write(TFileStream * pStream, ULONGLONG * pByteOffset, const // Perform the read operation bytes_written = write((intptr_t)pStream->Base.File.hFile, pvBuffer, (size_t)dwBytesToWrite); - if (bytes_written == -1) + if(bytes_written == -1) { CascUnlock(pStream->Lock); SetCascError(errno); @@ -611,22 +611,48 @@ static void BaseMap_Init(TFileStream * pStream) //----------------------------------------------------------------------------- // Local functions - base HTTP file support -static DWORD BaseHttp_ParseURL(TFileStream * pStream, LPCTSTR szFileName) +static DWORD BaseHttp_ParseURL(TFileStream * pStream, LPCTSTR szFileName, int * pPortNum) { - LPCTSTR szFilePtr = szFileName; - char * hostName; - char * fileName; + LPCTSTR szHostNamePtr = szFileName; + LPCTSTR szHostNameEnd = szFileName; + LPCTSTR szPortPtr = NULL; + LPCTSTR szPortEnd = NULL; + LPCTSTR szFilePtr; + size_t nLength; + LPSTR hostName = NULL; + LPSTR fileName = NULL; + char szPort[20]; + + // Find the end of the host name + while(szHostNameEnd[0] != 0 && szHostNameEnd[0] != ':' && szHostNameEnd[0] != '/') + szHostNameEnd++; + szFilePtr = szHostNameEnd; - // Find the end od the host name - if((szFilePtr = _tcschr(szFileName, '/')) == NULL) - return ERROR_INVALID_PARAMETER; + // Is there port number? + if(szHostNameEnd[0] == ':') + { + // Set the range of the port + szPortPtr = szPortEnd = szHostNameEnd + 1; + while(szPortEnd[0] != 0 && szPortEnd[0] != '/') + szPortEnd++; + szFilePtr = szPortEnd; + } - // Allocate and copy the host name - if((hostName = CASC_ALLOC(szFilePtr - szFileName + 1)) != NULL) + // Allocate the host name + nLength = szHostNameEnd - szHostNamePtr + 1; + if((hostName = CASC_ALLOC(nLength)) != NULL) { - CascStrCopy(hostName, 256, szFileName, (szFilePtr - szFileName)); + // Copy the host name + CascStrCopy(hostName, nLength, szHostNamePtr, (szHostNameEnd - szHostNamePtr)); - // Allocate and copy the resource name + // Parse port, if present + if(szPortPtr != NULL && szPortEnd > szPortPtr) + { + CascStrCopy(szPort, _countof(szPort), szPortPtr, (szPortEnd - szPortPtr)); + pPortNum[0] = atoi(szPort); + } + + // Allocate file name if((fileName = CascNewStrT2A(szFilePtr)) != NULL) { pStream->Base.Socket.hostName = hostName; @@ -634,12 +660,16 @@ static DWORD BaseHttp_ParseURL(TFileStream * pStream, LPCTSTR szFileName) return ERROR_SUCCESS; } + // Free the host name CASC_FREE(hostName); } return ERROR_NOT_ENOUGH_MEMORY; } +//----------------------------------------------------------------------------- +// Local functions - base HTTP file support + static bool BaseHttp_Download(TFileStream * pStream) { CASC_MIME Mime; @@ -654,6 +684,9 @@ static bool BaseHttp_Download(TFileStream * pStream) // If we already have the data, it's success if(pStream->Base.Socket.fileData == NULL) { + // Reset the file data length as well + pStream->Base.Socket.fileDataLength = 0; + // Construct the request, either HTTP or Ribbit (https://wowdev.wiki/Ribbit). // Note that Ribbit requests don't start with slash if((pStream->dwFlags & BASE_PROVIDER_MASK) == BASE_PROVIDER_RIBBIT) @@ -668,13 +701,22 @@ static bool BaseHttp_Download(TFileStream * pStream) server_response = pStream->Base.Socket.pSocket->ReadResponse(request, request_length, &response_length); if(server_response != NULL) { - // Decode the MIME document - if((dwErrCode = Mime.Load(server_response, response_length)) == ERROR_SUCCESS) + // Check for non-zero data + if(response_length != 0) { - // Move the data from MIME to HTTP stream - pStream->Base.Socket.fileData = Mime.GiveAway(&pStream->Base.Socket.fileDataLength); + // Decode the MIME document + if((dwErrCode = Mime.Load(server_response, response_length)) == ERROR_SUCCESS) + { + // Move the data from MIME to HTTP stream + pStream->Base.Socket.fileData = Mime.GiveAway(&pStream->Base.Socket.fileDataLength); + } + } + else + { + SetCascError(ERROR_BAD_FORMAT); } + // Free the buffer CASC_FREE(server_response); } } @@ -685,15 +727,13 @@ static bool BaseHttp_Download(TFileStream * pStream) static bool BaseHttp_Open(TFileStream * pStream, LPCTSTR szFileName, DWORD dwStreamFlags) { + PCASC_SOCKET pSocket; DWORD dwErrCode; + int portNum = ((dwStreamFlags & BASE_PROVIDER_MASK) == BASE_PROVIDER_RIBBIT) ? CASC_PORT_RIBBIT : CASC_PORT_HTTP; // Extract the server part - if((dwErrCode = BaseHttp_ParseURL(pStream, szFileName)) == ERROR_SUCCESS) + if((dwErrCode = BaseHttp_ParseURL(pStream, szFileName, &portNum)) == ERROR_SUCCESS) { - // Determine the proper port - PCASC_SOCKET pSocket; - int portNum = ((dwStreamFlags & BASE_PROVIDER_MASK) == BASE_PROVIDER_RIBBIT) ? CASC_PORT_RIBBIT : CASC_PORT_HTTP; - // Initiate the remote connection if((pSocket = sockets_connect(pStream->Base.Socket.hostName, portNum)) != NULL) { @@ -771,8 +811,7 @@ static bool BaseHttp_GetSize(TFileStream * pStream, ULONGLONG * pFileSize) CascLock(pStream->Lock); { // Make sure that we have the file data - bResult = BaseHttp_Download(pStream); - if(bResult) + if((bResult = BaseHttp_Download(pStream)) != false) { *pFileSize = pStream->Base.Socket.fileDataLength; } -- cgit v1.2.3