Merge pull request #616 from michael-loki/reader_removal

Replace dict_reader/list_reader with version which doesn't involve indirection
pull/619/head
Jeff 5 years ago committed by GitHub
commit 3bd1aa50ff
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -1,5 +1,6 @@
#include <dht/context.hpp> #include <dht/context.hpp>
#include <util/bencode.hpp>
#include <dht/messages/findintro.hpp> #include <dht/messages/findintro.hpp>
#include <dht/messages/findrouter.hpp> #include <dht/messages/findrouter.hpp>
#include <dht/messages/gotintro.hpp> #include <dht/messages/gotintro.hpp>
@ -17,57 +18,57 @@ namespace llarp
bool firstKey = true; bool firstKey = true;
bool relayed = false; bool relayed = false;
MessageDecoder(const Key_t &from) : From(from) MessageDecoder(const Key_t &from, bool wasRelayed)
: From(from), relayed(wasRelayed)
{ {
} }
static bool bool
on_key(dict_reader *r, llarp_buffer_t *key) operator()(llarp_buffer_t *buffer, llarp_buffer_t *key)
{ {
llarp_buffer_t strbuf; llarp_buffer_t strbuf;
MessageDecoder *dec = static_cast< MessageDecoder * >(r->user);
// check for empty dict // check for empty dict
if(!key) if(!key)
return !dec->firstKey; return !firstKey;
// first key // first key
if(dec->firstKey) if(firstKey)
{ {
if(!(*key == "A")) if(!(*key == "A"))
return false; return false;
if(!bencode_read_string(r->buffer, &strbuf)) if(!bencode_read_string(buffer, &strbuf))
return false; return false;
// bad msg size? // bad msg size?
if(strbuf.sz != 1) if(strbuf.sz != 1)
return false; return false;
llarp::LogInfo("Handle DHT message ", *strbuf.base, llarp::LogInfo("Handle DHT message ", *strbuf.base,
" relayed=", dec->relayed); " relayed=", relayed);
switch(*strbuf.base) switch(*strbuf.base)
{ {
case 'F': case 'F':
dec->msg.reset(new FindIntroMessage(dec->From, dec->relayed)); msg.reset(new FindIntroMessage(From, relayed));
break; break;
case 'R': case 'R':
if(dec->relayed) if(relayed)
dec->msg.reset(new RelayedFindRouterMessage(dec->From)); msg.reset(new RelayedFindRouterMessage(From));
else else
dec->msg.reset(new FindRouterMessage(dec->From)); msg.reset(new FindRouterMessage(From));
break; break;
case 'S': case 'S':
dec->msg.reset(new GotRouterMessage(dec->From, dec->relayed)); msg.reset(new GotRouterMessage(From, relayed));
break; break;
case 'I': case 'I':
dec->msg.reset(new PublishIntroMessage()); msg.reset(new PublishIntroMessage());
break; break;
case 'G': case 'G':
if(dec->relayed) if(relayed)
{ {
dec->msg.reset(new RelayedGotIntroMessage()); msg.reset(new RelayedGotIntroMessage());
break; break;
} }
else else
{ {
dec->msg.reset(new GotIntroMessage(dec->From)); msg.reset(new GotIntroMessage(From));
break; break;
} }
default: default:
@ -75,23 +76,19 @@ namespace llarp
// bad msg type // bad msg type
return false; return false;
} }
dec->firstKey = false; firstKey = false;
return dec->msg != nullptr; return msg != nullptr;
} }
else else
return dec->msg->DecodeKey(*key, r->buffer); return msg->DecodeKey(*key, buffer);
} }
}; };
IMessage::Ptr_t IMessage::Ptr_t
DecodeMesssage(const Key_t &from, llarp_buffer_t *buf, bool relayed) DecodeMesssage(const Key_t &from, llarp_buffer_t *buf, bool relayed)
{ {
MessageDecoder dec(from); MessageDecoder dec(from, relayed);
dec.relayed = relayed; if(!bencode_read_dict(dec, buf))
dict_reader r;
r.user = &dec;
r.on_key = &MessageDecoder::on_key;
if(!bencode_read_dict(buf, &r))
return nullptr; return nullptr;
return std::move(dec.msg); return std::move(dec.msg);
@ -99,25 +96,25 @@ namespace llarp
struct ListDecoder struct ListDecoder
{ {
ListDecoder(const Key_t &from, std::vector< IMessage::Ptr_t > &list) ListDecoder(bool hasRelayed, const Key_t &from,
: From(from), l(list) std::vector< IMessage::Ptr_t > &list)
: relayed(hasRelayed), From(from), l(list)
{ {
} }
bool relayed = false; bool relayed;
const Key_t &From; const Key_t &From;
std::vector< IMessage::Ptr_t > &l; std::vector< IMessage::Ptr_t > &l;
static bool bool
on_item(list_reader *r, bool has) operator()(llarp_buffer_t *buffer, bool has)
{ {
ListDecoder *dec = static_cast< ListDecoder * >(r->user);
if(!has) if(!has)
return true; return true;
auto msg = DecodeMesssage(dec->From, r->buffer, dec->relayed); auto msg = DecodeMesssage(From, buffer, relayed);
if(msg) if(msg)
{ {
dec->l.emplace_back(std::move(msg)); l.emplace_back(std::move(msg));
return true; return true;
} }
else else
@ -129,12 +126,8 @@ namespace llarp
DecodeMesssageList(Key_t from, llarp_buffer_t *buf, DecodeMesssageList(Key_t from, llarp_buffer_t *buf,
std::vector< IMessage::Ptr_t > &list, bool relayed) std::vector< IMessage::Ptr_t > &list, bool relayed)
{ {
ListDecoder dec(from, list); ListDecoder dec(relayed, from, list);
dec.relayed = relayed; return bencode_read_list(dec, buf);
list_reader r;
r.user = &dec;
r.on_item = &ListDecoder::on_item;
return bencode_read_list(buf, &r);
} }
} // namespace dht } // namespace dht
} // namespace llarp } // namespace llarp

@ -38,13 +38,10 @@ namespace llarp
} }
bool bool
InboundMessageParser::OnKey(dict_reader* r, llarp_buffer_t* key) InboundMessageParser::operator()(llarp_buffer_t* buffer, llarp_buffer_t* key)
{ {
InboundMessageParser* handler =
static_cast< InboundMessageParser* >(r->user);
// we are reading the first key // we are reading the first key
if(handler->firstkey) if(firstkey)
{ {
llarp_buffer_t strbuf; llarp_buffer_t strbuf;
// check for empty dict // check for empty dict
@ -57,7 +54,7 @@ namespace llarp
return false; return false;
} }
if(!bencode_read_string(r->buffer, &strbuf)) if(!bencode_read_string(buffer, &strbuf))
{ {
llarp::LogWarn("could not read value of message type"); llarp::LogWarn("could not read value of message type");
return false; return false;
@ -74,23 +71,23 @@ namespace llarp
switch(*strbuf.cur) switch(*strbuf.cur)
{ {
case 'i': case 'i':
handler->msg = &handler->holder->i; msg = &holder->i;
isLIM = true; isLIM = true;
break; break;
case 'd': case 'd':
handler->msg = &handler->holder->d; msg = &holder->d;
break; break;
case 'u': case 'u':
handler->msg = &handler->holder->u; msg = &holder->u;
break; break;
case 'm': case 'm':
handler->msg = &handler->holder->m; msg = &holder->m;
break; break;
case 'c': case 'c':
handler->msg = &handler->holder->c; msg = &holder->c;
break; break;
case 'x': case 'x':
handler->msg = &handler->holder->x; msg = &holder->x;
break; break;
default: default:
return false; return false;
@ -98,20 +95,19 @@ namespace llarp
if(!isLIM) if(!isLIM)
{ {
const std::string host = const std::string host = "RX_" + RouterID(from->GetPubKey()).ToString();
"RX_" + RouterID(handler->from->GetPubKey()).ToString(); METRICS_DYNAMIC_INCREMENT(msg->Name(), host.c_str());
METRICS_DYNAMIC_INCREMENT(handler->msg->Name(), host.c_str());
} }
handler->msg->session = handler->from; msg->session = from;
handler->firstkey = false; firstkey = false;
return true; return true;
} }
// check for last element // check for last element
if(!key) if(!key)
return handler->MessageDone(); return MessageDone();
return handler->msg->DecodeKey(*key, r->buffer); return msg->DecodeKey(*key, buffer);
} }
bool bool
@ -135,12 +131,11 @@ namespace llarp
llarp::LogWarn("no link session"); llarp::LogWarn("no link session");
return false; return false;
} }
reader.user = this;
reader.on_key = &OnKey; from = src;
from = src; firstkey = true;
firstkey = true;
ManagedBuffer copy(buf); ManagedBuffer copy(buf);
return bencode_read_dict(&copy.underlying, &reader); return bencode_read_dict(*this, &copy.underlying);
} }
void void

