| 108 | namespace boost { namespace filesystem { namespace detail { |
| 109 | |
| 110 | BOOST_FILESYSTEM_DECL |
| 111 | path unique_path(const path& model, system::error_code* ec) |
| 112 | { |
| 113 | std::wstring s (model.wstring()); // std::string ng for MBCS encoded POSIX |
| 114 | const wchar_t hex[] = L"0123456789abcdef"; |
| 115 | const int n_ran = 16; |
| 116 | const int max_nibbles = 2 * n_ran; // 4-bits per nibble |
| 117 | char ran[n_ran]; |
| 118 | |
| 119 | int nibbles_used = max_nibbles; |
| 120 | for(std::wstring::size_type i=0; i < s.size(); ++i) |
| 121 | { |
| 122 | if (s[i] == L'%') // digit request |
| 123 | { |
| 124 | if (nibbles_used == max_nibbles) |
| 125 | { |
| 126 | system_crypt_random(ran, sizeof(ran), ec); |
| 127 | if (ec != 0 && *ec) |
| 128 | return ""; |
| 129 | nibbles_used = 0; |
| 130 | } |
| 131 | int c = ran[nibbles_used/2]; |
| 132 | c >>= 4 * (nibbles_used++ & 1); // if odd, shift right 1 nibble |
| 133 | s[i] = hex[c & 0xf]; // convert to hex digit and replace |
| 134 | } |
| 135 | } |
| 136 | |
| 137 | if (ec != 0) ec->clear(); |
| 138 | |
| 139 | return s; |
| 140 | } |
| 141 | |
| 142 | }}} |