Merge pull request #26220 from 78andyp/blurayfixes
[xbmc.git] / xbmc / utils / UrlOptions.cpp
blob389d08dbad5094dbc908e02c849d6d55441011d3
1 /*
2 * Copyright (C) 2012-2018 Team Kodi
3 * This file is part of Kodi - https://kodi.tv
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 * See LICENSES/README.md for more information.
7 */
9 #include "UrlOptions.h"
11 #include "URL.h"
12 #include "utils/StringUtils.h"
13 #include "utils/log.h"
15 CUrlOptions::CUrlOptions() = default;
17 CUrlOptions::CUrlOptions(const std::string &options, const char *strLead /* = "" */)
18 : m_strLead(strLead)
20 AddOptions(options);
23 CUrlOptions::~CUrlOptions() = default;
25 std::string CUrlOptions::GetOptionsString(bool withLeadingSeparator /* = false */) const
27 std::string options;
28 for (const auto &opt : m_options)
30 if (!options.empty())
31 options += "&";
33 options += CURL::Encode(opt.first);
34 if (!opt.second.empty())
35 options += "=" + CURL::Encode(opt.second.asString());
38 if (withLeadingSeparator && !options.empty())
40 if (m_strLead.empty())
41 options = "?" + options;
42 else
43 options = m_strLead + options;
46 return options;
49 void CUrlOptions::AddOption(const std::string &key, const char *value)
51 if (key.empty() || value == NULL)
52 return;
54 return AddOption(key, std::string(value));
57 void CUrlOptions::AddOption(const std::string &key, const std::string &value)
59 if (key.empty())
60 return;
62 m_options[key] = value;
65 void CUrlOptions::AddOption(const std::string &key, int value)
67 if (key.empty())
68 return;
70 m_options[key] = value;
73 void CUrlOptions::AddOption(const std::string &key, float value)
75 if (key.empty())
76 return;
78 m_options[key] = value;
81 void CUrlOptions::AddOption(const std::string &key, double value)
83 if (key.empty())
84 return;
86 m_options[key] = value;
89 void CUrlOptions::AddOption(const std::string &key, bool value)
91 if (key.empty())
92 return;
94 m_options[key] = value;
97 void CUrlOptions::AddOptions(const std::string &options)
99 if (options.empty())
100 return;
102 std::string strOptions = options;
104 // if matching the preset leading str, remove from options.
105 if (!m_strLead.empty() && strOptions.compare(0, m_strLead.length(), m_strLead) == 0)
106 strOptions.erase(0, m_strLead.length());
107 else if (strOptions.at(0) == '?' || strOptions.at(0) == '#' || strOptions.at(0) == ';' || strOptions.at(0) == '|')
109 // remove leading ?, #, ; or | if present
110 if (!m_strLead.empty())
111 CLog::Log(LOGWARNING, "{}: original leading str {} overridden by {}", __FUNCTION__, m_strLead,
112 strOptions.at(0));
113 m_strLead = strOptions.at(0);
114 strOptions.erase(0, 1);
117 // split the options by & and process them one by one
118 for (const auto &option : StringUtils::Split(strOptions, "&"))
120 if (option.empty())
121 continue;
123 std::string key, value;
125 size_t pos = option.find('=');
126 key = CURL::Decode(option.substr(0, pos));
127 if (pos != std::string::npos)
128 value = CURL::Decode(option.substr(pos + 1));
130 // the key cannot be empty
131 if (!key.empty())
132 AddOption(key, value);
136 void CUrlOptions::AddOptions(const CUrlOptions &options)
138 m_options.insert(options.m_options.begin(), options.m_options.end());
141 void CUrlOptions::RemoveOption(const std::string &key)
143 if (key.empty())
144 return;
146 auto option = m_options.find(key);
147 if (option != m_options.end())
148 m_options.erase(option);
151 bool CUrlOptions::HasOption(const std::string &key) const
153 if (key.empty())
154 return false;
156 return m_options.find(key) != m_options.end();
159 bool CUrlOptions::GetOption(const std::string &key, CVariant &value) const
161 if (key.empty())
162 return false;
164 auto option = m_options.find(key);
165 if (option == m_options.end())
166 return false;
168 value = option->second;
169 return true;