Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Merge pull request #1802 from Montellese/urloptions_fix

allow key-only URL options and add CUrlOptions::RemoveOption()
  • Loading branch information...
commit a44e59f3b76f5d1f84d27f87c4896a699c8e914e 2 parents 7ec59c2 + a5d4013
@jmarshallnz jmarshallnz authored
View
7 project/VS2010Express/XBMC.vcxproj
@@ -1213,6 +1213,13 @@
</ClInclude>
<ClInclude Include="..\..\xbmc\interfaces\json-rpc\AddonsOperations.h" />
<ClCompile Include="..\..\xbmc\ThumbLoader.cpp" />
+ <ClCompile Include="..\..\xbmc\utils\test\TestUrlOptions.cpp">
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug (DirectX)|Win32'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug (OpenGL)|Win32'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release (DirectX)|Win32'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release (OpenGL)|Win32'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Template|Win32'">true</ExcludedFromBuild>
+ </ClCompile>
<ClCompile Include="..\..\xbmc\video\VideoThumbLoader.cpp" />
<ClCompile Include="..\..\xbmc\music\MusicThumbLoader.cpp" />
<ClCompile Include="..\..\xbmc\ThumbnailCache.cpp" />
View
3  project/VS2010Express/XBMC.vcxproj.filters
@@ -2948,6 +2948,9 @@
<ClCompile Include="..\..\xbmc\cores\AudioEngine\Utils\AELimiter.cpp">
<Filter>cores\AudioEngine\Utils</Filter>
</ClCompile>
+ <ClCompile Include="..\..\xbmc\utils\test\TestUrlOptions.cpp">
+ <Filter>utils\test</Filter>
+ </ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\xbmc\win32\pch.h">
View
6 xbmc/DbUrl.cpp
@@ -130,6 +130,12 @@ void CDbUrl::AddOptions(const std::string &options)
updateOptions();
}
+void CDbUrl::RemoveOption(const std::string &key)
+{
+ CUrlOptions::RemoveOption(key);
+ updateOptions();
+}
+
bool CDbUrl::validateOption(const std::string &key, const CVariant &value)
{
if (key.empty())
View
1  xbmc/DbUrl.h
@@ -46,6 +46,7 @@ class CDbUrl : public CUrlOptions
virtual void AddOption(const std::string &key, double value);
virtual void AddOption(const std::string &key, bool value);
virtual void AddOptions(const std::string &options);
+ virtual void RemoveOption(const std::string &key);
protected:
virtual bool parse() = 0;
View
2  xbmc/URL.cpp
@@ -801,6 +801,6 @@ void CURL::SetOption(const CStdString &key, const CStdString &value)
void CURL::RemoveOption(const CStdString &key)
{
- m_options.AddOption(key, "");
+ m_options.RemoveOption(key);
SetOptions(m_options.GetOptionsString(true));
}
View
2  xbmc/dialogs/GUIDialogMediaFilter.cpp
@@ -617,7 +617,7 @@ bool CGUIDialogMediaFilter::SetPath(const std::string &path)
// remove "filter" option
if (m_dbUrl->HasOption("filter"))
- m_dbUrl->AddOption("filter", "");
+ m_dbUrl->RemoveOption("filter");
if (video)
m_mediaType = ((CVideoDbUrl*)m_dbUrl)->GetItemType();
View
30 xbmc/filesystem/SmartPlaylistDirectory.cpp
@@ -111,7 +111,11 @@ namespace XFILE
if (!playlist.SaveAsJson(xsp, !filter))
return false;
}
- videoUrl.AddOption(option, xsp);
+
+ if (!xsp.empty())
+ videoUrl.AddOption(option, xsp);
+ else
+ videoUrl.RemoveOption(option);
CDatabase::Filter dbfilter;
success = db.GetSortedVideos(mediaType, videoUrl.ToString(), sorting, items, dbfilter);
@@ -140,7 +144,11 @@ namespace XFILE
if (!playlist.SaveAsJson(xsp, !filter))
return false;
}
- musicUrl.AddOption(option, xsp);
+
+ if (!xsp.empty())
+ musicUrl.AddOption(option, xsp);
+ else
+ musicUrl.RemoveOption(option);
CDatabase::Filter dbfilter;
success = db.GetAlbumsByWhere(musicUrl.ToString(), dbfilter, items, sorting);
@@ -165,7 +173,11 @@ namespace XFILE
if (!playlist.SaveAsJson(xsp, !filter))
return false;
}
- musicUrl.AddOption(option, xsp);
+
+ if (!xsp.empty())
+ musicUrl.AddOption(option, xsp);
+ else
+ musicUrl.RemoveOption(option);
CDatabase::Filter dbfilter;
success = db.GetArtistsNav(musicUrl.ToString(), items, !g_guiSettings.GetBool("musiclibrary.showcompilationartists"), -1, -1, -1, dbfilter, sorting);
@@ -195,7 +207,11 @@ namespace XFILE
if (!songPlaylist.SaveAsJson(xsp, !filter))
return false;
}
- musicUrl.AddOption(option, xsp);
+
+ if (!xsp.empty())
+ musicUrl.AddOption(option, xsp);
+ else
+ musicUrl.RemoveOption(option);
CDatabase::Filter dbfilter;
success = db.GetSongsByWhere(musicUrl.ToString(), dbfilter, items, sorting);
@@ -224,7 +240,11 @@ namespace XFILE
if (!mvidPlaylist.SaveAsJson(xsp, !filter))
return false;
}
- videoUrl.AddOption(option, xsp);
+
+ if (!xsp.empty())
+ videoUrl.AddOption(option, xsp);
+ else
+ videoUrl.RemoveOption(option);
CFileItemList items2;
success2 = db.GetSortedVideos(MediaTypeMusicVideo, videoUrl.ToString(), sorting, items2);
View
2  xbmc/music/MusicDatabase.cpp
@@ -5445,7 +5445,7 @@ bool CMusicDatabase::GetFilter(CDbUrl &musicUrl, Filter &filter, SortDescription
}
// remove the filter if it doesn't match the item type
else
- musicUrl.AddOption("filter", "");
+ musicUrl.RemoveOption("filter");
}
return true;
View
31 xbmc/utils/UrlOptions.cpp
@@ -46,7 +46,9 @@ std::string CUrlOptions::GetOptionsString(bool withLeadingSeperator /* = false *
if (opt != m_options.begin())
options += "&";
- options += CURL::Encode(opt->first) + "=" + CURL::Encode(opt->second.asString());
+ options += CURL::Encode(opt->first);
+ if (!opt->second.empty())
+ options += "=" + CURL::Encode(opt->second.asString());
}
if (withLeadingSeperator && !options.empty())
@@ -68,11 +70,7 @@ void CUrlOptions::AddOption(const std::string &key, const std::string &value)
if (key.empty())
return;
- UrlOptions::iterator option = m_options.find(key);
- if (!value.empty())
- m_options[key] = value;
- else if (option != m_options.end())
- m_options.erase(option);
+ m_options[key] = value;
}
void CUrlOptions::AddOption(const std::string &key, int value)
@@ -130,13 +128,12 @@ void CUrlOptions::AddOptions(const std::string &options)
if (option->empty())
continue;
- // every option must have the format key=value
- size_t pos = option->find('=');
- if (pos == string::npos || pos == 0 || pos >= option->size() - 1)
- continue;
+ string key, value;
- string key = CURL::Decode(option->substr(0, pos));
- string value = CURL::Decode(option->substr(pos + 1));
+ size_t pos = option->find('=');
+ key = CURL::Decode(option->substr(0, pos));
+ if (pos != string::npos)
+ value = CURL::Decode(option->substr(pos + 1));
// the key cannot be empty
if (!key.empty())
@@ -149,6 +146,16 @@ void CUrlOptions::AddOptions(const CUrlOptions &options)
m_options.insert(options.m_options.begin(), options.m_options.end());
}
+void CUrlOptions::RemoveOption(const std::string &key)
+{
+ if (key.empty())
+ return;
+
+ UrlOptions::iterator option = m_options.find(key);
+ if (option != m_options.end())
+ m_options.erase(option);
+}
+
bool CUrlOptions::HasOption(const std::string &key) const
{
if (key.empty())
View
1  xbmc/utils/UrlOptions.h
@@ -45,6 +45,7 @@ class CUrlOptions
virtual void AddOption(const std::string &key, bool value);
virtual void AddOptions(const std::string &options);
virtual void AddOptions(const CUrlOptions &options);
+ virtual void RemoveOption(const std::string &key);
virtual bool HasOption(const std::string &key) const;
virtual bool GetOption(const std::string &key, CVariant &value) const;
View
4 xbmc/utils/Variant.cpp
@@ -725,8 +725,10 @@ bool CVariant::empty() const
return m_data.string->empty();
else if (m_type == VariantTypeWideString)
return m_data.wstring->empty();
- else
+ else if (m_type == VariantTypeNull)
return true;
+
+ return false;
}
void CVariant::clear()
View
1  xbmc/utils/test/Makefile
@@ -49,6 +49,7 @@ SRCS= \
TestTimeSmoother.cpp \
TestTimeUtils.cpp \
TestURIUtils.cpp \
+ TestUrlOptions.cpp \
TestVariant.cpp \
TestXBMCTinyXML.cpp \
TestXMLUtils.cpp
View
204 xbmc/utils/test/TestUrlOptions.cpp
@@ -0,0 +1,204 @@
+/*
+ * Copyright (C) 2005-2012 Team XBMC
+ * http://www.xbmc.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with XBMC; see the file COPYING. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "utils/UrlOptions.h"
+
+#include "gtest/gtest.h"
+
+TEST(TestUrlOptions, Clear)
+{
+ const char *key = "foo";
+
+ CUrlOptions urlOptions;
+ urlOptions.AddOption(key, "bar");
+ EXPECT_TRUE(urlOptions.HasOption(key));
+
+ urlOptions.Clear();
+ EXPECT_FALSE(urlOptions.HasOption(key));
+}
+
+TEST(TestUrlOptions, AddOption)
+{
+ const char *keyChar = "char";
+ const char *keyString = "string";
+ const char *keyEmpty = "empty";
+ const char *keyInt = "int";
+ const char *keyFloat = "float";
+ const char *keyDouble = "double";
+ const char *keyBool = "bool";
+
+ const char *valueChar = "valueChar";
+ const std::string valueString = "valueString";
+ const char *valueEmpty = "";
+ int valueInt = 1;
+ float valueFloat = 1.0f;
+ double valueDouble = 1.0;
+ bool valueBool = true;
+
+ CVariant variantValue;
+
+ CUrlOptions urlOptions;
+ urlOptions.AddOption(keyChar, valueChar);
+ {
+ CVariant variantValue;
+ EXPECT_TRUE(urlOptions.GetOption(keyChar, variantValue));
+ EXPECT_TRUE(variantValue.isString());
+ EXPECT_STREQ(valueChar, variantValue.asString().c_str());
+ }
+
+ urlOptions.AddOption(keyString, valueString);
+ {
+ CVariant variantValue;
+ EXPECT_TRUE(urlOptions.GetOption(keyString, variantValue));
+ EXPECT_TRUE(variantValue.isString());
+ EXPECT_STREQ(valueString.c_str(), variantValue.asString().c_str());
+ }
+
+ urlOptions.AddOption(keyEmpty, valueEmpty);
+ {
+ CVariant variantValue;
+ EXPECT_TRUE(urlOptions.GetOption(keyEmpty, variantValue));
+ EXPECT_TRUE(variantValue.isString());
+ EXPECT_STREQ(valueEmpty, variantValue.asString().c_str());
+ }
+
+ urlOptions.AddOption(keyInt, valueInt);
+ {
+ CVariant variantValue;
+ EXPECT_TRUE(urlOptions.GetOption(keyInt, variantValue));
+ EXPECT_TRUE(variantValue.isInteger());
+ EXPECT_EQ(valueInt, (int)variantValue.asInteger());
+ }
+
+ urlOptions.AddOption(keyFloat, valueFloat);
+ {
+ CVariant variantValue;
+ EXPECT_TRUE(urlOptions.GetOption(keyFloat, variantValue));
+ EXPECT_TRUE(variantValue.isDouble());
+ EXPECT_EQ(valueFloat, variantValue.asFloat());
+ }
+
+ urlOptions.AddOption(keyDouble, valueDouble);
+ {
+ CVariant variantValue;
+ EXPECT_TRUE(urlOptions.GetOption(keyDouble, variantValue));
+ EXPECT_TRUE(variantValue.isDouble());
+ EXPECT_EQ(valueDouble, variantValue.asDouble());
+ }
+
+ urlOptions.AddOption(keyBool, valueBool);
+ {
+ CVariant variantValue;
+ EXPECT_TRUE(urlOptions.GetOption(keyBool, variantValue));
+ EXPECT_TRUE(variantValue.isBoolean());
+ EXPECT_EQ(valueBool, variantValue.asBoolean());
+ }
+}
+
+TEST(TestUrlOptions, AddOptions)
+{
+ std::string ref = "foo=bar&key=value";
+
+ CUrlOptions urlOptions(ref);
+ {
+ CVariant value;
+ EXPECT_TRUE(urlOptions.GetOption("foo", value));
+ EXPECT_TRUE(value.isString());
+ EXPECT_STREQ("bar", value.asString().c_str());
+ }
+ {
+ CVariant value;
+ EXPECT_TRUE(urlOptions.GetOption("key", value));
+ EXPECT_TRUE(value.isString());
+ EXPECT_STREQ("value", value.asString().c_str());
+ }
+
+ ref = "foo=bar&key";
+ urlOptions.Clear();
+ urlOptions.AddOptions(ref);
+ {
+ CVariant value;
+ EXPECT_TRUE(urlOptions.GetOption("foo", value));
+ EXPECT_TRUE(value.isString());
+ EXPECT_STREQ("bar", value.asString().c_str());
+ }
+ {
+ CVariant value;
+ EXPECT_TRUE(urlOptions.GetOption("key", value));
+ EXPECT_TRUE(value.isString());
+ EXPECT_TRUE(value.empty());
+ }
+}
+
+TEST(TestUrlOptions, RemoveOption)
+{
+ const char *key = "foo";
+
+ CUrlOptions urlOptions;
+ urlOptions.AddOption(key, "bar");
+ EXPECT_TRUE(urlOptions.HasOption(key));
+
+ urlOptions.RemoveOption(key);
+ EXPECT_FALSE(urlOptions.HasOption(key));
+}
+
+TEST(TestUrlOptions, HasOption)
+{
+ const char *key = "foo";
+
+ CUrlOptions urlOptions;
+ urlOptions.AddOption(key, "bar");
+ EXPECT_TRUE(urlOptions.HasOption(key));
+ EXPECT_FALSE(urlOptions.HasOption("bar"));
+}
+
+TEST(TestUrlOptions, GetOptions)
+{
+ const char *key1 = "foo";
+ const char *key2 = "key";
+ const char *value1 = "bar";
+ const char *value2 = "value";
+
+ CUrlOptions urlOptions;
+ urlOptions.AddOption(key1, value1);
+ urlOptions.AddOption(key2, value2);
+ const CUrlOptions::UrlOptions &options = urlOptions.GetOptions();
+ EXPECT_FALSE(options.empty());
+ EXPECT_EQ(2, options.size());
+
+ CUrlOptions::UrlOptions::const_iterator it1 = options.find(key1);
+ EXPECT_TRUE(it1 != options.end());
+ CUrlOptions::UrlOptions::const_iterator it2 = options.find(key2);
+ EXPECT_TRUE(it2 != options.end());
+ EXPECT_FALSE(options.find("wrong") != options.end());
+ EXPECT_TRUE(it1->second.isString());
+ EXPECT_TRUE(it2->second.isString());
+ EXPECT_STREQ(value1, it1->second.asString().c_str());
+ EXPECT_STREQ(value2, it2->second.asString().c_str());
+}
+
+TEST(TestUrlOptions, GetOptionsString)
+{
+ const char *ref = "foo=bar&key";
+
+ CUrlOptions urlOptions(ref);
+ std::string value = urlOptions.GetOptionsString();
+ EXPECT_STREQ(ref, value.c_str());
+}
View
2  xbmc/video/VideoDatabase.cpp
@@ -9342,7 +9342,7 @@ bool CVideoDatabase::GetFilter(CDbUrl &videoUrl, Filter &filter, SortDescription
}
// remove the filter if it doesn't match the item type
else
- videoUrl.AddOption("filter", "");
+ videoUrl.RemoveOption("filter");
}
return true;

0 comments on commit a44e59f

Please sign in to comment.
Something went wrong with that request. Please try again.