@ -16,10 +16,9 @@ namespace llarp
{ {
InboundMessageParser(AbstractRouter* router); InboundMessageParser(AbstractRouter* router);
~InboundMessageParser(); ~InboundMessageParser();
dict_reader reader;
static bool bool
OnKey(dict_reader* r, llarp_buffer_t* buf); operator()(llarp_buffer_t* buffer, llarp_buffer_t* key);
/// start processig message from a link session /// start processig message from a link session
bool bool

@ -9,6 +9,8 @@
#include <util/logic.hpp> #include <util/logic.hpp>
#include <nodedb.hpp> #include <nodedb.hpp>
#include <functional>
namespace llarp namespace llarp
{ {
LR_CommitMessage::~LR_CommitMessage() LR_CommitMessage::~LR_CommitMessage()
@ -113,47 +115,44 @@ namespace llarp
} }
bool bool
LR_CommitRecord::OnKey(dict_reader* r, llarp_buffer_t* key) LR_CommitRecord::OnKey(llarp_buffer_t* buffer, llarp_buffer_t* key)
{ {
if(!key) if(!key)
return true; return true;
LR_CommitRecord* self = static_cast< LR_CommitRecord* >(r->user);
bool read = false; bool read = false;
if(!BEncodeMaybeReadDictEntry("c", self->commkey, read, *key, r->buffer)) if(!BEncodeMaybeReadDictEntry("c", commkey, read, *key, buffer))
return false; return false;
if(!BEncodeMaybeReadDictEntry("i", self->nextHop, read, *key, r->buffer)) if(!BEncodeMaybeReadDictEntry("i", nextHop, read, *key, buffer))
return false; return false;
if(!BEncodeMaybeReadDictInt("l", self->lifetime, read, *key, r->buffer)) if(!BEncodeMaybeReadDictInt("l", lifetime, read, *key, buffer))
return false; return false;
if(!BEncodeMaybeReadDictEntry("n", self->tunnelNonce, read, *key, if(!BEncodeMaybeReadDictEntry("n", tunnelNonce, read, *key, buffer))
r->buffer))
return false; return false;
if(!BEncodeMaybeReadDictEntry("r", self->rxid, read, *key, r->buffer)) if(!BEncodeMaybeReadDictEntry("r", rxid, read, *key, buffer))
return false; return false;
if(!BEncodeMaybeReadDictEntry("t", self->txid, read, *key, r->buffer)) if(!BEncodeMaybeReadDictEntry("t", txid, read, *key, buffer))
return false; return false;
if(*key == "u") if(*key == "u")
{ {
self->nextRC = std::make_unique< RouterContact >(); nextRC = std::make_unique< RouterContact >();
return self->nextRC->BDecode(r->buffer); return nextRC->BDecode(buffer);
} }
if(!BEncodeMaybeReadVersion("v", self->version, LLARP_PROTO_VERSION, read, if(!BEncodeMaybeReadVersion("v", version, LLARP_PROTO_VERSION, read, *key,
*key, r->buffer)) buffer))
return false; return false;
if(*key == "w") if(*key == "w")
{ {
// check for duplicate // check for duplicate
if(self->work) if(work)
{ {
llarp::LogWarn("duplicate POW in LRCR"); llarp::LogWarn("duplicate POW in LRCR");
return false; return false;
} }
self->work = std::make_unique< PoW >(); work = std::make_unique< PoW >();
return self->work->BDecode(r->buffer); return work->BDecode(buffer);
} }
return read; return read;
} }
@ -161,10 +160,9 @@ namespace llarp
bool bool
LR_CommitRecord::BDecode(llarp_buffer_t* buf) LR_CommitRecord::BDecode(llarp_buffer_t* buf)
{ {
dict_reader r; using namespace std::placeholders;
r.user = this; return bencode_read_dict(std::bind(&LR_CommitRecord::OnKey, this, _1, _2),
r.on_key = &OnKey; buf);
return bencode_read_dict(buf, &r);
} }
bool bool

@ -41,8 +41,8 @@ namespace llarp
operator==(const LR_CommitRecord &other) const; operator==(const LR_CommitRecord &other) const;
private: private:
static bool bool
OnKey(dict_reader *r, llarp_buffer_t *buf); OnKey(llarp_buffer_t *buffer, llarp_buffer_t *key);
}; };
struct LR_CommitMessage : public ILinkMessage struct LR_CommitMessage : public ILinkMessage

