File: rfc2045cpp2.C

package info (click to toggle)
maildrop 3.2.1-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 14,896 kB
  • sloc: ansic: 29,827; cpp: 18,027; sh: 5,993; makefile: 882; perl: 94
file content (127 lines) | stat: -rw-r--r-- 2,168 bytes parent folder | download | duplicates (3)
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>;