2021-03-09 22:24:35 +00:00
|
|
|
#pragma once
|
2018-06-12 11:57:14 +00:00
|
|
|
|
2023-10-24 13:18:03 +00:00
|
|
|
#include "bencode.h"
|
|
|
|
#include "buffer.hpp"
|
|
|
|
#include "file.hpp"
|
|
|
|
#include "mem.hpp"
|
|
|
|
|
2022-07-16 00:41:14 +00:00
|
|
|
#include <llarp/util/logging.hpp>
|
2023-10-24 13:18:03 +00:00
|
|
|
|
2023-08-31 16:28:02 +00:00
|
|
|
#include <oxenc/bt.h>
|
2023-10-24 13:18:03 +00:00
|
|
|
|
2019-02-02 23:12:42 +00:00
|
|
|
#include <set>
|
2023-10-24 13:18:03 +00:00
|
|
|
#include <type_traits>
|
2019-02-02 23:12:42 +00:00
|
|
|
#include <vector>
|
2018-07-19 04:58:39 +00:00
|
|
|
|
2018-06-12 11:57:14 +00:00
|
|
|
namespace llarp
|
|
|
|
{
|
2023-08-31 16:28:02 +00:00
|
|
|
static auto ben_cat = log::Cat("stupid.bencode");
|
|
|
|
|
2023-11-02 12:39:20 +00:00
|
|
|
template <typename T>
|
|
|
|
T
|
|
|
|
decode_key(oxenc::bt_dict_consumer& btdp, const char* key)
|
|
|
|
{
|
|
|
|
return btdp.require<T>(key);
|
|
|
|
}
|
|
|
|
|
2020-04-07 18:38:56 +00:00
|
|
|
template <typename List_t>
|
2019-05-24 02:01:36 +00:00
|
|
|
bool
|
|
|
|
BEncodeReadList(List_t& result, llarp_buffer_t* buf);
|
|
|
|
|
2020-04-07 18:38:56 +00:00
|
|
|
template <typename Obj_t>
|
2018-06-23 00:00:44 +00:00
|
|
|
bool
|
|
|
|
BEncodeWriteDictString(const char* k, const Obj_t& str, llarp_buffer_t* buf)
|
|
|
|
{
|
|
|
|
return bencode_write_bytestring(buf, k, 1)
|
2018-08-10 21:34:11 +00:00
|
|
|
&& bencode_write_bytestring(buf, str.data(), str.size());
|
2018-06-23 00:00:44 +00:00
|
|
|
}
|
2018-06-12 11:57:14 +00:00
|
|
|
|
2020-04-07 18:38:56 +00:00
|
|
|
template <typename Obj_t>
|
2018-06-12 11:57:14 +00:00
|
|
|
bool
|
|
|
|
BEncodeWriteDictEntry(const char* k, const Obj_t& o, llarp_buffer_t* buf)
|
|
|
|
{
|
2023-08-31 16:28:02 +00:00
|
|
|
if (auto b = bencode_write_bytestring(buf, k, 1); not b)
|
|
|
|
return false;
|
|
|
|
auto bte = o.bt_encode();
|
|
|
|
buf->write(bte.begin(), bte.end());
|
|
|
|
return true;
|
2018-06-12 11:57:14 +00:00
|
|
|
}
|
|
|
|
|
2020-04-07 18:38:56 +00:00
|
|
|
template <typename Int_t>
|
2018-06-13 16:32:34 +00:00
|
|
|
bool
|
2018-07-23 21:59:43 +00:00
|
|
|
BEncodeWriteDictInt(const char* k, const Int_t& i, llarp_buffer_t* buf)
|
2018-06-13 16:32:34 +00:00
|
|
|
{
|
2021-03-08 20:48:11 +00:00
|
|
|
if (!bencode_write_bytestring(buf, k, 1))
|
|
|
|
return false;
|
|
|
|
if constexpr (std::is_enum_v<Int_t>)
|
|
|
|
return bencode_write_uint64(buf, static_cast<std::underlying_type_t<Int_t>>(i));
|
|
|
|
else
|
|
|
|
return bencode_write_uint64(buf, i);
|
2018-06-13 16:32:34 +00:00
|
|
|
}
|
|
|
|
|
2020-04-07 18:38:56 +00:00
|
|
|
template <typename List_t>
|
2018-08-30 18:48:43 +00:00
|
|
|
bool
|
2020-04-07 18:38:56 +00:00
|
|
|
BEncodeMaybeReadDictList(
|
|
|
|
const char* k, List_t& item, bool& read, const llarp_buffer_t& key, llarp_buffer_t* buf)
|
2018-08-30 18:48:43 +00:00
|
|
|
{
|
2022-09-09 21:48:38 +00:00
|
|
|
if (key.startswith(k))
|
2018-08-30 18:48:43 +00:00
|
|
|
{
|
2020-04-07 18:38:56 +00:00
|
|
|
if (!BEncodeReadList(item, buf))
|
2019-01-10 17:43:29 +00:00
|
|
|
{
|
2018-08-30 18:48:43 +00:00
|
|
|
return false;
|
2019-01-10 17:43:29 +00:00
|
|
|
}
|
2018-08-30 18:48:43 +00:00
|
|
|
read = true;
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2020-04-07 18:38:56 +00:00
|
|
|
template <typename Item_t>
|
2018-06-12 11:57:14 +00:00
|
|
|
bool
|
2020-04-07 18:38:56 +00:00
|
|
|
BEncodeMaybeReadDictEntry(
|
|
|
|
const char* k, Item_t& item, bool& read, const llarp_buffer_t& key, llarp_buffer_t* buf)
|
2018-06-12 11:57:14 +00:00
|
|
|
{
|
2022-09-09 21:48:38 +00:00
|
|
|
if (key.startswith(k))
|
2018-06-12 11:57:14 +00:00
|
|
|
{
|
2020-04-07 18:38:56 +00:00
|
|
|
if (!item.BDecode(buf))
|
2018-06-21 12:55:02 +00:00
|
|
|
{
|
2021-05-11 11:22:36 +00:00
|
|
|
llarp::LogWarn("failed to decode key ", k, " for entry in dict");
|
2018-08-08 17:43:46 +00:00
|
|
|
|
2018-06-12 11:57:14 +00:00
|
|
|
return false;
|
2018-06-21 12:55:02 +00:00
|
|
|
}
|
2018-06-12 11:57:14 +00:00
|
|
|
read = true;
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2020-04-07 18:38:56 +00:00
|
|
|
template <typename Int_t>
|
2018-06-22 13:59:28 +00:00
|
|
|
bool
|
2020-04-07 18:38:56 +00:00
|
|
|
BEncodeMaybeReadDictInt(
|
|
|
|
const char* k, Int_t& i, bool& read, const llarp_buffer_t& key, llarp_buffer_t* buf)
|
2018-06-22 13:59:28 +00:00
|
|
|
{
|
2022-09-09 21:48:38 +00:00
|
|
|
if (key.startswith(k))
|
2018-06-22 13:59:28 +00:00
|
|
|
{
|
2020-02-24 19:40:45 +00:00
|
|
|
uint64_t read_i;
|
2020-04-07 18:38:56 +00:00
|
|
|
if (!bencode_read_integer(buf, &read_i))
|
2018-06-22 13:59:28 +00:00
|
|
|
{
|
2021-05-11 11:22:36 +00:00
|
|
|
llarp::LogWarn("failed to decode key ", k, " for integer in dict");
|
2018-06-22 13:59:28 +00:00
|
|
|
return false;
|
|
|
|
}
|
2020-02-24 19:40:45 +00:00
|
|
|
|
2021-03-08 20:48:11 +00:00
|
|
|
i = static_cast<Int_t>(read_i);
|
2018-06-22 13:59:28 +00:00
|
|
|
read = true;
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2019-11-22 21:14:37 +00:00
|
|
|
/// If the key matches, reads in the version and ensures that it equals the
|
|
|
|
/// expected version
|
2020-04-07 18:38:56 +00:00
|
|
|
template <typename Item_t>
|
2018-06-12 11:57:14 +00:00
|
|
|
bool
|
2020-04-07 18:38:56 +00:00
|
|
|
BEncodeMaybeVerifyVersion(
|
|
|
|
const char* k,
|
|
|
|
Item_t& item,
|
|
|
|
uint64_t expect,
|
|
|
|
bool& read,
|
|
|
|
const llarp_buffer_t& key,
|
|
|
|
llarp_buffer_t* buf)
|
2018-06-12 11:57:14 +00:00
|
|
|
{
|
2022-09-09 21:48:38 +00:00
|
|
|
if (key.startswith(k))
|
2018-06-12 11:57:14 +00:00
|
|
|
{
|
2020-04-07 18:38:56 +00:00
|
|
|
if (!bencode_read_integer(buf, &item))
|
2018-06-12 11:57:14 +00:00
|
|
|
return false;
|
|
|
|
read = item == expect;
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2020-04-07 18:38:56 +00:00
|
|
|
template <typename List_t>
|
2018-06-23 00:00:44 +00:00
|
|
|
bool
|
2020-04-07 18:38:56 +00:00
|
|
|
BEncodeWriteDictBEncodeList(const char* k, const List_t& l, llarp_buffer_t* buf)
|
2018-06-23 00:00:44 +00:00
|
|
|
{
|
2023-08-31 16:28:02 +00:00
|
|
|
oxenc::bt_dict_producer btdp;
|
2018-06-23 00:00:44 +00:00
|
|
|
|
2023-08-31 16:28:02 +00:00
|
|
|
{
|
|
|
|
auto sublist = btdp.append_list(k);
|
|
|
|
|
|
|
|
for (const auto& item : l)
|
|
|
|
{
|
|
|
|
sublist.append(l.bt_encode());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
auto view = btdp.view();
|
|
|
|
buf->write(view.begin(), view.end());
|
|
|
|
|
|
|
|
return true;
|
2018-06-23 00:00:44 +00:00
|
|
|
}
|
|
|
|
|
2020-04-07 18:38:56 +00:00
|
|
|
template <typename Array>
|
2018-08-30 18:48:43 +00:00
|
|
|
bool
|
|
|
|
BEncodeWriteDictArray(const char* k, const Array& array, llarp_buffer_t* buf)
|
|
|
|
{
|
2020-04-07 18:38:56 +00:00
|
|
|
if (!bencode_write_bytestring(buf, k, 1))
|
2018-08-30 18:48:43 +00:00
|
|
|
return false;
|
2020-04-07 18:38:56 +00:00
|
|
|
if (!bencode_start_list(buf))
|
2018-08-30 18:48:43 +00:00
|
|
|
return false;
|
|
|
|
|
2020-04-07 18:38:56 +00:00
|
|
|
for (size_t idx = 0; idx < array.size(); ++idx)
|
2023-08-31 16:28:02 +00:00
|
|
|
if (!array[idx].bt_encode(buf))
|
2018-08-30 18:48:43 +00:00
|
|
|
return false;
|
|
|
|
return bencode_end(buf);
|
|
|
|
}
|
|
|
|
|
2020-04-07 18:38:56 +00:00
|
|
|
template <typename Iter>
|
2018-06-12 11:57:14 +00:00
|
|
|
bool
|
|
|
|
BEncodeWriteList(Iter itr, Iter end, llarp_buffer_t* buf)
|
|
|
|
{
|
2023-08-31 16:28:02 +00:00
|
|
|
oxenc::bt_list_producer btlp;
|
|
|
|
|
|
|
|
try
|
|
|
|
{
|
|
|
|
while (itr != end)
|
|
|
|
btlp.append(itr->bt_encode());
|
|
|
|
}
|
|
|
|
catch (...)
|
|
|
|
{
|
|
|
|
log::critical(ben_cat, "Stupid bencode.hpp shim code failed.");
|
|
|
|
}
|
|
|
|
|
|
|
|
auto view = btlp.view();
|
|
|
|
if (auto b = buf->write(view.begin(), view.end()); not b)
|
2018-06-12 11:57:14 +00:00
|
|
|
return false;
|
2023-08-31 16:28:02 +00:00
|
|
|
|
|
|
|
return true;
|
2018-06-12 11:57:14 +00:00
|
|
|
}
|
|
|
|
|
2020-04-07 18:38:56 +00:00
|
|
|
template <typename Sink>
|
2018-06-12 11:57:14 +00:00
|
|
|
bool
|
2019-05-22 00:36:03 +00:00
|
|
|
bencode_read_dict(Sink&& sink, llarp_buffer_t* buffer)
|
2018-06-12 11:57:14 +00:00
|
|
|
{
|
2020-04-07 18:38:56 +00:00
|
|
|
if (buffer->size_left() < 2) // minimum case is 'de'
|
2018-06-12 11:57:14 +00:00
|
|
|
return false;
|
2020-04-07 18:38:56 +00:00
|
|
|
if (*buffer->cur != 'd') // ensure is a dictionary
|
2019-05-22 00:36:03 +00:00
|
|
|
return false;
|
|
|
|
buffer->cur++;
|
2020-04-07 18:38:56 +00:00
|
|
|
while (buffer->size_left() && *buffer->cur != 'e')
|
2018-06-12 11:57:14 +00:00
|
|
|
{
|
2019-05-22 00:36:03 +00:00
|
|
|
llarp_buffer_t strbuf; // temporary buffer for current element
|
2020-04-07 18:38:56 +00:00
|
|
|
if (bencode_read_string(buffer, &strbuf))
|
2019-05-22 00:36:03 +00:00
|
|
|
{
|
2020-04-07 18:38:56 +00:00
|
|
|
if (!sink(buffer, &strbuf)) // check for early abort
|
2019-05-22 00:36:03 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
else
|
2018-06-12 11:57:14 +00:00
|
|
|
return false;
|
|
|
|
}
|
2019-05-22 00:36:03 +00:00
|
|
|
|
2020-04-07 18:38:56 +00:00
|
|
|
if (*buffer->cur != 'e')
|
2019-05-22 00:36:03 +00:00
|
|
|
{
|
|
|
|
llarp::LogWarn("reading dict not ending on 'e'");
|
|
|
|
// make sure we're at dictionary end
|
2018-06-12 11:57:14 +00:00
|
|
|
return false;
|
2019-05-22 00:36:03 +00:00
|
|
|
}
|
|
|
|
buffer->cur++;
|
|
|
|
return sink(buffer, nullptr);
|
2018-06-12 11:57:14 +00:00
|
|
|
}
|
|
|
|
|
2020-04-07 18:38:56 +00:00
|
|
|
template <typename Sink>
|
2019-05-24 02:01:36 +00:00
|
|
|
bool
|
|
|
|
bencode_decode_dict(Sink&& sink, llarp_buffer_t* buff)
|
|
|
|
{
|
|
|
|
return bencode_read_dict(
|
|
|
|
[&](llarp_buffer_t* buffer, llarp_buffer_t* key) {
|
2020-04-07 18:38:56 +00:00
|
|
|
if (key == nullptr)
|
2019-05-24 02:01:36 +00:00
|
|
|
return true;
|
2023-08-31 16:28:02 +00:00
|
|
|
if (sink.decode_key(*key, buffer))
|
2019-05-24 02:01:36 +00:00
|
|
|
return true;
|
2021-05-11 11:22:36 +00:00
|
|
|
llarp::LogWarn("undefined key '", *key->cur, "' for entry in dict");
|
2019-05-24 02:01:36 +00:00
|
|
|
|
|
|
|
return false;
|
|
|
|
},
|
|
|
|
buff);
|
|
|
|
}
|
|
|
|
|
2020-04-07 18:38:56 +00:00
|
|
|
template <typename Sink>
|
2018-07-19 04:58:39 +00:00
|
|
|
bool
|
2019-05-22 00:36:03 +00:00
|
|
|
bencode_read_list(Sink&& sink, llarp_buffer_t* buffer)
|
2018-07-19 04:58:39 +00:00
|
|
|
{
|
2020-04-07 18:38:56 +00:00
|
|
|
if (buffer->size_left() < 2) // minimum case is 'le'
|
2018-07-19 04:58:39 +00:00
|
|
|
return false;
|
2020-04-07 18:38:56 +00:00
|
|
|
if (*buffer->cur != 'l') // ensure is a list
|
2019-05-22 00:36:03 +00:00
|
|
|
{
|
2020-04-07 18:38:56 +00:00
|
|
|
llarp::LogWarn("bencode::bencode_read_list - expecting list got ", *buffer->cur);
|
2019-05-22 00:36:03 +00:00
|
|
|
return false;
|
|
|
|
}
|
2018-07-19 04:58:39 +00:00
|
|
|
|
2019-05-22 00:36:03 +00:00
|
|
|
buffer->cur++;
|
2020-04-07 18:38:56 +00:00
|
|
|
while (buffer->size_left() && *buffer->cur != 'e')
|
2018-07-19 04:58:39 +00:00
|
|
|
{
|
2020-04-07 18:38:56 +00:00
|
|
|
if (!sink(buffer, true)) // check for early abort
|
2018-07-19 04:58:39 +00:00
|
|
|
return false;
|
|
|
|
}
|
2020-04-07 18:38:56 +00:00
|
|
|
if (*buffer->cur != 'e') // make sure we're at a list end
|
2018-07-19 04:58:39 +00:00
|
|
|
return false;
|
2019-05-22 00:36:03 +00:00
|
|
|
buffer->cur++;
|
|
|
|
return sink(buffer, false);
|
|
|
|
}
|
|
|
|
|
2020-04-07 18:38:56 +00:00
|
|
|
template <typename Array>
|
2019-05-22 00:36:03 +00:00
|
|
|
bool
|
|
|
|
BEncodeReadArray(Array& array, llarp_buffer_t* buf)
|
|
|
|
{
|
|
|
|
size_t idx = 0;
|
|
|
|
return bencode_read_list(
|
|
|
|
[&array, &idx](llarp_buffer_t* buffer, bool has) {
|
2020-04-07 18:38:56 +00:00
|
|
|
if (has)
|
2019-05-22 00:36:03 +00:00
|
|
|
{
|
2020-04-07 18:38:56 +00:00
|
|
|
if (idx >= array.size())
|
2019-05-22 00:36:03 +00:00
|
|
|
return false;
|
2020-04-07 18:38:56 +00:00
|
|
|
if (!array[idx++].BDecode(buffer))
|
2019-05-22 00:36:03 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
},
|
|
|
|
buf);
|
|
|
|
}
|
2020-04-07 18:38:56 +00:00
|
|
|
template <typename List_t>
|
2019-05-22 00:36:03 +00:00
|
|
|
bool
|
|
|
|
BEncodeReadList(List_t& result, llarp_buffer_t* buf)
|
|
|
|
{
|
|
|
|
return bencode_read_list(
|
|
|
|
[&result](llarp_buffer_t* buffer, bool has) {
|
2020-04-07 18:38:56 +00:00
|
|
|
if (has)
|
2019-05-22 00:36:03 +00:00
|
|
|
{
|
2020-04-07 18:38:56 +00:00
|
|
|
if (!result.emplace(result.end())->BDecode(buffer))
|
2019-05-22 00:36:03 +00:00
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
},
|
|
|
|
buf);
|
2018-07-19 04:58:39 +00:00
|
|
|
}
|
|
|
|
|
2021-04-14 15:07:06 +00:00
|
|
|
/// read a std::set of decodable entities and deny duplicates
|
|
|
|
template <typename Set_t>
|
|
|
|
bool
|
|
|
|
BEncodeReadSet(Set_t& set, llarp_buffer_t* buffer)
|
|
|
|
{
|
|
|
|
return bencode_read_list(
|
|
|
|
[&set](llarp_buffer_t* buf, bool more) {
|
|
|
|
if (more)
|
|
|
|
{
|
|
|
|
typename Set_t::value_type item;
|
|
|
|
if (not item.BDecode(buf))
|
|
|
|
return false;
|
|
|
|
// deny duplicates
|
2021-04-14 19:40:57 +00:00
|
|
|
return set.emplace(item).second;
|
2021-04-14 15:07:06 +00:00
|
|
|
}
|
|
|
|
return true;
|
|
|
|
},
|
|
|
|
buffer);
|
|
|
|
}
|
|
|
|
|
2020-04-07 18:38:56 +00:00
|
|
|
template <typename List_t>
|
2018-06-12 11:57:14 +00:00
|
|
|
bool
|
|
|
|
BEncodeWriteDictList(const char* k, List_t& list, llarp_buffer_t* buf)
|
|
|
|
{
|
2020-04-07 18:38:56 +00:00
|
|
|
return bencode_write_bytestring(buf, k, 1) && BEncodeWriteList(list.begin(), list.end(), buf);
|
2018-06-12 11:57:14 +00:00
|
|
|
}
|
2018-06-23 00:00:44 +00:00
|
|
|
|
2020-04-07 18:38:56 +00:00
|
|
|
template <size_t bufsz, typename T>
|
2019-05-24 02:01:36 +00:00
|
|
|
void
|
|
|
|
Dump(const T& val)
|
2018-06-23 00:00:44 +00:00
|
|
|
{
|
2020-04-07 18:38:56 +00:00
|
|
|
std::array<byte_t, bufsz> tmp;
|
2019-05-24 02:01:36 +00:00
|
|
|
llarp_buffer_t buf(tmp);
|
2023-08-31 16:28:02 +00:00
|
|
|
|
|
|
|
auto bte = val.bt_encode();
|
|
|
|
|
|
|
|
if (auto b = buf.write(bte.begin(), bte.end()); b)
|
2020-04-07 18:38:56 +00:00
|
|
|
llarp::DumpBuffer<decltype(buf), 128>(buf);
|
2019-05-24 02:01:36 +00:00
|
|
|
}
|
2018-08-13 23:22:31 +00:00
|
|
|
|
2019-05-24 02:01:36 +00:00
|
|
|
/// read entire file and decode its contents into t
|
2020-04-07 18:38:56 +00:00
|
|
|
template <typename T>
|
2019-05-24 02:01:36 +00:00
|
|
|
bool
|
2020-11-03 15:54:55 +00:00
|
|
|
BDecodeReadFile(const fs::path fpath, T& t)
|
2019-05-24 02:01:36 +00:00
|
|
|
{
|
2022-10-05 18:05:25 +00:00
|
|
|
std::string content;
|
|
|
|
try
|
2018-08-13 23:22:31 +00:00
|
|
|
{
|
2023-10-31 20:49:01 +00:00
|
|
|
content = util::file_to_string(fpath);
|
2022-10-05 18:05:25 +00:00
|
|
|
}
|
|
|
|
catch (const std::exception&)
|
|
|
|
{
|
|
|
|
return false;
|
2019-05-24 02:01:36 +00:00
|
|
|
}
|
2022-10-05 18:05:25 +00:00
|
|
|
llarp_buffer_t buf(content);
|
2019-12-06 17:32:46 +00:00
|
|
|
return t.BDecode(&buf);
|
2019-05-24 02:01:36 +00:00
|
|
|
}
|
2018-06-23 00:00:44 +00:00
|
|
|
|
2018-09-03 13:10:56 +00:00
|
|
|
/// bencode and write to file
|
2020-04-07 18:38:56 +00:00
|
|
|
template <typename T, size_t bufsz>
|
2018-09-03 13:10:56 +00:00
|
|
|
bool
|
2020-11-03 15:54:55 +00:00
|
|
|
BEncodeWriteFile(const fs::path fpath, const T& t)
|
2018-09-03 13:10:56 +00:00
|
|
|
{
|
2022-10-05 18:05:25 +00:00
|
|
|
std::string tmp(bufsz, 0);
|
2019-02-02 23:12:42 +00:00
|
|
|
llarp_buffer_t buf(tmp);
|
2023-08-31 16:28:02 +00:00
|
|
|
|
|
|
|
auto bte = t.bt_encode();
|
|
|
|
buf.write(bte.begin(), bte.end());
|
|
|
|
|
2022-10-05 18:05:25 +00:00
|
|
|
tmp.resize(buf.cur - buf.base);
|
|
|
|
try
|
2018-09-03 13:10:56 +00:00
|
|
|
{
|
2023-11-02 12:30:38 +00:00
|
|
|
util::buffer_to_file(fpath, tmp);
|
2022-10-05 18:05:25 +00:00
|
|
|
}
|
|
|
|
catch (const std::exception& e)
|
|
|
|
{
|
|
|
|
return false;
|
2018-09-03 13:10:56 +00:00
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2019-11-03 15:31:01 +00:00
|
|
|
/// seek for an int in a dict with a key k used for version
|
|
|
|
/// set v to parsed value if found
|
|
|
|
/// this call rewinds the buffer unconditionally before return
|
|
|
|
/// returns false only if there was
|
2020-04-07 18:38:56 +00:00
|
|
|
template <typename Int_t>
|
2019-11-03 15:31:01 +00:00
|
|
|
bool
|
|
|
|
BEncodeSeekDictVersion(Int_t& v, llarp_buffer_t* buf, const byte_t k)
|
|
|
|
{
|
|
|
|
const auto ret = bencode_read_dict(
|
|
|
|
[&v, k](llarp_buffer_t* buffer, llarp_buffer_t* key) -> bool {
|
2020-04-07 18:38:56 +00:00
|
|
|
if (key == nullptr)
|
2019-11-03 15:31:01 +00:00
|
|
|
return true;
|
2020-04-07 18:38:56 +00:00
|
|
|
if (key->sz == 1 && *key->cur == k)
|
2019-11-03 15:31:01 +00:00
|
|
|
{
|
|
|
|
return bencode_read_integer(buffer, &v);
|
|
|
|
}
|
|
|
|
return bencode_discard(buffer);
|
2019-11-20 21:45:56 +00:00
|
|
|
},
|
|
|
|
buf);
|
2019-11-03 15:31:01 +00:00
|
|
|
// rewind
|
|
|
|
buf->cur = buf->base;
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2018-06-21 12:55:02 +00:00
|
|
|
} // namespace llarp
|