Skip to content

Commit 7bb887b

Browse files
committed
Lets try uriparser
Signed-off-by: Darby Johnston <[email protected]>
1 parent 1172e27 commit 7bb887b

File tree

3 files changed

+35
-155
lines changed

3 files changed

+35
-155
lines changed

src/opentimelineio/bundleUtils.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ SerializableObject::Retainer<Timeline> timeline_for_bundle_and_manifest(
118118
std::string const url = er ? er->target_url()
119119
: isr->target_url_base();
120120
std::string const scheme = scheme_from_url(url);
121-
if (!(scheme == "file://" || scheme.empty()))
121+
if (!(scheme == "file" || scheme.empty()))
122122
{
123123
if (MediaReferencePolicy::ErrorIfNotFile == media_policy)
124124
{

src/opentimelineio/urlUtils.cpp

Lines changed: 34 additions & 131 deletions
Original file line numberDiff line numberDiff line change
@@ -5,161 +5,64 @@
55

66
#include "opentimelineio/fileUtils.h"
77

8-
#include <algorithm>
8+
#include <uriparser/Uri.h>
9+
910
#include <filesystem>
10-
#include <iomanip>
11-
#include <regex>
12-
#include <sstream>
11+
#include <iostream>
1312

1413
namespace opentimelineio { namespace OPENTIMELINEIO_VERSION {
1514

1615
std::string
1716
scheme_from_url(std::string const& url)
1817
{
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)
3722
{
38-
auto const j = std::find(chars.begin(), chars.end(), *i);
39-
if (std::isalnum(*i) || j != chars.end())
23+
if (uri.scheme.first)
4024
{
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);
4626
}
27+
uriFreeUriMembersA(&uri);
4728
}
48-
return ss.str();
29+
return out;
4930
}
5031

5132
std::string
52-
url_decode(std::string const& url)
33+
url_from_filepath(std::string const& filepath)
5334
{
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())
6243
{
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());
8345
}
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;
9648
}
9749

9850
std::string
9951
filepath_from_url(std::string const& url)
10052
{
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())
14961
{
150-
has_unc = true;
151-
decoded.insert(0, "//");
62+
out = std::string(tmp.data());
15263
}
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;
16366
}
16467

16568
}} // namespace opentimelineio::OPENTIMELINEIO_VERSION

src/opentimelineio/urlUtils.h

Lines changed: 0 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -9,38 +9,15 @@
99
namespace opentimelineio { namespace OPENTIMELINEIO_VERSION {
1010

1111
/// @name URL Utilities
12-
/// @todo Should we use a third party library for handling URLs?
1312
///@{
1413

1514
/// @brief Get the scheme from a URL.
1615
OTIO_API std::string scheme_from_url(std::string const&);
1716

18-
/// @brief Encode a URL (i.e., replace " " characters with "%20").
19-
OTIO_API std::string url_encode(std::string const& url);
20-
21-
/// @brief Decode a URL (i.e., replace "%20" strings with " ").
22-
std::string url_decode(std::string const& url);
23-
2417
/// @brief Convert a filesystem path to a file URL.
25-
///
26-
/// For example:
27-
/// * "/var/tmp/thing.otio" -> "file:///var/tmp/thing.otio"
28-
/// * "subdir/thing.otio" -> "tmp/thing.otio"
29-
///
30-
/// @todo Hopefully this can be replaced by functionality from the C++
31-
/// standard library at some point.
3218
OTIO_API std::string url_from_filepath(std::string const&);
3319

3420
/// @brief Convert a file URL to a filesystem path.
35-
///
36-
/// URLs can either be encoded according to the `RFC 3986` standard or not.
37-
/// Additionally, Windows mapped drive letter and UNC paths need to be
38-
/// accounted for when processing URLs.
39-
///
40-
/// RFC 3986: https://tools.ietf.org/html/rfc3986
41-
///
42-
/// @todo Hopefully this can be replaced by functionality from the C++
43-
/// standard library at some point.
4421
OTIO_API std::string filepath_from_url(std::string const&);
4522

4623
///@}

0 commit comments

Comments
 (0)