aboutsummaryrefslogtreecommitdiff
path: root/dep/CascLib/src/common/FileStream.cpp
diff options
context:
space:
mode:
authorShauren <shauren.trinity@gmail.com>2022-11-03 01:15:30 +0100
committerShauren <shauren.trinity@gmail.com>2022-11-03 01:15:30 +0100
commitc4564566b0b308f88f3664ec124a8557bdc278f0 (patch)
treef09d604f961e5d605556bc652aea5ec5d505d025 /dep/CascLib/src/common/FileStream.cpp
parent722201e01c7809f1e85eb480499630a7d7d748b5 (diff)
Dep/CascLib: Update to ladislav-zezula/CascLib@136c6e05537bd7123620ddb28671d1f2cf060e0b
Diffstat (limited to 'dep/CascLib/src/common/FileStream.cpp')
-rw-r--r--dep/CascLib/src/common/FileStream.cpp101
1 files changed, 70 insertions, 31 deletions
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<char>(szFilePtr - szFileName + 1)) != NULL)
+ // Allocate the host name
+ nLength = szHostNameEnd - szHostNamePtr + 1;
+ if((hostName = CASC_ALLOC<char>(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;
}