diff --git a/build/config/compiler/BUILD.gn b/build/config/compiler/BUILD.gn index a2f8b130e88..873dc4cef51 100644 --- a/build/config/compiler/BUILD.gn +++ b/build/config/compiler/BUILD.gn @@ -732,10 +732,11 @@ config("optimize") { # Turn off optimizations. config("no_optimize") { if (is_win) { + # The only difference on windows is that the inlining is less aggressive. + # (We accept the default level). Otherwise it is very slow. cflags = [ "/O2", # Do some optimizations. "/Oy-", # Disable omitting frame pointers, must be after /O2. - "/Ob0", # Disable all inlining (on by default). ] } else if (is_android) { # On Android we kind of optimize some things that don't affect debugging diff --git a/runtime/bin/directory_win.cc b/runtime/bin/directory_win.cc index efaaaf90a6e..4ebf512307e 100644 --- a/runtime/bin/directory_win.cc +++ b/runtime/bin/directory_win.cc @@ -50,8 +50,8 @@ const char* PathBuffer::AsScopedString() const { bool PathBuffer::Add(const char* name) { - const wchar_t* wide_name = StringUtilsWin::Utf8ToWide(name); - return AddW(wide_name); + Utf8ToWideScope wide_name(name); + return AddW(wide_name.wide()); } @@ -377,8 +377,8 @@ static Directory::ExistsResult ExistsHelper(const wchar_t* dir_name) { Directory::ExistsResult Directory::Exists(const char* dir_name) { - const wchar_t* system_name = StringUtilsWin::Utf8ToWide(dir_name); - return ExistsHelper(system_name); + Utf8ToWideScope system_name(dir_name); + return ExistsHelper(system_name.wide()); } @@ -412,19 +412,19 @@ const char* Directory::Current() { bool Directory::SetCurrent(const char* path) { - const wchar_t* system_path = StringUtilsWin::Utf8ToWide(path); - bool result = SetCurrentDirectoryW(system_path) != 0; + Utf8ToWideScope system_path(path); + bool result = SetCurrentDirectoryW(system_path.wide()) != 0; return result; } bool Directory::Create(const char* dir_name) { - const wchar_t* system_name = StringUtilsWin::Utf8ToWide(dir_name); - int create_status = CreateDirectoryW(system_name, NULL); + Utf8ToWideScope system_name(dir_name); + int create_status = CreateDirectoryW(system_name.wide(), NULL); // If the directory already existed, treat it as a success. if ((create_status == 0) && (GetLastError() == ERROR_ALREADY_EXISTS) && - (ExistsHelper(system_name) == EXISTS)) { + (ExistsHelper(system_name.wide()) == EXISTS)) { return true; } return (create_status != 0); @@ -446,8 +446,8 @@ const char* Directory::CreateTemp(const char* prefix) { // descriptor inherited from its parent directory. // The return value is Dart_ScopeAllocated. PathBuffer path; - const wchar_t* system_prefix = StringUtilsWin::Utf8ToWide(prefix); - if (!path.AddW(system_prefix)) { + Utf8ToWideScope system_prefix(prefix); + if (!path.AddW(system_prefix.wide())) { return NULL; } @@ -481,16 +481,16 @@ const char* Directory::CreateTemp(const char* prefix) { bool Directory::Delete(const char* dir_name, bool recursive) { bool result = false; - const wchar_t* system_dir_name = StringUtilsWin::Utf8ToWide(dir_name); + Utf8ToWideScope system_dir_name(dir_name); if (!recursive) { if (File::GetType(dir_name, true) == File::kIsDirectory) { - result = (RemoveDirectoryW(system_dir_name) != 0); + result = (RemoveDirectoryW(system_dir_name.wide()) != 0); } else { SetLastError(ERROR_FILE_NOT_FOUND); } } else { PathBuffer path; - if (path.AddW(system_dir_name)) { + if (path.AddW(system_dir_name.wide())) { result = DeleteRecursively(&path); } } @@ -499,13 +499,13 @@ bool Directory::Delete(const char* dir_name, bool recursive) { bool Directory::Rename(const char* path, const char* new_path) { - const wchar_t* system_path = StringUtilsWin::Utf8ToWide(path); - const wchar_t* system_new_path = StringUtilsWin::Utf8ToWide(new_path); - ExistsResult exists = ExistsHelper(system_path); + Utf8ToWideScope system_path(path); + Utf8ToWideScope system_new_path(new_path); + ExistsResult exists = ExistsHelper(system_path.wide()); if (exists != EXISTS) { return false; } - ExistsResult new_exists = ExistsHelper(system_new_path); + ExistsResult new_exists = ExistsHelper(system_new_path.wide()); // MoveFile does not allow replacing exising directories. Therefore, // if the new_path is currently a directory we need to delete it // first. @@ -517,7 +517,7 @@ bool Directory::Rename(const char* path, const char* new_path) { } DWORD flags = MOVEFILE_WRITE_THROUGH; int move_status = - MoveFileExW(system_path, system_new_path, flags); + MoveFileExW(system_path.wide(), system_new_path.wide(), flags); return (move_status != 0); } diff --git a/runtime/bin/file.cc b/runtime/bin/file.cc index a3dcd7fcb7c..828db768494 100644 --- a/runtime/bin/file.cc +++ b/runtime/bin/file.cc @@ -92,7 +92,7 @@ void FUNCTION_NAME(File_Open)(Dart_NativeArguments args) { // reading. This is to prevent the opening of directories as // files. Directories can be opened for reading using the posix // 'open' call. - File* file = File::ScopedOpen(filename, file_mode); + File* file = File::Open(filename, file_mode); if (file != NULL) { Dart_SetReturnValue(args, Dart_NewInteger(reinterpret_cast(file))); @@ -677,7 +677,7 @@ CObject* File::OpenRequest(const CObjectArray& request) { File::DartFileOpenMode dart_file_mode = static_cast(mode.Value()); File::FileOpenMode file_mode = File::DartModeToFileMode(dart_file_mode); - file = File::ScopedOpen(filename.CString(), file_mode); + file = File::Open(filename.CString(), file_mode); if (file != NULL) { return new CObjectIntptr( CObject::NewIntptr(reinterpret_cast(file))); diff --git a/runtime/bin/file.h b/runtime/bin/file.h index cef6f0a5659..aa37ba57d08 100644 --- a/runtime/bin/file.h +++ b/runtime/bin/file.h @@ -157,15 +157,8 @@ class File : public ReferenceCounted { // reading and writing. If mode contains kWrite and the file does // not exist the file is created. The file is truncated to length 0 if // mode contains kTruncate. Assumes we are in an API scope. - static File* ScopedOpen(const char* path, FileOpenMode mode); - - // Like ScopedOpen(), but no API scope is needed. static File* Open(const char* path, FileOpenMode mode); - // Caution! On Windows, the static functions below may call - // Dart_ScopeAllocate() to do string conversions! If you call these functions - // without a scope, they will fail on Windows! - // Create a file object for the specified stdio file descriptor // (stdin, stout or stderr). static File* OpenStdio(int fd); @@ -181,15 +174,17 @@ class File : public ReferenceCounted { static int64_t LengthFromPath(const char* path); static void Stat(const char* path, int64_t* data); static time_t LastModified(const char* path); - static const char* LinkTarget(const char* pathname); static bool IsAbsolutePath(const char* path); - static const char* GetCanonicalPath(const char* path); static const char* PathSeparator(); static const char* StringEscapedPathSeparator(); static Type GetType(const char* path, bool follow_links); static Identical AreIdentical(const char* file_1, const char* file_2); static StdioHandleType GetStdioHandleType(int fd); + // LinkTarget and GetCanonicalPath may call Dart_ScopeAllocate. + static const char* LinkTarget(const char* pathname); + static const char* GetCanonicalPath(const char* path); + static FileOpenMode DartModeToFileMode(DartFileOpenMode mode); static CObject* ExistsRequest(const CObjectArray& request); diff --git a/runtime/bin/file_android.cc b/runtime/bin/file_android.cc index a139876bdb3..ea512ad6593 100644 --- a/runtime/bin/file_android.cc +++ b/runtime/bin/file_android.cc @@ -183,7 +183,7 @@ File* File::FileOpenW(const wchar_t* system_name, FileOpenMode mode) { } -File* File::ScopedOpen(const char* name, FileOpenMode mode) { +File* File::Open(const char* name, FileOpenMode mode) { // Report errors for non-regular files. struct stat st; if (NO_RETRY_EXPECTED(stat(name, &st)) == 0) { @@ -220,12 +220,6 @@ File* File::ScopedOpen(const char* name, FileOpenMode mode) { } -File* File::Open(const char* path, FileOpenMode mode) { - // ScopedOpen doesn't actually need a scope. - return ScopedOpen(path, mode); -} - - File* File::OpenStdio(int fd) { return ((fd < 0) || (2 < fd)) ? NULL : new File(new FileHandle(fd)); } diff --git a/runtime/bin/file_fuchsia.cc b/runtime/bin/file_fuchsia.cc index da22733f192..ae4233334cc 100644 --- a/runtime/bin/file_fuchsia.cc +++ b/runtime/bin/file_fuchsia.cc @@ -164,7 +164,7 @@ File* File::FileOpenW(const wchar_t* system_name, FileOpenMode mode) { } -File* File::ScopedOpen(const char* name, FileOpenMode mode) { +File* File::Open(const char* name, FileOpenMode mode) { // Report errors for non-regular files. struct stat st; if (NO_RETRY_EXPECTED(stat(name, &st)) == 0) { @@ -201,12 +201,6 @@ File* File::ScopedOpen(const char* name, FileOpenMode mode) { } -File* File::Open(const char* path, FileOpenMode mode) { - // ScopedOpen doesn't actually need a scope. - return ScopedOpen(path, mode); -} - - File* File::OpenStdio(int fd) { return ((fd < 0) || (2 < fd)) ? NULL : new File(new FileHandle(fd)); } diff --git a/runtime/bin/file_linux.cc b/runtime/bin/file_linux.cc index e6b27f8ace5..aeba5c836d8 100644 --- a/runtime/bin/file_linux.cc +++ b/runtime/bin/file_linux.cc @@ -182,7 +182,7 @@ File* File::FileOpenW(const wchar_t* system_name, FileOpenMode mode) { } -File* File::ScopedOpen(const char* name, FileOpenMode mode) { +File* File::Open(const char* name, FileOpenMode mode) { // Report errors for non-regular files. struct stat64 st; if (TEMP_FAILURE_RETRY(stat64(name, &st)) == 0) { @@ -220,12 +220,6 @@ File* File::ScopedOpen(const char* name, FileOpenMode mode) { } -File* File::Open(const char* path, FileOpenMode mode) { - // ScopedOpen doesn't actually need a scope. - return ScopedOpen(path, mode); -} - - File* File::OpenStdio(int fd) { return ((fd < 0) || (2 < fd)) ? NULL : new File(new FileHandle(fd)); } diff --git a/runtime/bin/file_macos.cc b/runtime/bin/file_macos.cc index 0720b6f3437..fe34eb75274 100644 --- a/runtime/bin/file_macos.cc +++ b/runtime/bin/file_macos.cc @@ -185,7 +185,7 @@ File* File::FileOpenW(const wchar_t* system_name, FileOpenMode mode) { } -File* File::ScopedOpen(const char* name, FileOpenMode mode) { +File* File::Open(const char* name, FileOpenMode mode) { // Report errors for non-regular files. struct stat st; if (NO_RETRY_EXPECTED(stat(name, &st)) == 0) { @@ -223,12 +223,6 @@ File* File::ScopedOpen(const char* name, FileOpenMode mode) { } -File* File::Open(const char* path, FileOpenMode mode) { - // ScopedOpen doesn't actually need a scope. - return ScopedOpen(path, mode); -} - - File* File::OpenStdio(int fd) { return ((fd < 0) || (2 < fd)) ? NULL : new File(new FileHandle(fd)); } diff --git a/runtime/bin/file_system_watcher_win.cc b/runtime/bin/file_system_watcher_win.cc index 698b0495039..ced2cefbb08 100644 --- a/runtime/bin/file_system_watcher_win.cc +++ b/runtime/bin/file_system_watcher_win.cc @@ -40,8 +40,8 @@ intptr_t FileSystemWatcher::WatchPath(intptr_t id, int events, bool recursive) { USE(id); - const wchar_t* name = StringUtilsWin::Utf8ToWide(path); - HANDLE dir = CreateFileW(name, + Utf8ToWideScope name(path); + HANDLE dir = CreateFileW(name.wide(), FILE_LIST_DIRECTORY, FILE_SHARE_READ | FILE_SHARE_WRITE | diff --git a/runtime/bin/file_win.cc b/runtime/bin/file_win.cc index d1e771948cf..fc72a78f3fd 100644 --- a/runtime/bin/file_win.cc +++ b/runtime/bin/file_win.cc @@ -233,21 +233,9 @@ File* File::FileOpenW(const wchar_t* system_name, FileOpenMode mode) { } -File* File::ScopedOpen(const char* name, FileOpenMode mode) { - const wchar_t* system_name = StringUtilsWin::Utf8ToWide(name); - return FileOpenW(system_name, mode); -} - - File* File::Open(const char* path, FileOpenMode mode) { - int path_len = MultiByteToWideChar(CP_UTF8, 0, path, -1, NULL, 0); - wchar_t* system_name = new wchar_t[path_len]; - if (system_name == NULL) { - return NULL; - } - MultiByteToWideChar(CP_UTF8, 0, path, -1, system_name, path_len); - File* file = FileOpenW(system_name, mode); - delete[] system_name; + Utf8ToWideScope system_name(path); + File* file = FileOpenW(system_name.wide(), mode); return file; } @@ -270,8 +258,8 @@ File* File::OpenStdio(int fd) { bool File::Exists(const char* name) { struct __stat64 st; - const wchar_t* system_name = StringUtilsWin::Utf8ToWide(name); - bool stat_status = _wstat64(system_name, &st); + Utf8ToWideScope system_name(name); + bool stat_status = _wstat64(system_name.wide(), &st); if (stat_status == 0) { return ((st.st_mode & S_IFMT) == S_IFREG); } else { @@ -281,8 +269,8 @@ bool File::Exists(const char* name) { bool File::Create(const char* name) { - const wchar_t* system_name = StringUtilsWin::Utf8ToWide(name); - int fd = _wopen(system_name, O_RDONLY | O_CREAT, 0666); + Utf8ToWideScope system_name(name); + int fd = _wopen(system_name.wide(), O_RDONLY | O_CREAT, 0666); if (fd < 0) { return false; } @@ -326,17 +314,17 @@ static const int kMountPointHeaderSize = 4 * sizeof USHORT; bool File::CreateLink(const char* utf8_name, const char* utf8_target) { - const wchar_t* name = StringUtilsWin::Utf8ToWide(utf8_name); - int create_status = CreateDirectoryW(name, NULL); + Utf8ToWideScope name(utf8_name); + int create_status = CreateDirectoryW(name.wide(), NULL); // If the directory already existed, treat it as a success. if ((create_status == 0) && ((GetLastError() != ERROR_ALREADY_EXISTS) || - ((GetFileAttributesW(name) & FILE_ATTRIBUTE_DIRECTORY) != 0))) { + ((GetFileAttributesW(name.wide()) & FILE_ATTRIBUTE_DIRECTORY) != 0))) { return false; } HANDLE dir_handle = CreateFileW( - name, + name.wide(), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, @@ -347,8 +335,8 @@ bool File::CreateLink(const char* utf8_name, const char* utf8_target) { return false; } - const wchar_t* target = StringUtilsWin::Utf8ToWide(utf8_target); - int target_len = wcslen(target); + Utf8ToWideScope target(utf8_target); + int target_len = wcslen(target.wide()); if (target_len > MAX_PATH - 1) { CloseHandle(dir_handle); return false; @@ -357,13 +345,13 @@ bool File::CreateLink(const char* utf8_name, const char* utf8_target) { int reparse_data_buffer_size = sizeof REPARSE_DATA_BUFFER + 2 * MAX_PATH * sizeof WCHAR; REPARSE_DATA_BUFFER* reparse_data_buffer = - reinterpret_cast(Dart_ScopeAllocate( - reparse_data_buffer_size)); + reinterpret_cast(malloc(reparse_data_buffer_size)); reparse_data_buffer->ReparseTag = IO_REPARSE_TAG_MOUNT_POINT; - wcscpy(reparse_data_buffer->MountPointReparseBuffer.PathBuffer, target); + wcscpy(reparse_data_buffer->MountPointReparseBuffer.PathBuffer, + target.wide()); wcscpy( reparse_data_buffer->MountPointReparseBuffer.PathBuffer + target_len + 1, - target); + target.wide()); reparse_data_buffer->MountPointReparseBuffer.SubstituteNameOffset = 0; reparse_data_buffer->MountPointReparseBuffer.SubstituteNameLength = target_len * sizeof WCHAR; @@ -383,6 +371,7 @@ bool File::CreateLink(const char* utf8_name, const char* utf8_target) { 0, &dummy_received_bytes, NULL); + free(reparse_data_buffer); if (CloseHandle(dir_handle) == 0) { return false; } @@ -391,20 +380,20 @@ bool File::CreateLink(const char* utf8_name, const char* utf8_target) { bool File::Delete(const char* name) { - const wchar_t* system_name = StringUtilsWin::Utf8ToWide(name); - int status = _wremove(system_name); + Utf8ToWideScope system_name(name); + int status = _wremove(system_name.wide()); return status != -1; } bool File::DeleteLink(const char* name) { - const wchar_t* system_name = StringUtilsWin::Utf8ToWide(name); + Utf8ToWideScope system_name(name); bool result = false; - DWORD attributes = GetFileAttributesW(system_name); + DWORD attributes = GetFileAttributesW(system_name.wide()); if ((attributes != INVALID_FILE_ATTRIBUTES) && (attributes & FILE_ATTRIBUTE_REPARSE_POINT) != 0) { // It's a junction(link), delete it. - result = (RemoveDirectoryW(system_name) != 0); + result = (RemoveDirectoryW(system_name.wide()) != 0); } else { SetLastError(ERROR_NOT_A_REPARSE_POINT); } @@ -415,11 +404,11 @@ bool File::DeleteLink(const char* name) { bool File::Rename(const char* old_path, const char* new_path) { File::Type type = GetType(old_path, false); if (type == kIsFile) { - const wchar_t* system_old_path = StringUtilsWin::Utf8ToWide(old_path); - const wchar_t* system_new_path = StringUtilsWin::Utf8ToWide(new_path); + Utf8ToWideScope system_old_path(old_path); + Utf8ToWideScope system_new_path(new_path); DWORD flags = MOVEFILE_WRITE_THROUGH | MOVEFILE_REPLACE_EXISTING; int move_status = - MoveFileExW(system_old_path, system_new_path, flags); + MoveFileExW(system_old_path.wide(), system_new_path.wide(), flags); return (move_status != 0); } else { SetLastError(ERROR_FILE_NOT_FOUND); @@ -431,11 +420,11 @@ bool File::Rename(const char* old_path, const char* new_path) { bool File::RenameLink(const char* old_path, const char* new_path) { File::Type type = GetType(old_path, false); if (type == kIsLink) { - const wchar_t* system_old_path = StringUtilsWin::Utf8ToWide(old_path); - const wchar_t* system_new_path = StringUtilsWin::Utf8ToWide(new_path); + Utf8ToWideScope system_old_path(old_path); + Utf8ToWideScope system_new_path(new_path); DWORD flags = MOVEFILE_WRITE_THROUGH | MOVEFILE_REPLACE_EXISTING; int move_status = - MoveFileExW(system_old_path, system_new_path, flags); + MoveFileExW(system_old_path.wide(), system_new_path.wide(), flags); return (move_status != 0); } else { SetLastError(ERROR_FILE_NOT_FOUND); @@ -447,10 +436,10 @@ bool File::RenameLink(const char* old_path, const char* new_path) { bool File::Copy(const char* old_path, const char* new_path) { File::Type type = GetType(old_path, false); if (type == kIsFile) { - const wchar_t* system_old_path = StringUtilsWin::Utf8ToWide(old_path); - const wchar_t* system_new_path = StringUtilsWin::Utf8ToWide(new_path); - bool success = CopyFileExW(system_old_path, - system_new_path, + Utf8ToWideScope system_old_path(old_path); + Utf8ToWideScope system_new_path(new_path); + bool success = CopyFileExW(system_old_path.wide(), + system_new_path.wide(), NULL, NULL, NULL, @@ -465,8 +454,8 @@ bool File::Copy(const char* old_path, const char* new_path) { int64_t File::LengthFromPath(const char* name) { struct __stat64 st; - const wchar_t* system_name = StringUtilsWin::Utf8ToWide(name); - int stat_status = _wstat64(system_name, &st); + Utf8ToWideScope system_name(name); + int stat_status = _wstat64(system_name.wide(), &st); if (stat_status == 0) { return st.st_size; } @@ -565,8 +554,8 @@ void File::Stat(const char* name, int64_t* data) { data[kType] = type; if (type != kDoesNotExist) { struct _stat64 st; - const wchar_t* system_name = StringUtilsWin::Utf8ToWide(name); - int stat_status = _wstat64(system_name, &st); + Utf8ToWideScope system_name(name); + int stat_status = _wstat64(system_name.wide(), &st); if (stat_status == 0) { data[kCreatedTime] = st.st_ctime * 1000; data[kModifiedTime] = st.st_mtime * 1000; @@ -582,8 +571,8 @@ void File::Stat(const char* name, int64_t* data) { time_t File::LastModified(const char* name) { struct __stat64 st; - const wchar_t* system_name = StringUtilsWin::Utf8ToWide(name); - int stat_status = _wstat64(system_name, &st); + Utf8ToWideScope system_name(name); + int stat_status = _wstat64(system_name.wide(), &st); if (stat_status == 0) { return st.st_mtime; } @@ -603,9 +592,9 @@ bool File::IsAbsolutePath(const char* pathname) { const char* File::GetCanonicalPath(const char* pathname) { - const wchar_t* system_name = StringUtilsWin::Utf8ToWide(pathname); + Utf8ToWideScope system_name(pathname); HANDLE file_handle = CreateFileW( - system_name, + system_name.wide(), 0, FILE_SHARE_READ, NULL, @@ -639,7 +628,7 @@ const char* File::GetCanonicalPath(const char* pathname) { if ((result_size < MAX_PATH - 1 + 4) && (result_size > 4) && (wcsncmp(path, L"\\\\?\\", 4) == 0) && - (wcsncmp(system_name, L"\\\\?\\", 4) != 0)) { + (wcsncmp(system_name.wide(), L"\\\\?\\", 4) != 0)) { result = StringUtilsWin::WideToUtf8(path + 4); } else { result = StringUtilsWin::WideToUtf8(path); @@ -670,19 +659,15 @@ File::StdioHandleType File::GetStdioHandleType(int fd) { File::Type File::GetType(const char* pathname, bool follow_links) { // Convert to wchar_t string. - int name_len = MultiByteToWideChar(CP_UTF8, 0, pathname, -1, NULL, 0); - wchar_t* name; - name = new wchar_t[name_len]; - MultiByteToWideChar(CP_UTF8, 0, pathname, -1, name, name_len); - - DWORD attributes = GetFileAttributesW(name); + Utf8ToWideScope name(pathname); + DWORD attributes = GetFileAttributesW(name.wide()); File::Type result = kIsFile; if (attributes == INVALID_FILE_ATTRIBUTES) { result = kDoesNotExist; } else if ((attributes & FILE_ATTRIBUTE_REPARSE_POINT) != 0) { if (follow_links) { HANDLE dir_handle = CreateFileW( - name, + name.wide(), 0, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, @@ -701,7 +686,6 @@ File::Type File::GetType(const char* pathname, bool follow_links) { } else if ((attributes & FILE_ATTRIBUTE_DIRECTORY) != 0) { result = kIsDirectory; } - delete[] name; return result; } @@ -710,9 +694,9 @@ File::Identical File::AreIdentical(const char* file_1, const char* file_2) { BY_HANDLE_FILE_INFORMATION file_info[2]; const char* file_names[2] = { file_1, file_2 }; for (int i = 0; i < 2; ++i) { - const wchar_t* wide_name = StringUtilsWin::Utf8ToWide(file_names[i]); + Utf8ToWideScope wide_name(file_names[i]); HANDLE file_handle = CreateFileW( - wide_name, + wide_name.wide(), 0, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, diff --git a/runtime/bin/socket_win.cc b/runtime/bin/socket_win.cc index f76f764c7c4..1dce52e9d97 100644 --- a/runtime/bin/socket_win.cc +++ b/runtime/bin/socket_win.cc @@ -370,12 +370,12 @@ bool Socket::ReverseLookup(const RawAddr& addr, bool Socket::ParseAddress(int type, const char* address, RawAddr* addr) { int result; - const wchar_t* system_address = StringUtilsWin::Utf8ToWide(address); + Utf8ToWideScope system_address(address); if (type == SocketAddress::TYPE_IPV4) { - result = InetPton(AF_INET, system_address, &addr->in.sin_addr); + result = InetPton(AF_INET, system_address.wide(), &addr->in.sin_addr); } else { ASSERT(type == SocketAddress::TYPE_IPV6); - result = InetPton(AF_INET6, system_address, &addr->in6.sin6_addr); + result = InetPton(AF_INET6, system_address.wide(), &addr->in6.sin6_addr); } return result == 1; } diff --git a/runtime/bin/utils_win.h b/runtime/bin/utils_win.h index fe0fa5c8140..3e7fa4c982e 100644 --- a/runtime/bin/utils_win.h +++ b/runtime/bin/utils_win.h @@ -37,6 +37,61 @@ class StringUtilsWin { DISALLOW_IMPLICIT_CONSTRUCTORS(StringUtilsWin); }; +// These scopes provide strings converted as indicated by the scope names. +// The provided strings are allocated with 'new' and have the same lifetime as +// the scope. +class WideToUtf8Scope { + public: + explicit WideToUtf8Scope(const wchar_t* wide) { + intptr_t utf8_len = WideCharToMultiByte( + CP_UTF8, 0, wide, -1, NULL, 0, NULL, NULL); + char* utf8 = new char[utf8_len]; + WideCharToMultiByte(CP_UTF8, 0, wide, -1, utf8, utf8_len, NULL, NULL); + length_ = utf8_len; + utf8_ = utf8; + } + + ~WideToUtf8Scope() { + delete[] utf8_; + utf8_ = NULL; + } + + char* utf8() const { return utf8_; } + intptr_t length() const { return length_; } + + private: + intptr_t length_; + char* utf8_; + + DISALLOW_ALLOCATION(); + DISALLOW_IMPLICIT_CONSTRUCTORS(WideToUtf8Scope); +}; + +class Utf8ToWideScope { + public: + explicit Utf8ToWideScope(const char* utf8) { + int wide_len = MultiByteToWideChar(CP_UTF8, 0, utf8, -1, NULL, 0); + wchar_t* wide = new wchar_t[wide_len]; + MultiByteToWideChar(CP_UTF8, 0, utf8, -1, wide, wide_len); + length_ = wide_len; + wide_ = wide; + } + + ~Utf8ToWideScope() { + delete[] wide_; + } + + wchar_t* wide() const { return wide_; } + intptr_t length() const { return length_; } + + private: + intptr_t length_; + wchar_t* wide_; + + DISALLOW_ALLOCATION(); + DISALLOW_IMPLICIT_CONSTRUCTORS(Utf8ToWideScope); +}; + } // namespace bin } // namespace dart