1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127
|
/*
** Copyright 2025 Double Precision, Inc.
** See COPYING for distribution information.
**
*/
#include "rfc2045/rfc2045.h"
rfc2045::entity_parser_base::entity_parser_base()=default;
rfc2045::entity_parser_base::~entity_parser_base()=default;
template<bool crlf> rfc2045::entity_parser<crlf>::~entity_parser()
{
// Call parsed_entity() to insure that the execution thread will get
// stopped, if we bailed out early without asking for the parsed_entity
// and then join the execution thread.
(void)this->parsed_entity();
parsing_thread.join();
}
namespace {
#if 0
}
#endif
// Define beginning/ending input iterators that the execution thread uses
// to parse content that was fed into the entity parser.
struct parser_end_iter {
};
struct parser_beg_iter {
rfc2045::entity_parser_base &entity_parser;
std::unique_lock<std::mutex> &lock;
mutable std::string buffer;
mutable std::string::iterator b{buffer.begin()}, e{b};
char store;
// If b==e on exit, there are no more chunks to parse.
char operator*() const
{
while (b == e)
{
if (!entity_parser.get_next_chunk(lock, buffer))
return 0;
b=buffer.begin();
e=buffer.end();
}
return *b;
}
parser_beg_iter &operator++()
{
operator*();
if (b != e)
++b;
return *this;
}
const char *operator++(int)
{
store=operator*();
if (b != e)
++b;
operator*(); // Must read the next chunk, if needed it.
return &store;
}
bool operator!=(const parser_end_iter &ei) const
{
return !operator==(ei);
}
bool operator==(const parser_end_iter &ei) const
{
operator*();
return b == e;
}
void drain()
{
while (b != e)
{
b=e;
operator*();
}
}
};
#if 0
{
#endif
}
template<bool crlf> rfc2045::entity_parser<crlf>::entity_parser()
{
parsing_thread=std::thread{
[this]
{
std::unique_lock lock{m};
parser_beg_iter b{*this, lock};
parser_end_iter e;
typename entity::template line_iter<crlf>::
template iter<parser_beg_iter,
parser_end_iter> i{b, e};
entity_getting_parsed.parse(i);
b.drain();
}};
}
template class rfc2045::entity_parser<false>;
template class rfc2045::entity_parser<true>;
|