OpenVPN 3 Core Library
Loading...
Searching...
No Matches
split.hpp
Go to the documentation of this file.
1
// OpenVPN -- An application to securely tunnel IP networks
2
// over a single port, with support for SSL/TLS-based
3
// session authentication and key exchange,
4
// packet encryption, packet authentication, and
5
// packet compression.
6
//
7
// Copyright (C) 2012- OpenVPN Inc.
8
//
9
// SPDX-License-Identifier: MPL-2.0 OR AGPL-3.0-only WITH openvpn3-openssl-exception
10
//
11
12
// General string-splitting methods. These methods along with lexical analyzer
13
// classes (such as those defined in lex.hpp and OptionList::LexComment) can be
14
// used as a basis for parsers.
15
16
#ifndef OPENVPN_COMMON_SPLIT_H
17
#define OPENVPN_COMMON_SPLIT_H
18
19
#include <string>
20
#include <vector>
21
#include <utility>
22
23
#include <
openvpn/common/size.hpp
>
24
#include <
openvpn/common/lex.hpp
>
25
#include <
openvpn/common/clamp_typerange.hpp
>
26
27
28
using namespace
openvpn::numeric_util
;
29
30
namespace
openvpn::Split
{
31
32
enum
33
{
34
TRIM_LEADING_SPACES
= (1 << 0),
35
TRIM_SPECIAL
= (1 << 1),
// trims quotes (but respects their content)
36
};
37
38
struct
NullLimit
39
{
40
void
add_term
()
41
{
42
}
43
};
44
45
// Split a string using a character (such as ',') as a separator.
46
// Types:
47
// V : string vector of return data
48
// LEX : lexical analyzer class such as StandardLex
49
// LIM : limit class such as OptionList::Limits
50
// Args:
51
// ret : return data -- a list of strings
52
// input : input string to be split
53
// split_by : separator
54
// flags : TRIM_LEADING_SPACES, TRIM_SPECIAL
55
// max_terms : the size of the returned string list will be, at most, this value + 1. Pass
56
// ~0 to disable.
57
// lim : an optional limits object such as OptionList::Limits
58
template
<
typename
V,
typename
LEX,
typename
LIM>
59
inline
void
by_char_void
(V &ret,
const
std::string &
input
,
const
char
split_by,
const
unsigned
int
flags = 0,
const
unsigned
int
max_terms = ~0, LIM *lim =
nullptr
)
60
{
61
LEX lex;
62
unsigned
int
nterms = 0;
63
std::string term;
64
for
(std::string::const_iterator i =
input
.begin(); i !=
input
.end(); ++i)
65
{
66
const
char
c = *i;
67
lex.put(c);
68
if
(!lex.in_quote() && c == split_by && nterms < max_terms)
69
{
70
if
(lim)
71
lim->add_term();
72
ret.push_back(std::move(term));
73
++nterms;
74
term =
""
;
75
}
76
else
if
((!(flags &
TRIM_SPECIAL
) || lex.available())
77
&& (!(flags &
TRIM_LEADING_SPACES
) || !term.empty() || !
SpaceMatch::is_space
(c)))
78
term += c;
79
}
80
if
(lim)
81
lim->add_term();
82
ret.push_back(std::move(term));
83
}
84
85
// convenience method that returns data rather than modifying an in-place argument
86
template
<
typename
V,
typename
LEX,
typename
LIM>
87
inline
V
by_char
(
const
std::string &
input
,
const
char
split_by,
const
unsigned
int
flags = 0,
const
unsigned
int
max_terms = ~0, LIM *lim =
nullptr
)
88
{
89
V ret;
90
by_char_void<V, LEX, LIM>(ret,
input
, split_by, flags, max_terms, lim);
91
return
ret;
92
}
93
94
// Split a string using spaces as a separator.
95
// Types:
96
// V : string vector of return data
97
// LEX : lexical analyzer class such as StandardLex
98
// SPACE : class that we use to differentiate between space and non-space chars
99
// LIM : limit class such as OptionList::Limits
100
// Args:
101
// ret : return data -- a list of strings
102
// input : input string to be split
103
// lim : an optional limits object such as OptionList::Limits
104
template
<
typename
V,
typename
LEX,
typename
SPACE,
typename
LIM>
105
inline
void
by_space_void
(V &ret,
const
std::string &
input
, LIM *lim =
nullptr
)
106
{
107
LEX lex;
108
109
std::string term;
110
bool
defined =
false
;
111
for
(std::string::const_iterator i =
input
.begin(); i !=
input
.end(); ++i)
112
{
113
const
char
c = *i;
114
lex.put(c);
115
if
(lex.in_quote())
116
defined =
true
;
117
if
(lex.available())
118
{
119
const
char
tc = clamp_to_default<char>(lex.get(),
'?'
);
120
if
(!SPACE::is_space(tc) || lex.in_quote())
121
{
122
defined =
true
;
123
term += tc;
124
}
125
else
if
(defined)
126
{
127
if
(lim)
128
lim->add_term();
129
ret.push_back(std::move(term));
130
term =
""
;
131
defined =
false
;
132
}
133
}
134
}
135
if
(defined)
136
{
137
if
(lim)
138
lim->add_term();
139
ret.push_back(std::move(term));
140
}
141
}
142
143
// convenience method that returns data rather than modifying an in-place argument
144
template
<
typename
V,
typename
LEX,
typename
SPACE,
typename
LIM>
145
inline
V
by_space
(
const
std::string &
input
, LIM *lim =
nullptr
)
146
{
147
V ret;
148
by_space_void<V, LEX, SPACE, LIM>(ret,
input
, lim);
149
return
ret;
150
}
151
}
// namespace openvpn::Split
152
153
#endif
// OPENVPN_COMMON_SPLIT_H
clamp_typerange.hpp
lex.hpp
openvpn::Split
Definition
split.hpp:30
openvpn::Split::by_space_void
void by_space_void(V &ret, const std::string &input, LIM *lim=nullptr)
Definition
split.hpp:105
openvpn::Split::by_char
V by_char(const std::string &input, const char split_by, const unsigned int flags=0, const unsigned int max_terms=~0, LIM *lim=nullptr)
Definition
split.hpp:87
openvpn::Split::by_char_void
void by_char_void(V &ret, const std::string &input, const char split_by, const unsigned int flags=0, const unsigned int max_terms=~0, LIM *lim=nullptr)
Definition
split.hpp:59
openvpn::Split::TRIM_LEADING_SPACES
@ TRIM_LEADING_SPACES
Definition
split.hpp:34
openvpn::Split::TRIM_SPECIAL
@ TRIM_SPECIAL
Definition
split.hpp:35
openvpn::Split::by_space
V by_space(const std::string &input, LIM *lim=nullptr)
Definition
split.hpp:145
openvpn::numeric_util
Definition
clamp_typerange.hpp:22
size.hpp
openvpn::SpaceMatch::is_space
static bool is_space(char c)
Definition
lex.hpp:25
openvpn::Split::NullLimit
Definition
split.hpp:39
openvpn::Split::NullLimit::add_term
void add_term()
Definition
split.hpp:40
input
static const char * input[]
Definition
test_parseargv.cpp:31
openvpn
common
split.hpp
Generated by
1.9.8