@ -32,12 +32,10 @@ namespace llarp
InboundMessageParser::InboundMessageParser() InboundMessageParser::InboundMessageParser()
: firstKey(false) : firstKey(false)
, key('\0') , ourKey('\0')
, msg(nullptr) , msg(nullptr)
, m_Holder(std::make_unique< MessageHolder >()) , m_Holder(std::make_unique< MessageHolder >())
{ {
reader.user = this;
reader.on_key = &OnKey;
} }
InboundMessageParser::~InboundMessageParser() InboundMessageParser::~InboundMessageParser()
@ -45,76 +43,74 @@ namespace llarp
} }
bool bool
InboundMessageParser::OnKey(dict_reader* r, llarp_buffer_t* key) InboundMessageParser::operator()(llarp_buffer_t* buffer,
llarp_buffer_t* key)
{ {
InboundMessageParser* self = if(key == nullptr && firstKey)
static_cast< InboundMessageParser* >(r->user);
if(key == nullptr && self->firstKey)
{ {
// empty dict // empty dict
return false; return false;
} }
if(!key) if(!key)
return true; return true;
if(self->firstKey) if(firstKey)
{ {
llarp_buffer_t strbuf; llarp_buffer_t strbuf;
if(!(*key == "A")) if(!(*key == "A"))
return false; return false;
if(!bencode_read_string(r->buffer, &strbuf)) if(!bencode_read_string(buffer, &strbuf))
return false; return false;
if(strbuf.sz != 1) if(strbuf.sz != 1)
return false; return false;
self->key = *strbuf.cur; ourKey = *strbuf.cur;
LogDebug("routing message '", self->key, "'"); LogDebug("routing message '", key, "'");
switch(self->key) switch(ourKey)
{ {
case 'D': case 'D':
self->msg = &self->m_Holder->D; msg = &m_Holder->D;
break; break;
case 'L': case 'L':
self->msg = &self->m_Holder->L; msg = &m_Holder->L;
break; break;
case 'M': case 'M':
self->msg = &self->m_Holder->M; msg = &m_Holder->M;
break; break;
case 'P': case 'P':
self->msg = &self->m_Holder->P; msg = &m_Holder->P;
break; break;
case 'T': case 'T':
self->msg = &self->m_Holder->T; msg = &m_Holder->T;
break; break;
case 'H': case 'H':
self->msg = &self->m_Holder->H; msg = &m_Holder->H;
break; break;
case 'I': case 'I':
self->msg = &self->m_Holder->I; msg = &m_Holder->I;
break; break;
case 'G': case 'G':
self->msg = &self->m_Holder->G; msg = &m_Holder->G;
break; break;
case 'J': case 'J':
self->msg = &self->m_Holder->J; msg = &m_Holder->J;
break; break;
case 'O': case 'O':
self->msg = &self->m_Holder->O; msg = &m_Holder->O;
break; break;
case 'U': case 'U':
self->msg = &self->m_Holder->U; msg = &m_Holder->U;
break; break;
case 'C': case 'C':
self->msg = &self->m_Holder->C; msg = &m_Holder->C;
break; break;
default: default:
llarp::LogError("invalid routing message id: ", *strbuf.cur); llarp::LogError("invalid routing message id: ", *strbuf.cur);
} }
self->firstKey = false; firstKey = false;
return self->msg != nullptr; return msg != nullptr;
} }
else else
{ {
return self->msg->DecodeKey(*key, r->buffer); return msg->DecodeKey(*key, buffer);
} }
} }
@ -129,13 +125,13 @@ namespace llarp
firstKey = true; firstKey = true;
ManagedBuffer copiedBuf(buf); ManagedBuffer copiedBuf(buf);
auto& copy = copiedBuf.underlying; auto& copy = copiedBuf.underlying;
if(bencode_read_dict(&copy, &reader)) if(bencode_read_dict(*this, &copy))
{ {
msg->from = from; msg->from = from;
result = msg->HandleMessage(h, r); result = msg->HandleMessage(h, r);
if(!result) if(!result)
{ {
llarp::LogWarn("Failed to handle inbound routing message ", key); llarp::LogWarn("Failed to handle inbound routing message ", ourKey);
} }
} }
else else

