Skip to content

Commit d7f700a

Browse files
authored
Added support for paths containing unicode characters on Windows (#156)
1 parent 1555670 commit d7f700a

File tree

4 files changed

+84
-17
lines changed

4 files changed

+84
-17
lines changed

trantor/net/TcpConnection.h

100644100755
Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,13 +59,25 @@ class TRANTOR_EXPORT TcpConnection
5959
/**
6060
* @brief Send a file to the peer.
6161
*
62-
* @param fileName
62+
* @param fileName in UTF-8
6363
* @param offset
6464
* @param length
6565
*/
6666
virtual void sendFile(const char *fileName,
6767
size_t offset = 0,
6868
size_t length = 0) = 0;
69+
#ifdef _WIN32
70+
/**
71+
* @brief Send a file to the peer.
72+
*
73+
* @param fileName in UCS-2 (windows only)
74+
* @param offset
75+
* @param length
76+
*/
77+
virtual void sendFile(const wchar_t *fileName,
78+
size_t offset = 0,
79+
size_t length = 0) = 0;
80+
#endif // WIN32
6981

7082
/**
7183
* @brief Get the local address of the connection.

trantor/net/inner/TcpConnectionImpl.cc

100644100755
Lines changed: 30 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,6 @@
3333
#include <openssl/x509v3.h>
3434
#include <openssl/err.h>
3535
#endif
36-
#ifdef _WIN32
37-
#define stat _stati64
38-
#endif
3936
#include <regex>
4037

4138
using namespace trantor;
@@ -1273,7 +1270,19 @@ void TcpConnectionImpl::sendFile(const char *fileName,
12731270
size_t length)
12741271
{
12751272
assert(fileName);
1276-
#ifndef _WIN32
1273+
#ifdef _WIN32
1274+
// Convert UTF-8 file path to UCS-2
1275+
int nSizeNeeded = ::MultiByteToWideChar(
1276+
CP_UTF8, 0, fileName, (int)strnlen_s(fileName, MAX_PATH), NULL, 0);
1277+
std::wstring wFileName(nSizeNeeded, 0);
1278+
::MultiByteToWideChar(CP_UTF8,
1279+
0,
1280+
fileName,
1281+
(int)strnlen_s(fileName, MAX_PATH),
1282+
&wFileName[0],
1283+
nSizeNeeded);
1284+
sendFile(wFileName.c_str(), offset, length);
1285+
#else // _WIN32
12771286
int fd = open(fileName, O_RDONLY);
12781287

12791288
if (fd < 0)
@@ -1295,16 +1304,22 @@ void TcpConnectionImpl::sendFile(const char *fileName,
12951304
}
12961305

12971306
sendFile(fd, offset, length);
1298-
#else
1299-
#ifndef _MSC_VER
1300-
auto fp = fopen(fileName, "rb");
1301-
#else
1307+
#endif // _WIN32
1308+
}
1309+
1310+
#ifdef _WIN32
1311+
void TcpConnectionImpl::sendFile(const wchar_t *fileName,
1312+
size_t offset,
1313+
size_t length)
1314+
{
1315+
assert(fileName);
13021316
FILE *fp;
1303-
if (fopen_s(&fp, fileName, "rb") != 0)
1304-
{
1317+
#ifndef _MSC_VER
1318+
fp = _wfopen(fileName, L"rb");
1319+
#else // _MSC_VER
1320+
if (_wfopen_s(&fp, fileName, L"rb") != 0)
13051321
fp = nullptr;
1306-
}
1307-
#endif
1322+
#endif // _MSC_VER
13081323
if (fp == nullptr)
13091324
{
13101325
LOG_SYSERR << fileName << " open error";
@@ -1313,8 +1328,8 @@ void TcpConnectionImpl::sendFile(const char *fileName,
13131328

13141329
if (length == 0)
13151330
{
1316-
struct stat filestat;
1317-
if (stat(fileName, &filestat) < 0)
1331+
struct _stati64 filestat;
1332+
if (_wstati64(fileName, &filestat) < 0)
13181333
{
13191334
LOG_SYSERR << fileName << " stat error";
13201335
fclose(fp);
@@ -1324,8 +1339,8 @@ void TcpConnectionImpl::sendFile(const char *fileName,
13241339
}
13251340

13261341
sendFile(fp, offset, length);
1327-
#endif
13281342
}
1343+
#endif // _WIN32
13291344

13301345
#ifndef _WIN32
13311346
void TcpConnectionImpl::sendFile(int sfd, size_t offset, size_t length)

trantor/net/inner/TcpConnectionImpl.h

100644100755
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,11 @@ class TcpConnectionImpl : public TcpConnection,
115115
virtual void sendFile(const char *fileName,
116116
size_t offset = 0,
117117
size_t length = 0) override;
118+
#ifdef _WIN32
119+
virtual void sendFile(const wchar_t *fileName,
120+
size_t offset = 0,
121+
size_t length = 0) override;
122+
#endif // WIN32
118123

119124
virtual const InetAddress &localAddr() const override
120125
{

trantor/utils/AsyncFileLogger.cc

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
#ifdef __linux__
1919
#include <sys/prctl.h>
2020
#endif
21+
#else
22+
#include <Windows.h>
2123
#endif
2224
#include <string.h>
2325
#include <iostream>
@@ -184,7 +186,17 @@ AsyncFileLogger::LoggerFile::LoggerFile(const std::string &filePath,
184186
#ifndef _MSC_VER
185187
fp_ = fopen(fileFullName_.c_str(), "a");
186188
#else
187-
fp_ = _fsopen(fileFullName_.c_str(), "a+", _SH_DENYWR);
189+
// Convert UTF-8 file to UCS-2
190+
int nSizeNeeded = ::MultiByteToWideChar(
191+
CP_UTF8, 0, &fileFullName_[0], (int)fileFullName_.size(), NULL, 0);
192+
std::wstring wFullName(nSizeNeeded, 0);
193+
::MultiByteToWideChar(CP_UTF8,
194+
0,
195+
&fileFullName_[0],
196+
(int)fileFullName_.size(),
197+
&wFullName[0],
198+
nSizeNeeded);
199+
fp_ = _wfsopen(wFullName.c_str(), L"a+", _SH_DENYWR);
188200
#endif
189201
if (fp_ == nullptr)
190202
{
@@ -232,7 +244,30 @@ AsyncFileLogger::LoggerFile::~LoggerFile()
232244
filePath_ + fileBaseName_ + "." +
233245
creationDate_.toCustomedFormattedString("%y%m%d-%H%M%S") +
234246
std::string(seq) + fileExtName_;
247+
#ifndef _WIN32
235248
rename(fileFullName_.c_str(), newName.c_str());
249+
#else // _WIN32
250+
// Convert UTF-8 file to UCS-2
251+
int nSizeNeeded = ::MultiByteToWideChar(
252+
CP_UTF8, 0, &fileFullName_[0], (int)fileFullName_.size(), NULL, 0);
253+
std::wstring wFullName(nSizeNeeded, 0);
254+
::MultiByteToWideChar(CP_UTF8,
255+
0,
256+
&fileFullName_[0],
257+
(int)fileFullName_.size(),
258+
&wFullName[0],
259+
nSizeNeeded);
260+
nSizeNeeded = ::MultiByteToWideChar(
261+
CP_UTF8, 0, &newName[0], (int)newName.size(), NULL, 0);
262+
std::wstring wNewName(nSizeNeeded, 0);
263+
::MultiByteToWideChar(CP_UTF8,
264+
0,
265+
&newName[0],
266+
(int)newName.size(),
267+
&wNewName[0],
268+
nSizeNeeded);
269+
_wrename(wFullName.c_str(), wNewName.c_str());
270+
#endif // _WIN32
236271
}
237272
}
238273

0 commit comments

Comments
 (0)