1  
//
1  
//
2  
// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
2  
// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
3  
//
3  
//
4  
// Distributed under the Boost Software License, Version 1.0. (See accompanying
4  
// Distributed under the Boost Software License, Version 1.0. (See accompanying
5  
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
5  
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6  
//
6  
//
7  
// Official repository: https://github.com/CPPAlliance/http
7  
// Official repository: https://github.com/CPPAlliance/http
8  
//
8  
//
9  

9  

10  
#ifndef BOOST_HTTP_DETAIL_MOVE_CHARS_HPP
10  
#ifndef BOOST_HTTP_DETAIL_MOVE_CHARS_HPP
11  
#define BOOST_HTTP_DETAIL_MOVE_CHARS_HPP
11  
#define BOOST_HTTP_DETAIL_MOVE_CHARS_HPP
12  

12  

13  
#include <boost/core/detail/string_view.hpp>
13  
#include <boost/core/detail/string_view.hpp>
14  
#include <cstring>
14  
#include <cstring>
15  
#include <functional>
15  
#include <functional>
16  

16  

17  
namespace boost {
17  
namespace boost {
18  
namespace http {
18  
namespace http {
19  
namespace detail {
19  
namespace detail {
20  

20  

21  
// Moves characters, and adjusts any passed
21  
// Moves characters, and adjusts any passed
22  
// views if they point to any moved characters.
22  
// views if they point to any moved characters.
23  

23  

24  
// true if s completely overlapped by buf
24  
// true if s completely overlapped by buf
25  
inline
25  
inline
26  
bool
26  
bool
27  
is_overlapping(
27  
is_overlapping(
28  
    core::string_view buf,
28  
    core::string_view buf,
29  
    core::string_view s) noexcept
29  
    core::string_view s) noexcept
30  
{
30  
{
31  
    auto const b0 = buf.data();
31  
    auto const b0 = buf.data();
32  
    auto const e0 = b0 + buf.size();
32  
    auto const e0 = b0 + buf.size();
33  
    auto const b1 = s.data();
33  
    auto const b1 = s.data();
34  
    auto const e1 = b1 + s.size();
34  
    auto const e1 = b1 + s.size();
35  
    auto const less_equal =
35  
    auto const less_equal =
36  
        std::less_equal<char const*>();
36  
        std::less_equal<char const*>();
37  
    if(less_equal(e0, b1))
37  
    if(less_equal(e0, b1))
38  
        return false;
38  
        return false;
39  
    if(less_equal(e1, b0))
39  
    if(less_equal(e1, b0))
40  
        return false;
40  
        return false;
41  
    // partial overlap is undefined
41  
    // partial overlap is undefined
42  
    BOOST_ASSERT(less_equal(e1, e0));
42  
    BOOST_ASSERT(less_equal(e1, e0));
43  
    BOOST_ASSERT(less_equal(b0, b1));
43  
    BOOST_ASSERT(less_equal(b0, b1));
44  
    return true;
44  
    return true;
45  
}
45  
}
46  

46  

47  
inline
47  
inline
48  
void
48  
void
49  
move_chars_impl(
49  
move_chars_impl(
50  
    char*,
50  
    char*,
51  
    char const*,
51  
    char const*,
52  
    core::string_view const&) noexcept
52  
    core::string_view const&) noexcept
53  
{
53  
{
54  
}
54  
}
55  

55  

56  
template<class... Sn>
56  
template<class... Sn>
57  
void
57  
void
58  
move_chars_impl(
58  
move_chars_impl(
59  
    char* dest,
59  
    char* dest,
60  
    char const* src,
60  
    char const* src,
61  
    core::string_view const& buf,
61  
    core::string_view const& buf,
62  
    core::string_view* s,
62  
    core::string_view* s,
63  
    Sn&&... sn) noexcept
63  
    Sn&&... sn) noexcept
64  
{
64  
{
65  
    if( s != nullptr &&
65  
    if( s != nullptr &&
66  
        is_overlapping(buf, *s))
66  
        is_overlapping(buf, *s))
67  
    {
67  
    {
68  
        *s = { s->data() + (dest - src), s->size() };
68  
        *s = { s->data() + (dest - src), s->size() };
69  
    }
69  
    }
70  
    move_chars_impl(dest, src, buf, sn...);
70  
    move_chars_impl(dest, src, buf, sn...);
71  
}
71  
}
72  

72  

73  
template<class... Args>
73  
template<class... Args>
74  
void
74  
void
75  
move_chars(
75  
move_chars(
76  
    char* dest,
76  
    char* dest,
77  
    char const* src,
77  
    char const* src,
78  
    std::size_t n,
78  
    std::size_t n,
79  
    Args&&... args) noexcept
79  
    Args&&... args) noexcept
80  
{
80  
{
81  
    move_chars_impl(
81  
    move_chars_impl(
82  
        dest,
82  
        dest,
83  
        src,
83  
        src,
84  
        core::string_view(src, n),
84  
        core::string_view(src, n),
85  
        args...);
85  
        args...);
86  
    std::memmove(
86  
    std::memmove(
87  
        dest, src, n);
87  
        dest, src, n);
88  
}
88  
}
89  

89  

90  
} // detail
90  
} // detail
91  
} // http
91  
} // http
92  
} // boost
92  
} // boost
93  

93  

94  
#endif
94  
#endif