Skip to content

Commit b5a8c54

Browse files
committed
Remove unnecessary regex
1 parent e33aba7 commit b5a8c54

File tree

4 files changed

+239
-14
lines changed

4 files changed

+239
-14
lines changed

include/string_view.hpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
#pragma once
2+
3+
#include <regex>
4+
5+
#if __cplusplus >= 201703L
6+
#include <string_view>
7+
namespace sdptransform {
8+
using string_view=std::string_view;
9+
string_view convertMatchToView(const std::ssub_match& match) {
10+
#if __cplusplus >= 202002L && __cpp_lib_concepts
11+
return string_view(match.first, match.second);
12+
#else
13+
return string_view(&(*match.first), match.second-match.first);
14+
#endif
15+
}
16+
}
17+
#else
18+
#include <string_view_lite.hpp>
19+
namespace sdptransform {
20+
using string_view=string_view_lite;
21+
string_view convertMatchToView(const std::ssub_match& match) {
22+
return string_view(match.first, match.second);
23+
}
24+
}
25+
#endif

include/string_view_lite.hpp

Lines changed: 190 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,190 @@
1+
#pragma once
2+
3+
#include <string>
4+
#include <algorithm>
5+
#include <ostream>
6+
7+
namespace sdptransform
8+
{
9+
// lite version of string_view for c++14
10+
class string_view_lite
11+
{
12+
public:
13+
// types
14+
using Traits_type = std::char_traits<char>;
15+
using value_type = char;
16+
using pointer = value_type *;
17+
using const_pointer = const value_type *;
18+
using reference = value_type &;
19+
using const_reference = const value_type &;
20+
using const_iterator = const value_type *;
21+
using iterator = const_iterator;
22+
using const_reverse_iterator = std::reverse_iterator<const_iterator>;
23+
using reverse_iterator = const_reverse_iterator;
24+
using size_type = size_t;
25+
using difference_type = ptrdiff_t;
26+
static constexpr size_type npos = size_type(-1);
27+
28+
constexpr string_view_lite() noexcept {}
29+
constexpr string_view_lite(const string_view_lite &) noexcept = default;
30+
constexpr string_view_lite &operator=(const string_view_lite &) noexcept = default;
31+
string_view_lite(const value_type *str) : data_(str), size_(Traits_type::length(str)) {}
32+
constexpr string_view_lite(std::nullptr_t) = delete;
33+
string_view_lite(const value_type *str, size_type len) : data_(str), size_(len)
34+
{
35+
if (Traits_type::length(str) < size_)
36+
{
37+
throw std::runtime_error("string_view_lite constructor : wrong length");
38+
}
39+
}
40+
string_view_lite(std::string::const_iterator begin, std::string::const_iterator end) : data_(&(*begin)), size_(end - begin) {}
41+
string_view_lite(const std::string &s) : data_(s.data()), size_(s.size()) {}
42+
43+
// iterator support
44+
constexpr const_iterator begin() const noexcept { return data_; }
45+
constexpr const_iterator end() const noexcept { return data_ + size_; }
46+
constexpr const_iterator cbegin() const noexcept { return begin(); }
47+
constexpr const_iterator cend() const noexcept { return end(); }
48+
const_reverse_iterator rbegin() const noexcept { return const_reverse_iterator(end()); }
49+
const_reverse_iterator rend() const noexcept { return const_reverse_iterator(begin()); }
50+
const_reverse_iterator crbegin() const noexcept { return rbegin(); }
51+
const_reverse_iterator crend() const noexcept { return rend(); }
52+
53+
// capacity
54+
constexpr size_type size() const noexcept { return size_; }
55+
constexpr size_type length() const noexcept { return size(); }
56+
constexpr size_type max_size() const noexcept { return npos; }
57+
[[nodiscard]] constexpr bool empty() const noexcept
58+
{
59+
return size() == 0U;
60+
}
61+
62+
// element access
63+
constexpr const_reference operator[](size_type pos) const { return *(data_ + pos); }
64+
constexpr const_reference at(size_type pos) const
65+
{
66+
if (pos >= size_)
67+
{
68+
throw std::out_of_range("string_view_lite at");
69+
}
70+
return operator[](pos);
71+
}
72+
constexpr const_reference front() const
73+
{
74+
if (empty())
75+
{
76+
throw std::out_of_range("string_view_lite front");
77+
}
78+
return *begin();
79+
}
80+
constexpr const_reference back() const
81+
{
82+
if (empty())
83+
{
84+
throw std::out_of_range("string_view_lite back");
85+
}
86+
return *(end() - 1);
87+
}
88+
constexpr const_pointer data() const noexcept { return data_; }
89+
90+
// modifiers
91+
constexpr void remove_prefix(size_type n)
92+
{
93+
if (n >= size_)
94+
{
95+
string_view_lite sv;
96+
swap(sv);
97+
}
98+
else
99+
{
100+
data_ += n;
101+
size_ -= n;
102+
}
103+
}
104+
constexpr void remove_suffix(size_type n)
105+
{
106+
if (n >= size_)
107+
{
108+
string_view_lite sv;
109+
swap(sv);
110+
}
111+
else
112+
{
113+
size_ -= n;
114+
}
115+
}
116+
void swap(string_view_lite &s) noexcept
117+
{
118+
std::swap(data_, s.data_);
119+
std::swap(size_, s.size_);
120+
}
121+
122+
// string operations
123+
124+
string_view_lite substr(size_type pos = 0, size_type n = npos) const
125+
{
126+
if (pos > size_)
127+
{
128+
throw std::out_of_range("string_view_lite substr");
129+
}
130+
if (pos == size_)
131+
{
132+
return string_view_lite();
133+
}
134+
if (n == npos || size_ < (n + pos))
135+
{
136+
return string_view_lite(data_ + pos, size_ - pos);
137+
}
138+
return string_view_lite(data_ + pos, n);
139+
}
140+
141+
// searching
142+
constexpr size_type find(string_view_lite s, size_type pos = 0) const noexcept
143+
{
144+
return pos >= size() ? npos : std::search(cbegin() + pos, cend(), s.cbegin(), s.cend(), Traits_type::eq) - cbegin();
145+
}
146+
constexpr size_type find(value_type c, size_type pos = 0) const noexcept
147+
{
148+
return (empty() || pos >= size()) ? npos : std::find(cbegin() + pos, cend(), c) - cbegin();
149+
}
150+
151+
constexpr size_type find_first_of(value_type c, size_type pos = 0) const noexcept
152+
{
153+
return find(c, pos);
154+
}
155+
size_type find_last_of(value_type c, size_type pos = npos) const noexcept
156+
{
157+
return empty() ? npos : std::find(const_reverse_iterator(cbegin() + pos + 1), crend(), c) - crbegin();
158+
}
159+
constexpr size_type find_first_not_of(value_type c, size_type pos = 0) const noexcept
160+
{
161+
return (pos >= size() || empty())
162+
? npos
163+
: std::find_if(cbegin() + pos, cend(), [&c](char other)
164+
{ return other != c; }) -
165+
cbegin();
166+
}
167+
constexpr size_type find_last_not_of(value_type c, size_type pos = npos) const noexcept
168+
{
169+
return empty() ? npos : std::find_if(const_reverse_iterator(cbegin() + pos + 1), crend(), [&c](char other)
170+
{ return other != c; }) -
171+
crbegin();
172+
}
173+
174+
private:
175+
const_pointer data_ = ""; // exposition only
176+
size_type size_ = 0U; // exposition only
177+
};
178+
179+
std::basic_ostream<string_view_lite::value_type, string_view_lite::Traits_type> &
180+
operator<<(std::basic_ostream<string_view_lite::value_type, string_view_lite::Traits_type> &os,
181+
string_view_lite str)
182+
{
183+
for (char c : str)
184+
{
185+
os << c;
186+
}
187+
return os;
188+
}
189+
190+
} // namespace sdptransform