@ -25,13 +25,12 @@ namespace llarp
ParseMessageBuffer(const llarp_buffer_t& buf, IMessageHandler* handler, ParseMessageBuffer(const llarp_buffer_t& buf, IMessageHandler* handler,
const PathID_t& from, AbstractRouter* r); const PathID_t& from, AbstractRouter* r);
private: bool
static bool operator()(llarp_buffer_t* buffer, llarp_buffer_t* key);
OnKey(dict_reader* r, llarp_buffer_t* key);
private:
bool firstKey; bool firstKey;
char key; char ourKey;
dict_reader reader;
struct MessageHolder; struct MessageHolder;

@ -121,59 +121,3 @@ bencode_end(llarp_buffer_t* buff)
assert(std::distance(std::begin(letter), std::end(letter)) == 1); assert(std::distance(std::begin(letter), std::end(letter)) == 1);
return buff->write(std::begin(letter), std::end(letter)); return buff->write(std::begin(letter), std::end(letter));
} }
bool
bencode_read_dict(llarp_buffer_t* buff, struct dict_reader* r)
{
if(buff->size_left() < 2) // minimum case is 'de'
return false;
llarp_buffer_t strbuf; // temporary buffer for current element
r->buffer = buff; // set up dict_reader
if(*r->buffer->cur != 'd') // ensure is a dictionary
return false;
r->buffer->cur++;
while(r->buffer->size_left() && *r->buffer->cur != 'e')
{
if(bencode_read_string(r->buffer, &strbuf))
{
if(!r->on_key(r, &strbuf)) // check for early abort
return false;
}
else
return false;
}
if(*r->buffer->cur != 'e')
{
llarp::LogWarn("reading dict not ending on 'e'");
// make sure we're at dictionary end
return false;
}
r->buffer->cur++;
return r->on_key(r, nullptr);
}
bool
bencode_read_list(llarp_buffer_t* buff, struct list_reader* r)
{
if(buff->size_left() < 2) // minimum case is 'le'
return false;
r->buffer = buff;
if(*r->buffer->cur != 'l') // ensure is a list
{
llarp::LogWarn("bencode::bencode_read_list - expecting list got ",
*r->buffer->cur);
return false;
}
r->buffer->cur++;
while(r->buffer->size_left() && *r->buffer->cur != 'e')
{
if(!r->on_item(r, true)) // check for early abort
return false;
}
if(*r->buffer->cur != 'e') // make sure we're at a list end
return false;
r->buffer->cur++;
return r->on_item(r, false);
}

