merge changes from 1.10.2

This commit is contained in:
Günter Obiltschnig
2021-04-11 16:31:35 +02:00
parent 5187f9d0d2
commit cb6e801537
8 changed files with 76 additions and 36 deletions

View File

@@ -176,6 +176,23 @@ public:
return result; return result;
} }
template <typename Fn>
void forEach(Fn&& fn) const
/// Iterates over all key-value pairs in the
/// cache, using a functor or lambda expression.
///
/// The given functor must take the key and value
/// as parameters. Note that the value is passed
/// as the actual value (or reference),
/// not a Poco::SharedPtr.
{
typename TMutex::ScopedLock lock(_mutex);
for (const auto& p: _data)
{
fn(p.first, *p.second);
}
}
protected: protected:
mutable FIFOEvent<ValidArgs<TKey>> IsValid; mutable FIFOEvent<ValidArgs<TKey>> IsValid;
mutable FIFOEvent<KeySet> Replace; mutable FIFOEvent<KeySet> Replace;

View File

@@ -189,7 +189,7 @@ public:
val.append("{ "); val.append("{ ");
Var key(_val.first()); Var key(_val.first());
Impl::appendJSONKey(val, key); Impl::appendJSONKey(val, key);
val.append(" : "); val.append(": ");
Impl::appendJSONValue(val, _val.second()); Impl::appendJSONValue(val, _val.second());
val.append(" }"); val.append(" }");
} }
@@ -338,7 +338,7 @@ public:
val.append("{ "); val.append("{ ");
Var key(_val.first()); Var key(_val.first());
Impl::appendJSONKey(val, key); Impl::appendJSONKey(val, key);
val.append(" : "); val.append(": ");
Impl::appendJSONValue(val, _val.second()); Impl::appendJSONValue(val, _val.second());
val.append(" }"); val.append(" }");
} }

View File

@@ -339,7 +339,7 @@ public:
{ {
Var key(it->first); Var key(it->first);
Impl::appendJSONKey(val, key); Impl::appendJSONKey(val, key);
val.append(" : "); val.append(": ");
Impl::appendJSONValue(val, it->second); Impl::appendJSONValue(val, it->second);
++it; ++it;
} }
@@ -348,7 +348,7 @@ public:
val.append(", "); val.append(", ");
Var key(it->first); Var key(it->first);
Impl::appendJSONKey(val, key); Impl::appendJSONKey(val, key);
val.append(" : "); val.append(": ");
Impl::appendJSONValue(val, it->second); Impl::appendJSONValue(val, it->second);
} }
val.append(" }"); val.append(" }");
@@ -525,7 +525,7 @@ public:
{ {
Var key(it->first); Var key(it->first);
Impl::appendJSONKey(val, key); Impl::appendJSONKey(val, key);
val.append(" : "); val.append(": ");
Impl::appendJSONValue(val, it->second); Impl::appendJSONValue(val, it->second);
++it; ++it;
} }
@@ -534,7 +534,7 @@ public:
val.append(", "); val.append(", ");
Var key(it->first); Var key(it->first);
Impl::appendJSONKey(val, key); Impl::appendJSONKey(val, key);
val.append(" : "); val.append(": ");
Impl::appendJSONValue(val, it->second); Impl::appendJSONValue(val, it->second);
} }
val.append(" }"); val.append(" }");
@@ -711,7 +711,7 @@ public:
{ {
Var key(it->first); Var key(it->first);
Impl::appendJSONKey(val, key); Impl::appendJSONKey(val, key);
val.append(" : "); val.append(": ");
Impl::appendJSONValue(val, it->second); Impl::appendJSONValue(val, it->second);
++it; ++it;
} }
@@ -720,7 +720,7 @@ public:
val.append(", "); val.append(", ");
Var key(it->first); Var key(it->first);
Impl::appendJSONKey(val, key); Impl::appendJSONKey(val, key);
val.append(" : "); val.append(": ");
Impl::appendJSONValue(val, it->second); Impl::appendJSONValue(val, it->second);
} }
val.append(" }"); val.append(" }");
@@ -897,7 +897,7 @@ public:
{ {
Var key(it->first); Var key(it->first);
Impl::appendJSONKey(val, key); Impl::appendJSONKey(val, key);
val.append(" : "); val.append(": ");
Impl::appendJSONValue(val, it->second); Impl::appendJSONValue(val, it->second);
++it; ++it;
} }
@@ -906,7 +906,7 @@ public:
val.append(", "); val.append(", ");
Var key(it->first); Var key(it->first);
Impl::appendJSONKey(val, key); Impl::appendJSONKey(val, key);
val.append(" : "); val.append(": ");
Impl::appendJSONValue(val, it->second); Impl::appendJSONValue(val, it->second);
} }
val.append(" }"); val.append(" }");

