-
Notifications
You must be signed in to change notification settings - Fork 273
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add utility for string and redis #434
Merged
lguohan
merged 18 commits into
sonic-net:master
from
Pterosaur:utility_for_string_and_redis
Dec 29, 2020
Merged
Changes from all commits
Commits
Show all changes
18 commits
Select commit
Hold shift + click to select a range
8f4f88d
Add utility for string and redis
Pterosaur cd10f06
Polish code
Pterosaur d1ed78e
Renmae get_value to fvGetValue
Pterosaur a55d746
Fix operator>>(istream, bool)
Pterosaur 014c794
Polish split to call tokenize
Pterosaur c96c624
Polish hex binary function by calling boost hex/unhex
Pterosaur 6dc76df
Polish name and optimize split performance
Pterosaur 83e95e8
strictly limit the buffer length with hex string length
Pterosaur ef4ea2c
Rename fvtGetValue
Pterosaur 88d8356
optimize fvtGetValue
Pterosaur 3d79e04
Fix code
Pterosaur c017707
Merge branch 'master' into utility_for_string_and_redis
Pterosaur 7a0a672
Polish code
Pterosaur 2adf276
Remove LOG_ENTER in short functions
Pterosaur 280594d
Add alpha boolean
Pterosaur a7f5acd
polish code
Pterosaur 45af9c2
optimize stream operator
Pterosaur c452b86
polish code
Pterosaur File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
#pragma once | ||
|
||
#include <iostream> | ||
#include <ios> | ||
|
||
namespace swss | ||
{ | ||
class Boolean | ||
{ | ||
public: | ||
Boolean() = default; | ||
Boolean(bool boolean) : m_boolean(boolean) | ||
{ | ||
} | ||
operator bool() const | ||
{ | ||
return m_boolean; | ||
} | ||
operator bool&() | ||
{ | ||
return m_boolean; | ||
} | ||
protected: | ||
bool m_boolean; | ||
}; | ||
|
||
class AlphaBoolean : public Boolean | ||
{ | ||
public: | ||
AlphaBoolean() = default; | ||
AlphaBoolean(bool boolean) : Boolean(boolean) | ||
{ | ||
} | ||
}; | ||
|
||
static inline std::ostream &operator<<(std::ostream &out, const AlphaBoolean &b) | ||
{ | ||
return out << std::boolalpha << (bool)(b); | ||
} | ||
|
||
static inline std::istream &operator>>(std::istream &in, AlphaBoolean &b) | ||
{ | ||
return in >> std::boolalpha >> (bool &)(b); | ||
} | ||
|
||
static inline std::ostream &operator<<(std::ostream &out, const Boolean &b) | ||
{ | ||
return out << (bool)(b); | ||
} | ||
|
||
static inline std::istream &operator>>(std::istream &in, Boolean &b) | ||
{ | ||
return in >> (bool &)(b); | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
#include "redisutility.h" | ||
#include "stringutility.h" | ||
|
||
#include <boost/algorithm/string.hpp> | ||
|
||
|
||
boost::optional<std::string> swss::fvsGetValue( | ||
const std::vector<FieldValueTuple> &fvt, | ||
const std::string &field, | ||
bool case_insensitive) | ||
{ | ||
boost::optional<std::string> ret; | ||
|
||
for (auto itr = fvt.begin(); itr != fvt.end(); itr++) | ||
{ | ||
bool is_equal = false; | ||
if (case_insensitive) | ||
{ | ||
is_equal = boost::iequals(fvField(*itr), field); | ||
} | ||
else | ||
{ | ||
is_equal = (fvField(*itr) == field); | ||
} | ||
if (is_equal) | ||
{ | ||
ret = fvValue(*itr); | ||
break; | ||
} | ||
} | ||
|
||
return ret; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
#pragma once | ||
|
||
#include "rediscommand.h" | ||
|
||
#include <boost/optional.hpp> | ||
|
||
#include <vector> | ||
#include <algorithm> | ||
|
||
namespace swss | ||
{ | ||
boost::optional<std::string> fvsGetValue( | ||
const std::vector<FieldValueTuple> &fvt, | ||
const std::string &field, | ||
bool case_insensitive = false); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,136 @@ | ||
#pragma once | ||
|
||
#include "logger.h" | ||
#include "tokenize.h" | ||
#include "schema.h" | ||
|
||
#include <boost/lexical_cast.hpp> | ||
#include <boost/algorithm/hex.hpp> | ||
|
||
#include <inttypes.h> | ||
#include <algorithm> | ||
#include <iterator> | ||
#include <vector> | ||
#include <string> | ||
#include <sstream> | ||
#include <cctype> | ||
|
||
namespace swss { | ||
|
||
template<typename T> | ||
static inline void lexical_convert(const std::string &str, T &t) | ||
{ | ||
t = boost::lexical_cast<T>(str); | ||
} | ||
|
||
namespace lexical_convert_detail | ||
{ | ||
|
||
template <typename T, typename... Args> | ||
void lexical_convert( | ||
std::vector<std::string>::const_iterator begin, | ||
std::vector<std::string>::const_iterator end, | ||
T &t) | ||
{ | ||
if (begin == end) | ||
{ | ||
SWSS_LOG_THROW("Insufficient corpus"); | ||
} | ||
auto cur_itr = begin++; | ||
if (begin != end) | ||
{ | ||
SWSS_LOG_THROW("Too much corpus"); | ||
} | ||
swss::lexical_convert(*cur_itr, t); | ||
} | ||
|
||
template <typename T, typename... Args> | ||
void lexical_convert( | ||
std::vector<std::string>::const_iterator begin, | ||
std::vector<std::string>::const_iterator end, | ||
T &t, | ||
Args &... args) | ||
{ | ||
if (begin == end) | ||
{ | ||
SWSS_LOG_THROW("Insufficient corpus"); | ||
} | ||
swss::lexical_convert(*(begin++), t); | ||
return lexical_convert(begin, end, args...); | ||
} | ||
|
||
} | ||
|
||
template <typename T, typename... Args> | ||
void lexical_convert(const std::vector<std::string> &strs, T &t, Args &... args) | ||
{ | ||
lexical_convert_detail::lexical_convert(strs.begin(), strs.end(), t, args...); | ||
} | ||
|
||
namespace join_detail | ||
{ | ||
|
||
template <typename T> | ||
void join(std::ostringstream &ostream, char, const T &t) | ||
{ | ||
ostream << t; | ||
} | ||
|
||
template <typename T, typename... Args> | ||
void join(std::ostringstream &ostream, char delimiter, const T &t, const Args &... args) | ||
{ | ||
ostream << t << delimiter; | ||
join(ostream, delimiter, args...); | ||
} | ||
|
||
} | ||
|
||
template <typename T, typename... Args> | ||
static inline std::string join(char delimiter, const T &t, const Args &... args) | ||
{ | ||
std::ostringstream ostream; | ||
join_detail::join(ostream, delimiter, t, args...); | ||
return ostream.str(); | ||
} | ||
|
||
static inline bool hex_to_binary(const std::string &hex_str, std::uint8_t *buffer, size_t buffer_length) | ||
{ | ||
if (hex_str.length() != (buffer_length * 2)) | ||
{ | ||
SWSS_LOG_DEBUG("Buffer length isn't sufficient"); | ||
return false; | ||
} | ||
|
||
try | ||
{ | ||
boost::algorithm::unhex(hex_str, buffer); | ||
} | ||
catch(const boost::algorithm::non_hex_input &e) | ||
{ | ||
SWSS_LOG_DEBUG("Invalid hex string %s", hex_str.c_str()); | ||
return false; | ||
} | ||
|
||
return true; | ||
} | ||
|
||
template<typename T> | ||
static inline void hex_to_binary(const std::string &s, T &value) | ||
{ | ||
return hex_to_binary(s, &value, sizeof(T)); | ||
} | ||
|
||
static inline std::string binary_to_hex(const void *buffer, size_t length) | ||
{ | ||
std::string s; | ||
auto buf = static_cast<const std::uint8_t *>(buffer); | ||
|
||
boost::algorithm::hex( | ||
buf, | ||
buf + length, | ||
std::back_inserter<std::string>(s)); | ||
|
||
return s; | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
#include "common/boolean.h" | ||
|
||
#include "gtest/gtest.h" | ||
|
||
#include <sstream> | ||
|
||
TEST(BOOLEAN, boolean) | ||
{ | ||
swss::Boolean b; | ||
|
||
b = true; | ||
std::ostringstream ost; | ||
ost << b; | ||
EXPECT_EQ(ost.str(), "1"); | ||
|
||
b = false; | ||
std::ostringstream osf; | ||
osf << b; | ||
EXPECT_EQ(osf.str(), "0"); | ||
|
||
b = false; | ||
std::istringstream ist("1"); | ||
ist >> b; | ||
EXPECT_TRUE(b); | ||
EXPECT_FALSE(ist.fail()); | ||
|
||
b = true; | ||
std::istringstream isf("0"); | ||
isf >> b; | ||
EXPECT_FALSE(b); | ||
EXPECT_FALSE(isf.fail()); | ||
} | ||
|
||
TEST(BOOLEAN, alpha_boolean) | ||
{ | ||
swss::AlphaBoolean bt(true); | ||
swss::AlphaBoolean bf(false); | ||
|
||
EXPECT_TRUE(bt); | ||
EXPECT_FALSE(bf); | ||
|
||
std::ostringstream ost; | ||
ost << bt; | ||
EXPECT_EQ(ost.str(), "true"); | ||
|
||
std::ostringstream osf; | ||
osf << bf; | ||
EXPECT_EQ(osf.str(), "false"); | ||
|
||
std::istringstream is; | ||
|
||
bt = false; | ||
is.str("true"); | ||
is >> bt; | ||
EXPECT_TRUE(bt); | ||
EXPECT_FALSE(is.fail()); | ||
is.clear(); | ||
|
||
bt = false; | ||
is.str("true123"); | ||
int i; | ||
is >> bt >> i; | ||
EXPECT_TRUE(bt); | ||
EXPECT_EQ(i, 123); | ||
EXPECT_FALSE(is.fail()); | ||
is.clear(); | ||
|
||
bf = true; | ||
is.str("false"); | ||
is >> bf; | ||
EXPECT_FALSE(bf); | ||
EXPECT_FALSE(is.fail()); | ||
is.clear(); | ||
|
||
bf = true; | ||
is.str("abdef"); | ||
EXPECT_FALSE(is >> bt); | ||
EXPECT_TRUE(is.fail()); | ||
is.clear(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
#include "common/redisutility.h" | ||
#include "common/stringutility.h" | ||
#include "common/boolean.h" | ||
|
||
#include "gtest/gtest.h" | ||
|
||
TEST(REDISUTILITY, fvsGetValue) | ||
{ | ||
std::vector<swss::FieldValueTuple> fvt; | ||
fvt.push_back(std::make_pair("int", "123")); | ||
fvt.push_back(std::make_pair("bool", "true")); | ||
fvt.push_back(std::make_pair("string", "name")); | ||
|
||
auto si = swss::fvsGetValue(fvt, "int"); | ||
EXPECT_TRUE(si); | ||
auto sb = swss::fvsGetValue(fvt, "bool"); | ||
EXPECT_TRUE(sb); | ||
auto ss = swss::fvsGetValue(fvt, "string"); | ||
EXPECT_TRUE(ss); | ||
|
||
int i; | ||
swss::AlphaBoolean b; | ||
std::string s; | ||
ASSERT_NO_THROW(swss::lexical_convert({*si, *sb, *ss}, i, b, s)); | ||
EXPECT_EQ(i, 123); | ||
EXPECT_EQ(b, true); | ||
EXPECT_EQ(s, "name"); | ||
|
||
EXPECT_FALSE(swss::fvsGetValue(fvt, "Int")); | ||
EXPECT_TRUE(swss::fvsGetValue(fvt, "Int", true)); | ||
EXPECT_FALSE(swss::fvsGetValue(fvt, "double")); | ||
} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You need another cast operator