]> git.ipfire.org Git - thirdparty/squid.git/blob - src/base/CharacterSet.cc
SourceFormat Enforcement
[thirdparty/squid.git] / src / base / CharacterSet.cc
1 /*
2 * Copyright (C) 1996-2017 The Squid Software Foundation and contributors
3 *
4 * Squid software is distributed under GPLv2+ license and includes
5 * contributions from numerous individuals and organizations.
6 * Please see the COPYING and CONTRIBUTORS files for details.
7 */
8
9 #include "squid.h"
10 #include "CharacterSet.h"
11
12 #include <algorithm>
13 #include <iostream>
14 #include <functional>
15
16 CharacterSet &
17 CharacterSet::operator +=(const CharacterSet &src)
18 {
19 Storage::const_iterator s = src.chars_.begin();
20 const Storage::const_iterator e = src.chars_.end();
21 Storage::iterator d = chars_.begin();
22 while (s != e) {
23 if (*s)
24 *d = 1;
25 ++s;
26 ++d;
27 }
28 return *this;
29 }
30
31 CharacterSet &
32 CharacterSet::operator -=(const CharacterSet &src)
33 {
34 Storage::const_iterator s = src.chars_.begin();
35 const Storage::const_iterator e = src.chars_.end();
36 Storage::iterator d = chars_.begin();
37 while (s != e) {
38 if (*s)
39 *d = 0;
40 ++s;
41 ++d;
42 }
43 return *this;
44 }
45
46 CharacterSet &
47 CharacterSet::add(const unsigned char c)
48 {
49 chars_[static_cast<uint8_t>(c)] = 1;
50 return *this;
51 }
52
53 CharacterSet &
54 CharacterSet::addRange(unsigned char low, unsigned char high)
55 {
56 //manual loop splitting is needed to cover case where high is 255
57 // otherwise low will wrap, resulting in infinite loop
58 while (low < high) {
59 chars_[static_cast<uint8_t>(low)] = 1;
60 ++low;
61 }
62 chars_[static_cast<uint8_t>(high)] = 1;
63 return *this;
64 }
65
66 CharacterSet
67 CharacterSet::complement(const char *label) const
68 {
69 CharacterSet result((label ? label : "complement_of_some_other_set"), "");
70 // negate each of our elements and add them to the result storage
71 std::transform(chars_.begin(), chars_.end(), result.chars_.begin(),
72 std::logical_not<Storage::value_type>());
73 return result;
74 }
75
76 CharacterSet::CharacterSet(const char *label, const char * const c) :
77 name(label ? label: "anonymous"),
78 chars_(Storage(256,0))
79 {
80 const size_t clen = strlen(c);
81 for (size_t i = 0; i < clen; ++i)
82 add(c[i]);
83 }
84
85 CharacterSet::CharacterSet(const char *label, unsigned char low, unsigned char high) :
86 name(label ? label: "anonymous"),
87 chars_(Storage(256,0))
88 {
89 addRange(low,high);
90 }
91
92 CharacterSet::CharacterSet(const char *label, std::initializer_list<std::pair<uint8_t, uint8_t>> ranges) :
93 name(label ? label: "anonymous"),
94 chars_(Storage(256,0))
95 {
96 for (auto range: ranges)
97 addRange(range.first, range.second);
98 }
99
100 CharacterSet
101 operator+ (CharacterSet lhs, const CharacterSet &rhs)
102 {
103 lhs += rhs;
104 return lhs;
105 }
106
107 CharacterSet
108 operator- (CharacterSet lhs, const CharacterSet &rhs)
109 {
110 lhs -= rhs;
111 return lhs;
112 }
113
114 std::ostream&
115 operator <<(std::ostream &s, const CharacterSet &c)
116 {
117 s << "CharacterSet(" << c.name << ')';
118 return s;
119 }
120
121 const CharacterSet
122 // RFC 5234
123 CharacterSet::ALPHA("ALPHA", "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"),
124 CharacterSet::BIT("BIT","01"),
125 CharacterSet::CR("CR","\r"),
126 CharacterSet::CTL("CTL", {{0x01,0x1f},{0x7f,0x7f}}),
127 CharacterSet::DIGIT("DIGIT","0123456789"),
128 CharacterSet::DQUOTE("DQUOTE","\""),
129 CharacterSet::HEXDIG("HEXDIG","0123456789aAbBcCdDeEfF"),
130 CharacterSet::HTAB("HTAB","\t"),
131 CharacterSet::LF("LF","\n"),
132 CharacterSet::SP("SP"," "),
133 CharacterSet::VCHAR("VCHAR", 0x21, 0x7e),
134 // RFC 7230
135 CharacterSet::WSP("WSP"," \t"),
136 CharacterSet::CTEXT("ctext", {{0x09,0x09},{0x20,0x20},{0x2a,0x5b},{0x5d,0x7e},{0x80,0xff}}),
137 CharacterSet::TCHAR("TCHAR","!#$%&'*+-.^_`|~0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"),
138 CharacterSet::SPECIAL("SPECIAL","()<>@,;:\\\"/[]?={}"),
139 CharacterSet::QDTEXT("QDTEXT", {{0x09,0x09},{0x20,0x21},{0x23,0x5b},{0x5d,0x7e},{0x80,0xff}}),
140 CharacterSet::OBSTEXT("OBSTEXT",0x80,0xff),
141 // RFC 7232
142 CharacterSet::ETAGC("ETAGC", {{0x21,0x21},{0x23,0x7e},{0x80,0xff}}),
143 // RFC 7235
144 CharacterSet::TOKEN68C("TOKEN68C","-._~+/0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")
145 ;
146