View File

@@ -49,8 +49,7 @@ void writeString(const std::string &value, T& obj, typename WriteFunc<T, S>::Typ
{ {
for(std::string::const_iterator it = value.begin(), end = value.end(); it != end; ++it) for(std::string::const_iterator it = value.begin(), end = value.end(); it != end; ++it)
{ {
// Forward slash isn't strictly required by JSON spec, but some parsers expect it if((*it >= 0 && *it <= 31) || (*it == '"') || (*it == '\\'))
if((*it >= 0 && *it <= 31) || (*it == '"') || (*it == '\\') || (*it == '/'))
{ {
std::string str = Poco::UTF8::escape(it, it + 1, true); std::string str = Poco::UTF8::escape(it, it + 1, true);
(obj.*write)(str.c_str(), str.size()); (obj.*write)(str.c_str(), str.size());

View File

@@ -221,6 +221,29 @@ void LRUCacheTest::testUpdate()
} }
void LRUCacheTest::testForEach()
{
LRUCache<int, int> aCache(3);
std::map<int, int> values;
aCache.add(1, 100);
aCache.add(2, 200);
aCache.add(3, 300);
aCache.forEach(
[&values](int key, int value)
{
values[key] = value;
}
);
assertEquals (values.size(), 3);
assertEquals (values[1], 100);
assertEquals (values[2], 200);
assertEquals (values[3], 300);
}
void LRUCacheTest::onUpdate(const void* pSender, const Poco::KeyValueArgs<int, int>& args) void LRUCacheTest::onUpdate(const void* pSender, const Poco::KeyValueArgs<int, int>& args)
{ {
++updateCnt; ++updateCnt;
@@ -260,6 +283,7 @@ CppUnit::Test* LRUCacheTest::suite()
CppUnit_addTest(pSuite, LRUCacheTest, testCacheSizeN); CppUnit_addTest(pSuite, LRUCacheTest, testCacheSizeN);
CppUnit_addTest(pSuite, LRUCacheTest, testDuplicateAdd); CppUnit_addTest(pSuite, LRUCacheTest, testDuplicateAdd);
CppUnit_addTest(pSuite, LRUCacheTest, testUpdate); CppUnit_addTest(pSuite, LRUCacheTest, testUpdate);
CppUnit_addTest(pSuite, LRUCacheTest, testForEach);
return pSuite; return pSuite;
} }

View File

@@ -31,6 +31,7 @@ public:
void testCacheSizeN(); void testCacheSizeN();
void testDuplicateAdd(); void testDuplicateAdd();
void testUpdate(); void testUpdate();
void testForEach();
void setUp(); void setUp();
void tearDown(); void tearDown();

View File

@@ -1378,7 +1378,6 @@ void StringTest::testJSONString()
{ {
assertTrue (toJSON("\\", false) == "\\\\"); assertTrue (toJSON("\\", false) == "\\\\");
assertTrue (toJSON("\"", false) == "\\\""); assertTrue (toJSON("\"", false) == "\\\"");
assertTrue (toJSON("/", false) == "\\/");
assertTrue (toJSON("\a", false) == "\\u0007"); assertTrue (toJSON("\a", false) == "\\u0007");
assertTrue (toJSON("\b", false) == "\\b"); assertTrue (toJSON("\b", false) == "\\b");
assertTrue (toJSON("\f", false) == "\\f"); assertTrue (toJSON("\f", false) == "\\f");
@@ -1395,7 +1394,7 @@ void StringTest::testJSONString()
std::string str = "\"foo\\\\\""; std::string str = "\"foo\\\\\"";
assertTrue (toJSON("foo\\") == str); assertTrue (toJSON("foo\\") == str);
assertTrue (toJSON("bar/") == "\"bar\\/\""); assertTrue (toJSON("bar/") == "\"bar/\"");
assertTrue (toJSON("baz") == "\"baz\""); assertTrue (toJSON("baz") == "\"baz\"");
assertTrue (toJSON("q\"uote\"d") == "\"q\\\"uote\\\"d\""); assertTrue (toJSON("q\"uote\"d") == "\"q\\\"uote\\\"d\"");
assertTrue (toJSON("bs\b") == "\"bs\\b\""); assertTrue (toJSON("bs\b") == "\"bs\\b\"");
@@ -1412,7 +1411,7 @@ void StringTest::testJSONString()
ostr.str(""); ostr.str("");
toJSON("foo\\", ostr); toJSON("foo\\", ostr);
assertTrue (toJSON("bar/") == "\"bar\\/\""); assertTrue (toJSON("bar/") == "\"bar/\"");
ostr.str(""); ostr.str("");
toJSON("baz", ostr); toJSON("baz", ostr);
assertTrue (ostr.str() == "\"baz\""); assertTrue (ostr.str() == "\"baz\"");

View File

@@ -2438,14 +2438,14 @@ void VarTest::testDynamicPair()
catch (InvalidAccessException&) { } catch (InvalidAccessException&) { }
Var va(aPair); Var va(aPair);
assertTrue ("{ \"0\" : null }" == va.convert<std::string>()); assertTrue ("{ \"0\": null }" == va.convert<std::string>());
assertTrue (aPair.toString() == va.convert<std::string>()); assertTrue (aPair.toString() == va.convert<std::string>());
aPair = Pair<int>(4, "123"); aPair = Pair<int>(4, "123");
assertTrue ("123" == aPair.second()); assertTrue ("123" == aPair.second());
va = aPair; va = aPair;
assertTrue ("{ \"4\" : \"123\" }" == va.convert<std::string>()); assertTrue ("{ \"4\": \"123\" }" == va.convert<std::string>());
assertTrue (aPair.toString() == va.convert<std::string>()); assertTrue (aPair.toString() == va.convert<std::string>());
int i = 1; int i = 1;
@@ -2464,11 +2464,11 @@ void VarTest::testDynamicPair()
assertTrue ("2" == pPair.second()); assertTrue ("2" == pPair.second());
Var vp(pPair); Var vp(pPair);
assertTrue ("{ \"1\" : \"2\" }" == vp.convert<std::string>()); assertTrue ("{ \"1\": \"2\" }" == vp.convert<std::string>());
assertTrue (pPair.toString() == vp.convert<std::string>()); assertTrue (pPair.toString() == vp.convert<std::string>());
Var vs(sPair); Var vs(sPair);
assertTrue ("{ \"2\" : 1 }" == vs.convert<std::string>()); assertTrue ("{ \"2\": 1 }" == vs.convert<std::string>());
assertTrue (sPair.toString() == vs.convert<std::string>()); assertTrue (sPair.toString() == vs.convert<std::string>());
} }
@@ -2509,7 +2509,7 @@ void VarTest::testStructToString()
aStruct["Age"] = 1; aStruct["Age"] = 1;
Var a1(aStruct); Var a1(aStruct);
std::string res = a1.convert<std::string>(); std::string res = a1.convert<std::string>();
std::string expected = "{ \"Age\" : 1, \"First Name\" : \"Junior\", \"Last Name\" : \"POCO\" }"; std::string expected = "{ \"Age\": 1, \"First Name\": \"Junior\", \"Last Name\": \"POCO\" }";
assertTrue (res == expected); assertTrue (res == expected);
assertTrue (aStruct.toString() == res); assertTrue (aStruct.toString() == res);
} }
@@ -2523,7 +2523,7 @@ void VarTest::testOrderedStructToString()
aStruct["Age"] = 1; aStruct["Age"] = 1;
Var a1(aStruct); Var a1(aStruct);
std::string res = a1.convert<std::string>(); std::string res = a1.convert<std::string>();
std::string expected = "{ \"First Name\" : \"Junior\", \"Last Name\" : \"POCO\", \"Age\" : 1 }"; std::string expected = "{ \"First Name\": \"Junior\", \"Last Name\": \"POCO\", \"Age\": 1 }";
assertTrue(res == expected); assertTrue(res == expected);
assertTrue(aStruct.toString() == res); assertTrue(aStruct.toString() == res);
} }
@@ -2535,7 +2535,7 @@ void VarTest::testStructToStringEscape()
aStruct["Value"] = "Value with \" and \n"; aStruct["Value"] = "Value with \" and \n";
Var a1(aStruct); Var a1(aStruct);
std::string res = a1.convert<std::string>(); std::string res = a1.convert<std::string>();
std::string expected = "{ \"Value\" : \"Value with \\\" and \\n\" }"; std::string expected = "{ \"Value\": \"Value with \\\" and \\n\" }";
assertTrue (res == expected); assertTrue (res == expected);
assertTrue (aStruct.toString() == res); assertTrue (aStruct.toString() == res);
} }
@@ -2560,14 +2560,14 @@ void VarTest::testArrayOfStructsToString()
Var a1(s16); Var a1(s16);
std::string res = a1.convert<std::string>(); std::string res = a1.convert<std::string>();
std::string expected = "[ " std::string expected = "[ "
"{ \"Age\" : 1, \"First Name\" : \"Junior\", \"Last Name\" : \"POCO\" }, " "{ \"Age\": 1, \"First Name\": \"Junior\", \"Last Name\": \"POCO\" }, "
"{ \"Age\" : 100, \"First Name\" : \"Senior\", \"Last Name\" : \"POCO\" }, " "{ \"Age\": 100, \"First Name\": \"Senior\", \"Last Name\": \"POCO\" }, "
"[ " "[ "
"{ \"Age\" : 1, \"First Name\" : \"Junior\", \"Last Name\" : \"POCO\" }, " "{ \"Age\": 1, \"First Name\": \"Junior\", \"Last Name\": \"POCO\" }, "
"{ \"Age\" : 100, \"First Name\" : \"Senior\", \"Last Name\" : \"POCO\" }, " "{ \"Age\": 100, \"First Name\": \"Senior\", \"Last Name\": \"POCO\" }, "
"[ " "[ "
"{ \"Age\" : 1, \"First Name\" : \"Junior\", \"Last Name\" : \"POCO\" }, " "{ \"Age\": 1, \"First Name\": \"Junior\", \"Last Name\": \"POCO\" }, "
"{ \"Age\" : 100, \"First Name\" : \"Senior\", \"Last Name\" : \"POCO\" } " "{ \"Age\": 100, \"First Name\": \"Senior\", \"Last Name\": \"POCO\" } "
"] ] ]"; "] ] ]";
assertTrue (res == expected); assertTrue (res == expected);
@@ -2594,8 +2594,8 @@ void VarTest::testStructWithArraysToString()
aStruct["Address"] = addr; aStruct["Address"] = addr;
Var a2(aStruct); Var a2(aStruct);
std::string res = a2.convert<std::string>(); std::string res = a2.convert<std::string>();
std::string expected = "{ \"Address\" : { \"Country\" : \"Carinthia\", \"Number\" : 4, \"Street\" : \"Unknown\" }, " std::string expected = "{ \"Address\": { \"Country\": \"Carinthia\", \"Number\": 4, \"Street\": \"Unknown\" }, "
"\"Age\" : 1, \"First Name\" : \"Junior\", \"Last Name\" : [ \"string\", 23 ] }"; "\"Age\": 1, \"First Name\": \"Junior\", \"Last Name\": [ \"string\", 23 ] }";
assertTrue (res == expected); assertTrue (res == expected);
assertTrue (aStruct.toString() == res); assertTrue (aStruct.toString() == res);
@@ -2615,17 +2615,17 @@ void VarTest::testJSONDeserializeString()
char cc = b2.convert<char>(); char cc = b2.convert<char>();
assertTrue (cc == 'c'); assertTrue (cc == 'c');
tst = "{ \"a\" : \"1\", \"b\" : \"2\" \n}"; tst = "{ \"a\": \"1\", \"b\": \"2\" \n}";
a = Var::parse(tst); a = Var::parse(tst);
assertTrue (a.toString() == "{ \"a\" : \"1\", \"b\" : \"2\" }"); assertTrue (a.toString() == "{ \"a\": \"1\", \"b\": \"2\" }");
tst = "{ \"a\" : \"1\", \"b\" : \"2\"\n}"; tst = "{ \"a\": \"1\", \"b\": \"2\"\n}";
a = Var::parse(tst); a = Var::parse(tst);
assertTrue (a.toString() == "{ \"a\" : \"1\", \"b\" : \"2\" }"); assertTrue (a.toString() == "{ \"a\": \"1\", \"b\": \"2\" }");
tst = "{ \"message\" : \"escape\\b\\f\\n\\r\\t\", \"path\" : \"\\/dev\\/null\" }"; tst = "{ \"message\": \"escape\\b\\f\\n\\r\\t\", \"path\": \"\\/dev\\/null\" }";
a = Var::parse(tst); a = Var::parse(tst);
assertTrue(a.toString() == "{ \"message\" : \"escape\\b\\f\\n\\r\\t\", \"path\" : \"\\/dev\\/null\" }"); assertTrue(a.toString() == "{ \"message\": \"escape\\b\\f\\n\\r\\t\", \"path\": \"/dev/null\" }");
} }