src/parser.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,6 @@ namespace sdptransform
3434

3535
json parse(const std::string& sdp)
3636
{
37-
static const std::regex ValidLineRegex("^([a-z])=(.*)");
38-
3937
json session = json::object();
4038
std::stringstream sdpstream(sdp);
4139
std::string line;
@@ -49,7 +47,8 @@ namespace sdptransform
4947
line.pop_back();
5048

5149
// Ensure it's a valid SDP line.
52-
if (!std::regex_search(line, ValidLineRegex))
50+
// we match ^[a-z]=
51+
if (line.size()<2 || line[0]<'a' || line[0] > 'z' || line[1]!='=')
5352
continue;
5453

5554
char type = line[0];

src/writer.cpp

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#include <cstddef> // size_t
33
#include <sstream> // std::stringstream
44
#include <stdexcept>
5+
#include "string_view.hpp"
56

67
namespace sdptransform
78
{
@@ -166,42 +167,52 @@ namespace sdptransform
166167

167168
linestream << type << "=";
168169

170+
string_view runningFormat(format);
171+
size_t nextPos = 0U;
169172
for(
170-
auto it = std::sregex_iterator(format.begin(), format.end(), FormatRegex);
171-
it != std::sregex_iterator();
172-
++it
173-
)
173+
auto pos = runningFormat.find('%'); pos != std::string::npos; pos = runningFormat.find('%',nextPos))
174174
{
175-
const std::smatch& match = *it;
176-
const std::string& str = match.str();
175+
const char nextChar = (pos+1<runningFormat.size()) ? runningFormat[pos+1] : '0';
176+
const string_view prefix = runningFormat.substr(0,pos);
177+
178+
if(nextChar != '%' && nextChar != 'v' && nextChar != 'd' && nextChar != 's') {
179+
nextPos = pos +2;
180+
continue;
181+
}
177182

178183
if (i >= len)
179184
{
180-
linestream << str;
185+
linestream << prefix << '%' << nextChar;
181186
}
182187
else
183188
{
184189
auto& arg = args[i];
185190
i++;
186191

187-
linestream << match.prefix();
192+
linestream << prefix;
188193

189-
if (str == "%%")
194+
if (nextChar == '%')
190195
{
191196
linestream << "%";
192197
}
193-
else if (str == "%s" || str == "%d")
198+
else if (nextChar == 's' || nextChar == 'd')
194199
{
195200
if (arg.is_string())
196201
linestream << arg.get<std::string>();
197202
else
198203
linestream << arg;
199204
}
200-
else if (str == "%v")
205+
else if (nextChar == 'v')
201206
{
202207
// Do nothing.
203208
}
204209
}
210+
211+
runningFormat=runningFormat.substr(pos+2);
212+
nextPos=0;
213+
}
214+
if(!runningFormat.empty()) {
215+
linestream << runningFormat;
205216
}
206217

207218
linestream << "\r\n";

0 commit comments

Comments
 (0)