|  | @@ -57,6 +57,7 @@
 | 
	
		
			
				|  |  |  #include <windows.h>
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  #include <google/protobuf/stubs/io_win32.h>
 | 
	
		
			
				|  |  | +#include <google/protobuf/stubs/scoped_ptr.h>
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  #include <cassert>
 | 
	
		
			
				|  |  |  #include <memory>
 | 
	
	
		
			
				|  | @@ -71,7 +72,6 @@ namespace win32 {
 | 
	
		
			
				|  |  |  namespace {
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  using std::string;
 | 
	
		
			
				|  |  | -using std::unique_ptr;
 | 
	
		
			
				|  |  |  using std::wstring;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  template <typename char_type>
 | 
	
	
		
			
				|  | @@ -139,11 +139,11 @@ string join_paths(const string& path1, const string& path2) {
 | 
	
		
			
				|  |  |      return path1;
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -  if (is_separator(path1.back())) {
 | 
	
		
			
				|  |  | -    return is_separator(path2.front()) ? (path1 + path2.substr(1))
 | 
	
		
			
				|  |  | +  if (is_separator(path1[path1.size() - 1])) {
 | 
	
		
			
				|  |  | +    return is_separator(path2[0]) ? (path1 + path2.substr(1))
 | 
	
		
			
				|  |  |                                         : (path1 + path2);
 | 
	
		
			
				|  |  |    } else {
 | 
	
		
			
				|  |  | -    return is_separator(path2.front()) ? (path1 + path2)
 | 
	
		
			
				|  |  | +    return is_separator(path2[0]) ? (path1 + path2)
 | 
	
		
			
				|  |  |                                         : (path1 + '\\' + path2);
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  |  }
 | 
	
	
		
			
				|  | @@ -203,24 +203,24 @@ string normalize(string path) {
 | 
	
		
			
				|  |  |      result << s;
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  |    // Preserve trailing separator if the input contained it.
 | 
	
		
			
				|  |  | -  if (is_separator(path.back())) {
 | 
	
		
			
				|  |  | +  if (!path.empty() && is_separator(path[path.size() - 1])) {
 | 
	
		
			
				|  |  |      result << '\\';
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  |    return result.str();
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -std::unique_ptr<WCHAR[]> as_wstring(const string& s) {
 | 
	
		
			
				|  |  | +WCHAR* as_wstring(const string& s) {
 | 
	
		
			
				|  |  |    int len = ::MultiByteToWideChar(CP_UTF8, 0, s.c_str(), s.size(), NULL, 0);
 | 
	
		
			
				|  |  | -  std::unique_ptr<WCHAR[]> result(new WCHAR[len + 1]);
 | 
	
		
			
				|  |  | -  ::MultiByteToWideChar(CP_UTF8, 0, s.c_str(), s.size(), result.get(), len + 1);
 | 
	
		
			
				|  |  | -  result.get()[len] = 0;
 | 
	
		
			
				|  |  | -  return std::move(result);
 | 
	
		
			
				|  |  | +  WCHAR* result = new WCHAR[len + 1];
 | 
	
		
			
				|  |  | +  ::MultiByteToWideChar(CP_UTF8, 0, s.c_str(), s.size(), result, len + 1);
 | 
	
		
			
				|  |  | +  result[len] = 0;
 | 
	
		
			
				|  |  | +  return result;
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -wstring as_wchar_path(const string& path) {
 | 
	
		
			
				|  |  | -  std::unique_ptr<WCHAR[]> wbuf(as_wstring(path));
 | 
	
		
			
				|  |  | +void as_wchar_path(const string& path, wstring* wchar_path) {
 | 
	
		
			
				|  |  | +  scoped_array<WCHAR> wbuf(as_wstring(path));
 | 
	
		
			
				|  |  |    replace_directory_separators(wbuf.get());
 | 
	
		
			
				|  |  | -  return wstring(wbuf.get());
 | 
	
		
			
				|  |  | +  wchar_path->assign(wbuf.get());
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  bool as_windows_path(const string& path, wstring* result) {
 | 
	
	
		
			
				|  | @@ -239,7 +239,7 @@ bool as_windows_path(const string& path, wstring* result) {
 | 
	
		
			
				|  |  |      ::GetCurrentDirectoryA(MAX_PATH, cwd);
 | 
	
		
			
				|  |  |      mutable_path = join_paths(cwd, mutable_path);
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  | -  *result = as_wchar_path(normalize(mutable_path));
 | 
	
		
			
				|  |  | +  as_wchar_path(normalize(mutable_path), result);
 | 
	
		
			
				|  |  |    if (!has_longpath_prefix(result->c_str())) {
 | 
	
		
			
				|  |  |      // Add the "\\?\" prefix unconditionally. This way we prevent the Win32 API
 | 
	
		
			
				|  |  |      // from processing the path and "helpfully" removing trailing dots from the
 | 
	
	
		
			
				|  | @@ -324,7 +324,7 @@ FILE* fopen(const char* path, const char* mode) {
 | 
	
		
			
				|  |  |      errno = ENOENT;
 | 
	
		
			
				|  |  |      return NULL;
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  | -  std::unique_ptr<WCHAR[]> wmode(as_wstring(mode));
 | 
	
		
			
				|  |  | +  scoped_array<WCHAR> wmode(as_wstring(mode));
 | 
	
		
			
				|  |  |    return ::_wfopen(wpath.c_str(), wmode.get());
 | 
	
		
			
				|  |  |  #else
 | 
	
		
			
				|  |  |    return ::fopen(path, mode);
 |