У меня есть небольшой класс, который упаковывает данные capnp. Он имеет читатель capnp в качестве переменной-члена, что полезно, так как тогда мне не нужно создавать читатель каждый раз, когда я хочу читать из данных. Класс выглядит примерно так:
template<typename R>
class WrappedMessage {
WrappedMessage(const char *ptr, size_t sizeBytes) {
m_Ptr = (const capnp::word*)::malloc(sizeBytes);
::memcpy((void*)m_Ptr, ptr, sizeBytes);
m_Size = sizeBytes / sizeof(capnp::word);
m_Reader = std::make_unique<capnp::FlatArrayMessageReader>(kj::ArrayPtr<const capnp::word>(m_Ptr, m_Size));
m_MsgReader = m_Reader->getRoot<R>();
}
const typename R::Reader &get() const {
return m_MsgReader;
}
....
protected:
const capnp::word *m_Ptr = nullptr;
size_t m_Size = 0;
std::unique_ptr<capnp::FlatArrayMessageReader> m_Reader;
typename R::Reader m_MsgReader;
}
Затем я могу прочитать capnp, используя что-то вроде:
template <typename T, typename...Args>
std::shared_ptr<WrappedMessage<T>> load_capnp(Args&& ...args) {
return std::make_shared<WrappedMessage<T>>(std::forward<Args>(args)...);
}
После запуска моей программы некоторое время, подобное этому, я увидел исключение в журналах:
Caught a kj exception: Exceeded message traversal limit. See capnp::ReaderOptions.
И после небольшого чтения я заметил, что capnp ограничивает количество байтов, которые читатель может пройти по соображениям безопасности.
Итак, я полагаю, мой вопрос имеет два аспекта:
ОБНОВИТЬ
Я просто заметил документы рекомендую не просто устанавливать более высокий лимит, а вместо этого я должен:
скопировать сообщение в новый MallocMessageBuilder перед запуском
но я не думаю, что смогу сделать это в общем (то есть, мне нужно было бы иметь метод для каждого типа, копирующий каждое поле из оригинального читателя в конструктор).
ОБНОВИТЬ
Я нашел некоторый полезный код Вот для построения компоновщика из буфера с помощью initMessageBuilderFromFlatArrayCopy
, Этот конструктор может затем использоваться для чтения данных, избегая при этом ограничения хода.
Я думаю, что это ответит на часть 2 моего вопроса, но я все еще хотел бы услышать о части 1 (держит читателей в действии) на случай, если есть лучший способ.
Задача ещё не решена.
Других решений пока нет …