|
5 | 5 |
|
6 | 6 | #include "opentimelineio/fileUtils.h" |
7 | 7 |
|
8 | | -#include <algorithm> |
| 8 | +#include <uriparser/Uri.h> |
| 9 | + |
9 | 10 | #include <filesystem> |
10 | | -#include <iomanip> |
11 | | -#include <regex> |
12 | | -#include <sstream> |
| 11 | +#include <iostream> |
13 | 12 |
|
14 | 13 | namespace opentimelineio { namespace OPENTIMELINEIO_VERSION { |
15 | 14 |
|
16 | 15 | std::string |
17 | 16 | scheme_from_url(std::string const& url) |
18 | 17 | { |
19 | | - std::regex const rx("^([A-Za-z0-9+-\\.]+://)"); |
20 | | - auto const rxi = std::sregex_iterator(url.begin(), url.end(), rx); |
21 | | - return rxi != std::sregex_iterator() ? rxi->str() : std::string(); |
22 | | -} |
23 | | - |
24 | | -std::string |
25 | | -url_encode(std::string const& url) |
26 | | -{ |
27 | | - // Don't encode these characters. |
28 | | - std::vector<char> const chars = { '-', '.', '_', '~', ':', '/', '?', '#', |
29 | | - '[', ']', '@', '!', '$', '&', '\'', '(', |
30 | | - ')', '*', '+', ',', ';', '=', '\\' }; |
31 | | - |
32 | | - // Copy characters to the result, encoding if necessary. |
33 | | - std::stringstream ss; |
34 | | - ss.fill('0'); |
35 | | - ss << std::hex; |
36 | | - for (auto i = url.begin(), end = url.end(); i != end; ++i) |
| 18 | + std::string out; |
| 19 | + UriUriA uri; |
| 20 | + const char* uri_error_pos = nullptr; |
| 21 | + if (uriParseSingleUriA(&uri, url.c_str(), &uri_error_pos) == URI_SUCCESS) |
37 | 22 | { |
38 | | - auto const j = std::find(chars.begin(), chars.end(), *i); |
39 | | - if (std::isalnum(*i) || j != chars.end()) |
| 23 | + if (uri.scheme.first) |
40 | 24 | { |
41 | | - ss << *i; |
42 | | - } |
43 | | - else |
44 | | - { |
45 | | - ss << '%' << std::setw(2) << int(*i); |
| 25 | + out = std::string(uri.scheme.first, uri.scheme.afterLast - uri.scheme.first); |
46 | 26 | } |
| 27 | + uriFreeUriMembersA(&uri); |
47 | 28 | } |
48 | | - return ss.str(); |
| 29 | + return out; |
49 | 30 | } |
50 | 31 |
|
51 | 32 | std::string |
52 | | -url_decode(std::string const& url) |
| 33 | +url_from_filepath(std::string const& filepath) |
53 | 34 | { |
54 | | - std::string result; |
55 | | - |
56 | | - // Find all percent encodings. |
57 | | - size_t url_pos = 0; |
58 | | - std::regex const rx("(%[0-9A-Fa-f][0-9A-Fa-f])"); |
59 | | - for (auto i = std::sregex_iterator(url.begin(), url.end(), rx); |
60 | | - i != std::sregex_iterator(); |
61 | | - ++i) |
| 35 | + std::cout << "url_from_filepath()" << std::endl; |
| 36 | + std::cout << " filepath: " << filepath << std::endl; |
| 37 | + std::string out; |
| 38 | + //std::string tmp(8 + 3 * filepath.size() + 1, 0); |
| 39 | + //if (uriWindowsFilenameToUriStringA(filepath.c_str(), tmp.data()) == URI_SUCCESS) |
| 40 | + std::vector<char> tmp(7 + 3 * filepath.size() + 1, 0); |
| 41 | + if (uriUnixFilenameToUriStringA(filepath.c_str(), tmp.data()) == URI_SUCCESS && |
| 42 | + !tmp.empty()) |
62 | 43 | { |
63 | | - // Copy parts without any encodings. |
64 | | - if (url_pos != static_cast<size_t>(i->position())) |
65 | | - { |
66 | | - result.append(url.substr(url_pos, i->position() - url_pos)); |
67 | | - url_pos = i->position(); |
68 | | - } |
69 | | - |
70 | | - // Convert the encoding and append it. |
71 | | - std::stringstream ss; |
72 | | - ss << std::hex << i->str().substr(1); |
73 | | - unsigned int j = 0; |
74 | | - ss >> j; |
75 | | - result.push_back(char(j)); |
76 | | - url_pos += i->str().size(); |
77 | | - } |
78 | | - |
79 | | - // Copy the remainder without any encodings. |
80 | | - if (!url.empty() && url_pos != url.size() - 1) |
81 | | - { |
82 | | - result.append(url.substr(url_pos, url.size() - url_pos)); |
| 44 | + out = std::string(tmp.data()); |
83 | 45 | } |
84 | | - |
85 | | - return result; |
86 | | -} |
87 | | - |
88 | | -std::string |
89 | | -url_from_filepath(std::string const& filepath) |
90 | | -{ |
91 | | - std::string const encoded = url_encode(to_unix_separators(filepath)); |
92 | | - std::string const url = std::filesystem::u8path(filepath).is_relative() |
93 | | - ? encoded |
94 | | - : ("file://" + encoded); |
95 | | - return url; |
| 46 | + std::cout << " out: " << out.c_str() << std::endl; |
| 47 | + return out; |
96 | 48 | } |
97 | 49 |
|
98 | 50 | std::string |
99 | 51 | filepath_from_url(std::string const& url) |
100 | 52 | { |
101 | | - // Skip over the URL scheme. |
102 | | - bool has_scheme = false; |
103 | | - size_t pos = 0; |
104 | | - std::string const scheme = scheme_from_url(url); |
105 | | - if (!scheme.empty()) |
106 | | - { |
107 | | - has_scheme = true; |
108 | | - pos += scheme.size(); |
109 | | - } |
110 | | - |
111 | | - // Remove the URL query and fragment. |
112 | | - size_t size = std::string::npos; |
113 | | - size_t i = url.find('?', pos); |
114 | | - size_t j = url.find('#', pos); |
115 | | - if (i != std::string::npos || j != std::string::npos) |
116 | | - { |
117 | | - size = std::min(i, j) + 1; |
118 | | - } |
119 | | - std::string const path = url.substr(pos, size); |
120 | | - |
121 | | - // Decode the path. |
122 | | - std::string decoded = url_decode(path); |
123 | | - |
124 | | - // Use UNIX separators. |
125 | | - decoded = to_unix_separators(decoded); |
126 | | - |
127 | | - // Check for Windows drive letters. |
128 | | - bool has_windows_drive = false; |
129 | | - std::regex rx = std::regex("^([A-Za-z]:)"); |
130 | | - std::smatch matches; |
131 | | - if (std::regex_search(decoded, matches, rx)) |
132 | | - { |
133 | | - has_windows_drive = true; |
134 | | - } |
135 | | - else |
136 | | - { |
137 | | - rx = std::regex("^(.*/)([A-Za-z]:)"); |
138 | | - if (std::regex_search(decoded, matches, rx)) |
139 | | - { |
140 | | - has_windows_drive = true; |
141 | | - decoded = decoded.substr(matches.position(1) + matches.length(1)); |
142 | | - } |
143 | | - } |
144 | | - |
145 | | - // Add the "//" for UNC paths. |
146 | | - bool has_unc = false; |
147 | | - size = decoded.size(); |
148 | | - if (has_scheme && !has_windows_drive && pos < size - 1 && decoded[0] != '/') |
| 53 | + std::cout << "filepath_from_url()" << std::endl; |
| 54 | + std::cout << " url: " << url << std::endl; |
| 55 | + std::string out; |
| 56 | + //std::string tmp(url.size() + 1, 0); |
| 57 | + //if (uriUriStringToWindowsFilenameA(url.c_str(), tmp.data()) == URI_SUCCESS) |
| 58 | + std::vector<char> tmp(url.size() + 1, 0); |
| 59 | + if (uriUriStringToUnixFilenameA(url.c_str(), tmp.data()) == URI_SUCCESS && |
| 60 | + !tmp.empty()) |
149 | 61 | { |
150 | | - has_unc = true; |
151 | | - decoded.insert(0, "//"); |
| 62 | + out = std::string(tmp.data()); |
152 | 63 | } |
153 | | - |
154 | | - // Remove the current directory. |
155 | | - rx = std::regex("^(./)"); |
156 | | - if (!has_windows_drive && !has_unc |
157 | | - && std::regex_search(decoded, matches, rx)) |
158 | | - { |
159 | | - decoded = decoded.substr(matches.position() + matches.length()); |
160 | | - } |
161 | | - |
162 | | - return decoded; |
| 64 | + std::cout << " out: " << out.c_str() << std::endl; |
| 65 | + return out; |
163 | 66 | } |
164 | 67 |
|
165 | 68 | }} // namespace opentimelineio::OPENTIMELINEIO_VERSION |
0 commit comments