@ -41,38 +41,4 @@ bencode_start_dict(llarp_buffer_t* buff);
bool bool
bencode_end(llarp_buffer_t* buff); bencode_end(llarp_buffer_t* buff);
struct dict_reader
{
/// makes passing data into on_key easier
llarp_buffer_t* buffer;
/// not currently used, maybe used in the future to pass additional
/// information to on_key
void* user;
/**
* called when we got a key string, return true to continue iteration
* called with null key on done iterating
*/
std::function< bool(dict_reader*, llarp_buffer_t*) > on_key;
};
bool
bencode_read_dict(llarp_buffer_t* buff, struct dict_reader* r);
struct list_reader
{
/// makes passing data into on_item easier
llarp_buffer_t* buffer;
/// not currently used, maybe used in the future to pass additional
/// information to on_item
void* user;
/**
* called with true when we got an element, return true to continue iteration
* called with false on iteration completion
*/
std::function< bool(list_reader*, bool) > on_item;
};
bool
bencode_read_list(llarp_buffer_t* buff, struct list_reader* r);
#endif #endif

@ -140,28 +140,6 @@ namespace llarp
return bencode_end(buf); return bencode_end(buf);
} }
template < typename Array >
bool
BEncodeReadArray(Array& array, llarp_buffer_t* buf)
{
if(*buf->cur != 'l') // ensure is a list
return false;
buf->cur++;
size_t idx = 0;
while(buf->size_left() && *buf->cur != 'e')
{
if(idx >= array.size())
return false;
if(!array[idx++].BDecode(buf))
return false;
}
if(*buf->cur != 'e') // make sure we're at a list end
return false;
buf->cur++;
return true;
}
template < typename Iter > template < typename Iter >
bool bool
BEncodeWriteList(Iter itr, Iter end, llarp_buffer_t* buf) BEncodeWriteList(Iter itr, Iter end, llarp_buffer_t* buf)
@ -176,44 +154,97 @@ namespace llarp
return bencode_end(buf); return bencode_end(buf);
} }
template < typename List_t > template < typename Sink >
bool bool
BEncodeReadList(List_t& result, llarp_buffer_t* buf) bencode_read_dict(Sink&& sink, llarp_buffer_t* buffer)
{ {
if(*buf->cur != 'l') // ensure is a list if(buffer->size_left() < 2) // minimum case is 'de'
return false; return false;
if(*buffer->cur != 'd') // ensure is a dictionary
buf->cur++; return false;
while(buf->size_left() && *buf->cur != 'e') buffer->cur++;
while(buffer->size_left() && *buffer->cur != 'e')
{ {
if(!result.emplace(result.end())->BDecode(buf)) llarp_buffer_t strbuf; // temporary buffer for current element
if(bencode_read_string(buffer, &strbuf))
{
if(!sink(buffer, &strbuf)) // check for early abort
return false;
}
else
return false; return false;
} }
if(*buf->cur != 'e') // make sure we're at a list end
if(*buffer->cur != 'e')
{
llarp::LogWarn("reading dict not ending on 'e'");
// make sure we're at dictionary end
return false; return false;
buf->cur++; }
return true; buffer->cur++;
return sink(buffer, nullptr);
} }
template < typename T > template < typename Sink >
bool bool
BEncodeReadSet(std::set< T >& result, llarp_buffer_t* buf) bencode_read_list(Sink&& sink, llarp_buffer_t* buffer)
{ {
if(*buf->cur != 'l') // ensure is a list if(buffer->size_left() < 2) // minimum case is 'le'
return false;
if(*buffer->cur != 'l') // ensure is a list
{
llarp::LogWarn("bencode::bencode_read_list - expecting list got ",
*buffer->cur);
return false; return false;
}
buf->cur++; buffer->cur++;
while(buf->size_left() && *buf->cur != 'e') while(buffer->size_left() && *buffer->cur != 'e')
{ {
T item; if(!sink(buffer, true)) // check for early abort
if(!item.BDecode(buf))
return false; return false;
return result.insert(item).second;
} }
if(*buf->cur != 'e') // make sure we're at a list end if(*buffer->cur != 'e') // make sure we're at a list end
return false; return false;
buf->cur++; buffer->cur++;
return true; return sink(buffer, false);
}
template < typename Array >
bool
BEncodeReadArray(Array& array, llarp_buffer_t* buf)
{
size_t idx = 0;
return bencode_read_list(
[&array, &idx](llarp_buffer_t* buffer, bool has) {
if(has)
{
if(idx >= array.size())
return false;
if(!array[idx++].BDecode(buffer))
return false;
}
return true;
},
buf);
}
template < typename List_t >
bool
BEncodeReadList(List_t& result, llarp_buffer_t* buf)
{
return bencode_read_list(
[&result](llarp_buffer_t* buffer, bool has) {
if(has)
{
if(!result.emplace(result.end())->BDecode(buffer))
{
return false;
}
}
return true;
},
buf);
} }
template < typename List_t > template < typename List_t >
@ -245,19 +276,16 @@ namespace llarp
virtual bool virtual bool
BDecode(llarp_buffer_t* buf) BDecode(llarp_buffer_t* buf)
{ {
dict_reader r; return bencode_read_dict(*this, buf);
r.user = this;
r.on_key = &OnKey;
return bencode_read_dict(buf, &r);
} }
// TODO: check for shadowed values elsewhere // TODO: check for shadowed values elsewhere
uint64_t version = 0; uint64_t version = 0;
static bool bool
OnKey(dict_reader* r, llarp_buffer_t* k) operator()(llarp_buffer_t* buffer, llarp_buffer_t* key)
{ {
return static_cast< IBEncodeMessage* >(r->user)->HandleKey(k, r->buffer); return HandleKey(key, buffer);
} }
bool bool

