more test utils

This commit is contained in:
Michael Davidsaver
2019-11-26 17:53:41 -08:00
parent 4c60d72f9c
commit dd4da5d6d5
5 changed files with 55 additions and 5 deletions
+10
View File
@@ -337,6 +337,7 @@ bool EvOutBuf::refill(size_t more)
bool EvInBuf::refill(size_t more)
{
if(err) return false;
size_t len = size(); // unconsumed before request
if(base && evbuffer_drain(backing, pos-base))
throw std::bad_alloc();
@@ -344,8 +345,13 @@ bool EvInBuf::refill(size_t more)
limit = base = pos = nullptr;
if(more) {
// ensure new segment contains at least the requested size (one element)
// (we hope this is mostly a no-op)
(void)evbuffer_pullup(backing, len+more);
evbuffer_iovec vec;
// peek at the next segment
auto n = evbuffer_peek(backing, -1, nullptr, &vec, 1);
if(n<=0) { // current (2.1) impl never returns negative
return false;
@@ -353,6 +359,10 @@ bool EvInBuf::refill(size_t more)
base = pos = (uint8_t*)vec.iov_base;
limit = base+vec.iov_len;
if(size() < len+more) {
return false; // pullup didn't work.
}
}
return true;
}
+18 -1
View File
@@ -59,6 +59,7 @@ public:
pos = limit;
i -= size();
} while(static_cast<Subclass*>(this)->refill(i));
fault();
}
EPICS_ALWAYS_INLINE bool empty() const { return limit==pos; }
@@ -305,7 +306,7 @@ inline void _to_wire(Buf& buf, const uint8_t *mem, bool reverse)
* @param buf output buffer. buf[0] through buf[sizeof(T)-1] must be valid.
* @param val input variable
*/
template<typename T, typename Buf, typename std::enable_if<std::is_scalar<T>::value, int>::type =0>
template<typename T, typename Buf, typename std::enable_if<sizeof(T)>=2 && std::is_scalar<T>{} && !std::is_pointer<T>{}, int>::type =0>
inline void to_wire(Buf& buf, const T& val)
{
union {
@@ -316,6 +317,16 @@ inline void to_wire(Buf& buf, const T& val)
_to_wire<sizeof(T)>(buf, pun.b, buf.be ^ (EPICS_BYTE_ORDER==EPICS_ENDIAN_BIG));
}
template<typename T, typename Buf, typename std::enable_if<sizeof(T)==1 && std::is_scalar<T>{}, int>::type =0>
inline void to_wire(Buf& buf, const T& val)
{
if(!buf.ensure(1)) {
buf.fault();
} else {
buf.push(val);
}
}
template<typename Buf>
void to_wire(Buf& buf, const Size& size)
{
@@ -349,6 +360,12 @@ void to_wire(Buf& buf, const char *s)
}
template<typename Buf>
inline void to_wire(Buf& buf, const std::string& s)
{
to_wire(buf, s.c_str());
}
template<typename Buf>
void to_wire(Buf& buf, std::initializer_list<uint8_t> bytes)
{
+10 -1
View File
@@ -13,7 +13,9 @@
*/
#include <sstream>
#include <vector>
#include <functional>
#include <type_traits>
#include <pvxs/version.h>
#include <pvxs/util.h>
@@ -57,7 +59,7 @@ public:
namespace detail {
// control how testEq() and testNotEq() print things
template<typename T>
template<typename T, typename Enable=void>
struct test_print {
template<class C>
static inline void op(C& strm, const T& v) {
@@ -78,6 +80,13 @@ struct test_print<const char*> {
strm<<'"'<<escape(v)<<'"';
}
};
template<typename E>
struct test_print<std::vector<E>, typename std::enable_if<sizeof(E)==1>::type> {
template<class C>
static inline void op(C& strm, const std::vector<E>& v) {
strm<<'"'<<escape((const char*)v.data(), v.size())<<'"';
}
};
template<typename LHS, typename RHS>
testCase testEq(const char *sLHS, const LHS& lhs, const char *sRHS, const RHS& rhs)
+11 -2
View File
@@ -26,9 +26,11 @@ namespace detail {
class Escaper
{
const char* val;
size_t count;
friend std::ostream& operator<<(std::ostream& strm, const Escaper& esc);
public:
constexpr explicit Escaper(const char* v) :val(v) {}
PVXS_API explicit Escaper(const char* v);
constexpr explicit Escaper(const char* v, size_t l) :val(v),count(l) {}
};
PVXS_API
@@ -42,7 +44,7 @@ std::ostream& operator<<(std::ostream& strm, const Escaper& esc);
//! std::cout<<pvxs::escape(blah);
//! @endcode
inline detail::Escaper escape(const std::string& s) {
return detail::Escaper(s.c_str());
return detail::Escaper(s.c_str(), s.size());
}
//! Print string to output string with non-printable charactors escaped.
//! @code
@@ -51,6 +53,13 @@ inline detail::Escaper escape(const std::string& s) {
inline detail::Escaper escape(const char* s) {
return detail::Escaper(s);
}
//! Print string to output string with non-printable charactors escaped.
//! @code
//! std::cout<<pvxs::escape("this \"is a test\"", 6); // prints 'this \"'
//! @endcode
inline detail::Escaper escape(const char* s,size_t n) {
return detail::Escaper(s,n);
}
//! representation of a network address
struct PVXS_API SockAddr {
+6 -1
View File
@@ -39,13 +39,18 @@ void cleanup_for_valgrind()
namespace detail {
Escaper::Escaper(const char* v)
:val(v)
,count(v ? strlen(v) : 0)
{}
std::ostream& operator<<(std::ostream& strm, const Escaper& esc)
{
const char *s = esc.val;
if(!s) {
strm<<"<NULL>";
} else {
for(; *s; s++) {
for(size_t n=0; n<esc.count; n++,s++) {
char c = *s, next;
switch(c) {
case '\a': next = 'a'; break;