cmake: supernova - missing include_directories() for Jack
[supercollider.git] / external_libraries / boost / libs / filesystem / v3 / src / unique_path.cpp
blob1569b32e91538000c6f4b3c93d29dba56a732b15
1 // filesystem system_crypt_random.cpp ------------------------------------------------//
3 // Copyright Beman Dawes 2010
5 // Distributed under the Boost Software License, Version 1.0.
6 // See http://www.boost.org/LICENSE_1_0.txt
8 // Library home page: http://www.boost.org/libs/filesystem
10 //--------------------------------------------------------------------------------------//
12 #include <boost/config.hpp>
13 #if !defined( BOOST_NO_STD_WSTRING )
14 // Boost.Filesystem V3 and later requires std::wstring support.
15 // During the transition to V3, libraries are compiled with both V2 and V3 sources.
16 // On old compilers that don't support V3 anyhow, we just skip everything so the compile
17 // will succeed and the library can be built.
19 // define BOOST_FILESYSTEM_SOURCE so that <boost/filesystem/config.hpp> knows
20 // the library is being built (possibly exporting rather than importing code)
21 #define BOOST_FILESYSTEM_SOURCE
23 #ifndef BOOST_SYSTEM_NO_DEPRECATED
24 # define BOOST_SYSTEM_NO_DEPRECATED
25 #endif
27 #include <boost/filesystem/v3/operations.hpp>
29 # ifdef BOOST_POSIX_API
30 # include <fcntl.h>
31 # else // BOOST_WINDOWS_API
32 # include <windows.h>
33 # include <wincrypt.h>
34 # pragma comment(lib, "Advapi32.lib")
35 # endif
37 namespace {
39 void fail(int err, boost::system::error_code* ec)
41 if (ec == 0)
42 BOOST_FILESYSTEM_THROW( boost::system::system_error(err,
43 boost::system::system_category(),
44 "boost::filesystem::unique_path"));
46 ec->assign(err, boost::system::system_category());
47 return;
50 void system_crypt_random(void* buf, std::size_t len, boost::system::error_code* ec)
52 # ifdef BOOST_POSIX_API
54 int file = open("/dev/urandom", O_RDONLY);
55 if (file == -1)
57 file = open("/dev/random", O_RDONLY);
58 if (file == -1)
60 fail(errno, ec);
61 return;
65 size_t bytes_read = 0;
66 while (bytes_read < len)
68 ssize_t n = read(file, buf, len - bytes_read);
69 if (n == -1)
71 close(file);
72 fail(errno, ec);
73 return;
75 bytes_read += n;
76 buf = static_cast<char*>(buf) + n;
79 close(file);
81 # else // BOOST_WINDOWS_API
83 HCRYPTPROV handle;
84 int errval = 0;
86 if (!::CryptAcquireContextW(&handle, 0, 0, PROV_RSA_FULL, 0))
88 errval = ::GetLastError();
89 if (errval == NTE_BAD_KEYSET)
91 if (!::CryptAcquireContextW(&handle, 0, 0, PROV_RSA_FULL, CRYPT_NEWKEYSET))
93 errval = ::GetLastError();
95 else errval = 0;
99 if (!errval)
101 BOOL gen_ok = ::CryptGenRandom(handle, len, static_cast<unsigned char*>(buf));
102 if (!gen_ok)
103 errval = ::GetLastError();
104 ::CryptReleaseContext(handle, 0);
107 if (!errval) return;
109 fail(errval, ec);
110 # endif
113 } // unnamed namespace
115 namespace boost { namespace filesystem3 { namespace detail {
117 BOOST_FILESYSTEM_DECL
118 path unique_path(const path& model, system::error_code* ec)
120 std::wstring s (model.wstring()); // std::string ng for MBCS encoded POSIX
121 const wchar_t hex[] = L"0123456789abcdef";
122 const int n_ran = 16;
123 const int max_nibbles = 2 * n_ran; // 4-bits per nibble
124 char ran[n_ran];
126 int nibbles_used = max_nibbles;
127 for(std::wstring::size_type i=0; i < s.size(); ++i)
129 if (s[i] == L'%') // digit request
131 if (nibbles_used == max_nibbles)
133 system_crypt_random(ran, sizeof(ran), ec);
134 if (ec != 0 && *ec)
135 return "";
136 nibbles_used = 0;
138 int c = ran[nibbles_used/2];
139 c >>= 4 * (nibbles_used++ & 1); // if odd, shift right 1 nibble
140 s[i] = hex[c & 0xf]; // convert to hex digit and replace
144 if (ec != 0) ec->clear();
146 return s;
151 #endif // no wide character support