@ -387,15 +387,15 @@ TEST_P(DictReadTest, readtest)
std::vector< std::string > result; std::vector< std::string > result;
dict_reader reader{nullptr, nullptr, [&](dict_reader*, llarp_buffer_t* buf) { ASSERT_TRUE(llarp::bencode_read_dict(
if(buf) [&](llarp_buffer_t*, llarp_buffer_t* key) {
{ if(key)
result.emplace_back(buf->base, buf->base + buf->sz); {
} result.emplace_back(key->base, key->base + key->sz);
return true; }
}}; return true;
},
ASSERT_TRUE(bencode_read_dict(&buffer, &reader)); &buffer));
ASSERT_EQ(result, d.output); ASSERT_EQ(result, d.output);
} }
@ -422,18 +422,17 @@ TEST_P(ListReadTest, readtest)
std::vector< std::string > result; std::vector< std::string > result;
list_reader reader{nullptr, nullptr, [&](list_reader* r, bool cont) { ASSERT_TRUE(llarp::bencode_read_list(
if(cont) [&](llarp_buffer_t* b, bool cont) {
{ if(cont)
auto b = r->buffer; {
llarp_buffer_t tmp; llarp_buffer_t tmp;
bencode_read_string(b, &tmp); bencode_read_string(b, &tmp);
result.emplace_back(tmp.base, tmp.base + tmp.sz); result.emplace_back(tmp.base, tmp.base + tmp.sz);
} }
return true; return true;
}}; },
&buffer));
ASSERT_TRUE(bencode_read_list(&buffer, &reader));
ASSERT_EQ(result, d.output); ASSERT_EQ(result, d.output);
} }
@ -446,8 +445,6 @@ INSTANTIATE_TEST_CASE_P(TestBencode, ListReadTest,
TEST(TestBencode, ReadDictEmptyBuffer) TEST(TestBencode, ReadDictEmptyBuffer)
{ {
llarp_buffer_t buf((byte_t*)nullptr, 0); llarp_buffer_t buf((byte_t*)nullptr, 0);
dict_reader reader; ASSERT_FALSE(llarp::bencode_read_dict(
reader.on_key = [](dict_reader*, llarp_buffer_t*) -> bool { return true; }; [](llarp_buffer_t*, llarp_buffer_t*) { return true; }, &buf));
reader.user = nullptr;
ASSERT_FALSE(bencode_read_dict(&buf, &reader));
} }

Loading…
Cancel
Save