Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
P
pistache
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Libraries
pistache
Commits
01c447af
Unverified
Commit
01c447af
authored
Jun 05, 2021
by
Kip
Committed by
GitHub
Jun 05, 2021
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #932 from Tachi107/cpp17-std-string-view
Use std::string_view
parents
09a0c70a
27b3c93b
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
17 additions
and
430 deletions
+17
-430
include/pistache/meson.build
include/pistache/meson.build
+0
-1
include/pistache/net.h
include/pistache/net.h
+2
-5
include/pistache/router.h
include/pistache/router.h
+0
-2
include/pistache/string_view.h
include/pistache/string_view.h
+0
-282
src/client/client.cc
src/client/client.cc
+15
-15
tests/CMakeLists.txt
tests/CMakeLists.txt
+0
-1
tests/meson.build
tests/meson.build
+0
-1
tests/string_view_test.cc
tests/string_view_test.cc
+0
-123
No files found.
include/pistache/meson.build
View file @
01c447af
...
...
@@ -33,7 +33,6 @@ install_headers([
'ssl_wrappers.h',
'stream.h',
'string_logger.h',
'string_view.h',
'tcp.h',
'timer_pool.h',
'transport.h',
...
...
include/pistache/net.h
View file @
01c447af
...
...
@@ -6,8 +6,6 @@
#pragma once
#include <pistache/view.h>
#include <cstring>
#include <limits>
#include <stdexcept>
...
...
@@ -175,10 +173,9 @@ namespace Pistache
namespace
helpers
{
inline
Address
httpAddr
(
const
StringV
iew
&
view
)
inline
Address
httpAddr
(
const
std
::
string_v
iew
&
view
)
{
auto
const
str
=
view
.
toString
();
return
Address
(
str
);
return
Address
(
std
::
string
(
view
));
}
}
// namespace helpers
...
...
include/pistache/router.h
View file @
01c447af
...
...
@@ -17,8 +17,6 @@
#include <pistache/http.h>
#include <pistache/http_defs.h>
#include "pistache/string_view.h"
namespace
Pistache
::
Rest
{
...
...
include/pistache/string_view.h
deleted
100644 → 0
View file @
09a0c70a
#pragma once
#define CUSTOM_STRING_VIEW 1
#if __cplusplus >= 201703L
#if defined(__has_include)
#if __has_include(<string_view>)
#undef CUSTOM_STRING_VIEW
#include <string_view>
#elif __has_include(<experimental/string_view>)
#undef CUSTOM_STRING_VIEW
#include <experimental/string_view>
namespace
std
{
using
string_view
=
experimental
::
string_view
;
}
#endif
#endif
#endif
#ifdef CUSTOM_STRING_VIEW
#include <endian.h>
#include <cstring>
#include <stdexcept>
#include <string>
namespace
std
{
class
string_view
{
public:
using
size_type
=
std
::
size_t
;
static
constexpr
size_type
npos
=
size_type
(
-
1
);
constexpr
string_view
()
noexcept
:
data_
(
nullptr
)
,
size_
(
0
)
{
}
constexpr
string_view
(
const
string_view
&
other
)
noexcept
=
default
;
constexpr
string_view
(
const
char
*
s
,
size_type
count
)
:
data_
(
s
)
,
size_
(
count
)
{
}
explicit
string_view
(
const
char
*
s
)
:
data_
(
s
)
,
size_
(
strlen
(
s
))
{
}
string_view
substr
(
size_type
pos
,
size_type
count
=
npos
)
const
{
if
(
pos
>
size_
)
{
throw
std
::
out_of_range
(
"Out of range."
);
}
size_type
rcount
=
std
::
min
(
count
,
size_
-
pos
);
return
{
data_
+
pos
,
rcount
};
}
constexpr
size_type
size
()
const
noexcept
{
return
size_
;
}
constexpr
size_type
length
()
const
noexcept
{
return
size_
;
}
constexpr
char
operator
[](
size_type
pos
)
const
{
return
data_
[
pos
];
}
constexpr
const
char
*
data
()
const
noexcept
{
return
data_
;
}
bool
operator
==
(
const
string_view
&
rhs
)
const
{
return
(
!
std
::
lexicographical_compare
(
data_
,
data_
+
size_
,
rhs
.
data_
,
rhs
.
data_
+
rhs
.
size_
)
&&
!
std
::
lexicographical_compare
(
rhs
.
data_
,
rhs
.
data_
+
rhs
.
size_
,
data_
,
data_
+
size_
));
}
string_view
&
operator
=
(
const
string_view
&
view
)
noexcept
=
default
;
size_type
find
(
string_view
v
,
size_type
pos
=
0
)
const
noexcept
{
if
(
size_
<
pos
)
return
npos
;
if
((
size_
-
pos
)
<
v
.
size_
)
return
npos
;
for
(;
pos
<=
(
size_
-
v
.
size_
);
++
pos
)
{
bool
found
=
true
;
for
(
size_type
i
=
0
;
i
<
v
.
size_
;
++
i
)
{
if
(
data_
[
pos
+
i
]
!=
v
.
data_
[
i
])
{
found
=
false
;
break
;
}
}
if
(
found
)
{
return
pos
;
}
}
return
npos
;
}
size_type
find
(
char
ch
,
size_type
pos
=
0
)
const
noexcept
{
return
find
(
string_view
(
&
ch
,
1
),
pos
);
}
size_type
find
(
const
char
*
s
,
size_type
pos
,
size_type
count
)
const
{
return
find
(
string_view
(
s
,
count
),
pos
);
}
size_type
find
(
const
char
*
s
,
size_type
pos
=
0
)
const
{
return
find
(
string_view
(
s
),
pos
);
}
size_type
rfind
(
string_view
v
,
size_type
pos
=
npos
)
const
noexcept
{
if
(
v
.
size_
>
size_
)
return
npos
;
if
(
pos
>
size_
)
pos
=
size_
;
size_t
start
=
size_
-
v
.
size_
;
if
(
pos
!=
npos
)
start
=
pos
;
for
(
size_t
offset
=
0
;
offset
<=
pos
;
++
offset
,
--
start
)
{
bool
found
=
true
;
for
(
size_t
j
=
0
;
j
<
v
.
size_
;
++
j
)
{
if
(
data_
[
start
+
j
]
!=
v
.
data_
[
j
])
{
found
=
false
;
break
;
}
}
if
(
found
)
{
return
start
;
}
}
return
npos
;
}
size_type
rfind
(
char
c
,
size_type
pos
=
npos
)
const
noexcept
{
return
rfind
(
string_view
(
&
c
,
1
),
pos
);
}
size_type
rfind
(
const
char
*
s
,
size_type
pos
,
size_type
count
)
const
{
return
rfind
(
string_view
(
s
,
count
),
pos
);
}
size_type
rfind
(
const
char
*
s
,
size_type
pos
=
npos
)
const
{
return
rfind
(
string_view
(
s
),
pos
);
}
constexpr
bool
empty
()
const
noexcept
{
return
size_
==
0
;
}
private:
const
char
*
data_
;
size_type
size_
;
};
template
<
>
struct
hash
<
string_view
>
{
//-----------------------------------------------------------------------------
// MurmurHash3 was written by Austin Appleby, and is placed in the public
// domain. The author hereby disclaims copyright to this source code.
private:
#ifdef __GNUC__
#define FORCE_INLINE __attribute__((always_inline)) inline
#else
#define FORCE_INLINE inline
#endif
static
FORCE_INLINE
std
::
uint32_t
Rotl32
(
const
std
::
uint32_t
x
,
const
std
::
int8_t
r
)
{
return
(
x
<<
r
)
|
(
x
>>
(
32
-
r
));
}
static
FORCE_INLINE
std
::
uint32_t
Getblock
(
const
std
::
uint32_t
*
p
,
const
int
i
)
{
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
return
p
[
i
];
#else
std
::
uint32_t
temp_number
=
p
[
i
];
uint8_t
(
&
number
)[
4
]
=
*
reinterpret_cast
<
uint8_t
(
*
)[
4
]
>
(
&
temp_number
);
std
::
swap
(
number
[
0
],
number
[
3
]);
std
::
swap
(
number
[
1
],
number
[
2
]);
return
temp_number
;
#endif
}
static
FORCE_INLINE
uint32_t
fmix32
(
uint32_t
h
)
{
h
^=
h
>>
16
;
h
*=
0x85ebca6b
;
h
^=
h
>>
13
;
h
*=
0xc2b2ae35
;
h
^=
h
>>
16
;
return
h
;
}
public:
string_view
::
size_type
operator
()(
const
string_view
&
str
)
const
{
const
uint32_t
len
=
static_cast
<
uint32_t
>
(
str
.
length
());
const
uint8_t
*
data
=
reinterpret_cast
<
const
uint8_t
*>
(
str
.
data
());
const
int
nblocks
=
static_cast
<
int
>
(
len
/
4
);
uint32_t
h1
=
0
;
// seed
const
uint32_t
c1
=
0xcc9e2d51U
;
const
uint32_t
c2
=
0x1b873593U
;
const
uint32_t
*
blocks
=
reinterpret_cast
<
const
uint32_t
*>
(
data
+
nblocks
*
4
);
for
(
auto
i
=
-
nblocks
;
i
;
++
i
)
{
uint32_t
k1
=
Getblock
(
blocks
,
i
);
k1
*=
c1
;
k1
=
Rotl32
(
k1
,
15
);
k1
*=
c2
;
h1
^=
k1
;
h1
=
Rotl32
(
h1
,
13
);
h1
=
h1
*
5
+
0xe6546b64
;
}
const
uint8_t
*
tail
=
data
+
nblocks
*
4
;
uint32_t
k1
=
0
;
switch
(
len
&
3
)
{
case
3
:
k1
^=
tail
[
2
]
<<
16
;
/* fall through */
case
2
:
k1
^=
tail
[
1
]
<<
8
;
/* fall through */
case
1
:
k1
^=
tail
[
0
];
k1
*=
c1
;
k1
=
Rotl32
(
k1
,
15
);
k1
*=
c2
;
h1
^=
k1
;
default:
break
;
}
h1
^=
len
;
h1
=
fmix32
(
h1
);
return
hash
<
int
>
()(
h1
);
}
#undef FORCE_INLINE
};
}
// namespace std
#endif
src/client/client.cc
View file @
01c447af
...
...
@@ -32,7 +32,10 @@ namespace Pistache
namespace
{
std
::
pair
<
StringView
,
StringView
>
splitUrl
(
const
std
::
string
&
url
)
// Using const_cast can result in undefined behavior.
// C++17 provides a non-const .data() overload,
// but url must be passed as a non-const reference (or by value)
std
::
pair
<
std
::
string_view
,
std
::
string_view
>
splitUrl
(
const
std
::
string
&
url
)
{
RawStreamBuf
<
char
>
buf
(
const_cast
<
char
*>
(
url
.
data
()),
url
.
size
());
StreamCursor
cursor
(
&
buf
);
...
...
@@ -44,10 +47,10 @@ namespace Pistache
StreamCursor
::
Token
hostToken
(
cursor
);
match_until
({
'?'
,
'/'
},
cursor
);
StringV
iew
host
(
hostToken
.
rawText
(),
hostToken
.
size
());
StringView
page
(
cursor
.
offset
(),
buf
.
end
ptr
());
std
::
string_v
iew
host
(
hostToken
.
rawText
(),
hostToken
.
size
());
std
::
string_view
page
(
cursor
.
offset
(),
buf
.
endptr
()
-
buf
.
cur
ptr
());
return
std
::
make_pair
(
std
::
move
(
host
),
std
::
move
(
page
)
);
return
std
::
make_pair
(
host
,
page
);
}
}
// namespace
...
...
@@ -106,15 +109,12 @@ namespace Pistache
{
using
Http
::
crlf
;
auto
res
=
request
.
resource
();
auto
s
=
splitUrl
(
res
);
auto
body
=
request
.
body
();
auto
query
=
request
.
query
();
auto
res
=
request
.
resource
();
auto
[
host
,
path
]
=
splitUrl
(
res
);
auto
body
=
request
.
body
();
auto
query
=
request
.
query
();
auto
host
=
s
.
first
;
auto
path
=
s
.
second
;
auto
pathStr
=
path
.
toString
();
auto
pathStr
=
std
::
string
(
path
);
streamBuf
<<
request
.
method
()
<<
" "
;
if
(
pathStr
[
0
]
!=
'/'
)
...
...
@@ -127,7 +127,7 @@ namespace Pistache
writeHeaders
(
streamBuf
,
request
.
headers
());
writeHeader
<
Http
::
Header
::
UserAgent
>
(
streamBuf
,
UA
);
writeHeader
<
Http
::
Header
::
Host
>
(
streamBuf
,
host
.
toString
(
));
writeHeader
<
Http
::
Header
::
Host
>
(
streamBuf
,
std
::
string
(
host
));
if
(
!
body
.
empty
())
{
writeHeader
<
Http
::
Header
::
ContentLength
>
(
streamBuf
,
body
.
size
());
...
...
@@ -1027,7 +1027,7 @@ namespace Pistache
auto
resourceData
=
request
.
resource
();
auto
resource
=
splitUrl
(
resourceData
);
auto
conn
=
pool
.
pickConnection
(
resource
.
first
);
auto
conn
=
pool
.
pickConnection
(
std
::
string
(
resource
.
first
)
);
if
(
conn
==
nullptr
)
{
...
...
@@ -1038,7 +1038,7 @@ namespace Pistache
auto
data
=
std
::
make_shared
<
Connection
::
RequestData
>
(
std
::
move
(
resolve
),
std
::
move
(
reject
),
std
::
move
(
request
),
nullptr
);
auto
&
queue
=
requestsQueues
[
resource
.
first
];
auto
&
queue
=
requestsQueues
[
std
::
string
(
resource
.
first
)
];
if
(
!
queue
.
enqueue
(
data
))
data
->
reject
(
std
::
runtime_error
(
"Queue is full"
));
});
...
...
tests/CMakeLists.txt
View file @
01c447af
...
...
@@ -36,7 +36,6 @@ pistache_test(listener_test)
pistache_test
(
request_size_test
)
pistache_test
(
streaming_test
)
pistache_test
(
rest_server_test
)
pistache_test
(
string_view_test
)
pistache_test
(
mailbox_test
)
pistache_test
(
stream_test
)
pistache_test
(
reactor_test
)
...
...
tests/meson.build
View file @
01c447af
...
...
@@ -19,7 +19,6 @@ pistache_test_files = [
'request_size_test',
'streaming_test',
'rest_server_test',
'string_view_test',
'mailbox_test',
'stream_test',
'reactor_test',
...
...
tests/string_view_test.cc
deleted
100644 → 0
View file @
09a0c70a
#include "gtest/gtest.h"
#include <pistache/string_view.h>
#include <string>
TEST
(
string_view_test
,
substr_test
)
{
std
::
string_view
orig
(
"test"
);
std
::
string_view
targ
(
"est"
);
std
::
string_view
sub
=
orig
.
substr
(
1
);
ASSERT_EQ
(
sub
,
targ
);
sub
=
orig
.
substr
(
1
,
10
);
ASSERT_EQ
(
sub
,
targ
);
ASSERT_THROW
(
orig
.
substr
(
6
),
std
::
out_of_range
);
}
TEST
(
string_view_test
,
find_test
)
{
std
::
string_view
orig
(
"test"
);
std
::
string_view
find
(
"est"
);
ASSERT_EQ
(
orig
.
find
(
find
),
std
::
size_t
(
1
));
ASSERT_EQ
(
orig
.
find
(
find
,
1
),
std
::
size_t
(
1
));
ASSERT_EQ
(
orig
.
find
(
find
,
2
),
std
::
size_t
(
-
1
));
ASSERT_EQ
(
orig
.
find
(
'e'
),
std
::
size_t
(
1
));
ASSERT_EQ
(
orig
.
find
(
'e'
,
1
),
std
::
size_t
(
1
));
ASSERT_EQ
(
orig
.
find
(
'e'
,
2
),
std
::
size_t
(
-
1
));
ASSERT_EQ
(
orig
.
find
(
'1'
),
std
::
size_t
(
-
1
));
ASSERT_EQ
(
orig
.
find
(
"est"
),
std
::
size_t
(
1
));
ASSERT_EQ
(
orig
.
find
(
"est"
,
1
),
std
::
size_t
(
1
));
ASSERT_EQ
(
orig
.
find
(
"est"
,
1
,
2
),
std
::
size_t
(
1
));
ASSERT_EQ
(
orig
.
find
(
"set"
),
std
::
size_t
(
-
1
));
ASSERT_EQ
(
orig
.
find
(
"est"
,
2
),
std
::
size_t
(
-
1
));
ASSERT_EQ
(
orig
.
find
(
"est"
,
2
,
2
),
std
::
size_t
(
-
1
));
}
TEST
(
string_view_test
,
find_test_2
)
{
std
::
string_view
orig1
(
"test"
);
std
::
string_view
find1
(
"est"
);
ASSERT_EQ
(
orig1
.
find
(
find1
,
std
::
size_t
(
-
1
)),
std
::
size_t
(
-
1
));
ASSERT_EQ
(
orig1
.
find
(
find1
,
std
::
size_t
(
-
1
)
-
2
),
std
::
size_t
(
-
1
));
std
::
string_view
orig2
(
"test"
);
std
::
string_view
find2
(
""
);
ASSERT_EQ
(
orig2
.
find
(
find2
,
std
::
size_t
(
6
)),
std
::
size_t
(
-
1
));
ASSERT_EQ
(
orig2
.
find
(
find2
,
std
::
size_t
(
2
)),
std
::
size_t
(
2
));
ASSERT_EQ
(
orig2
.
find
(
find2
,
std
::
size_t
(
-
1
)),
std
::
size_t
(
-
1
));
std
::
string_view
orig3
(
""
);
std
::
string_view
find3
(
""
);
ASSERT_EQ
(
orig3
.
find
(
find3
,
std
::
size_t
(
0
)),
std
::
size_t
(
0
));
ASSERT_EQ
(
orig3
.
find
(
find3
,
std
::
size_t
(
6
)),
std
::
size_t
(
-
1
));
}
TEST
(
string_view_test
,
rfind_test
)
{
std
::
string_view
orig
(
"test"
);
std
::
string_view
find
(
"est"
);
ASSERT_EQ
(
orig
.
rfind
(
find
),
std
::
size_t
(
1
));
ASSERT_EQ
(
orig
.
rfind
(
find
,
1
),
std
::
size_t
(
1
));
ASSERT_EQ
(
orig
.
rfind
(
'e'
),
std
::
size_t
(
1
));
ASSERT_EQ
(
orig
.
rfind
(
'e'
,
1
),
std
::
size_t
(
1
));
ASSERT_EQ
(
orig
.
rfind
(
'q'
),
std
::
size_t
(
-
1
));
ASSERT_EQ
(
orig
.
rfind
(
"est"
),
std
::
size_t
(
1
));
ASSERT_EQ
(
orig
.
rfind
(
"est"
,
1
),
std
::
size_t
(
1
));
ASSERT_EQ
(
orig
.
rfind
(
"est"
,
1
,
2
),
std
::
size_t
(
1
));
ASSERT_EQ
(
orig
.
rfind
(
"set"
),
std
::
size_t
(
-
1
));
}
TEST
(
string_view_test
,
rfind_test_2
)
{
std
::
string_view
orig1
(
"e"
);
std
::
string_view
find1
(
"e"
);
ASSERT_EQ
(
orig1
.
rfind
(
find1
),
std
::
size_t
(
0
));
ASSERT_EQ
(
orig1
.
rfind
(
find1
,
1
),
std
::
size_t
(
0
));
std
::
string_view
orig2
(
"e"
);
std
::
string_view
find2
(
""
);
ASSERT_EQ
(
orig2
.
rfind
(
find2
),
std
::
size_t
(
1
));
ASSERT_EQ
(
orig2
.
rfind
(
find2
,
1
),
std
::
size_t
(
1
));
std
::
string_view
orig3
(
""
);
std
::
string_view
find3
(
"e"
);
ASSERT_EQ
(
orig3
.
rfind
(
find3
),
std
::
size_t
(
-
1
));
ASSERT_EQ
(
orig3
.
rfind
(
find3
,
1
),
std
::
size_t
(
-
1
));
std
::
string_view
orig4
(
""
);
std
::
string_view
find4
(
""
);
ASSERT_EQ
(
orig4
.
rfind
(
find4
),
std
::
size_t
(
0
));
ASSERT_EQ
(
orig4
.
rfind
(
find4
,
1
),
std
::
size_t
(
0
));
std
::
string_view
orig5
(
"a"
);
std
::
string_view
find5
(
"b"
);
ASSERT_EQ
(
orig5
.
rfind
(
find5
),
std
::
size_t
(
-
1
));
ASSERT_EQ
(
orig5
.
rfind
(
find5
,
4
),
std
::
size_t
(
-
1
));
}
TEST
(
string_view_test
,
emptiness
)
{
std
::
string_view
e1
;
std
::
string_view
e2
(
""
);
std
::
string_view
e3
(
"test"
,
0
);
std
::
string_view
ne
(
"test"
);
ASSERT_TRUE
(
e1
.
empty
());
ASSERT_TRUE
(
e2
.
empty
());
ASSERT_TRUE
(
e3
.
empty
());
ASSERT_FALSE
(
ne
.
empty
());
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment