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_NUMBER_STRING_HPP
10  
#ifndef BOOST_HTTP_DETAIL_NUMBER_STRING_HPP
11  
#define BOOST_HTTP_DETAIL_NUMBER_STRING_HPP
11  
#define BOOST_HTTP_DETAIL_NUMBER_STRING_HPP
12  

12  

13  
#include <boost/http/detail/config.hpp>
13  
#include <boost/http/detail/config.hpp>
14  
#include <boost/core/detail/string_view.hpp>
14  
#include <boost/core/detail/string_view.hpp>
15  
#include <cstdint>
15  
#include <cstdint>
16  

16  

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

20  

21  
// Convert integer to decimal
21  
// Convert integer to decimal
22  
// string using in-place storage
22  
// string using in-place storage
23  
class number_string
23  
class number_string
24  
{
24  
{
25  
    static constexpr unsigned buf_size = 18;
25  
    static constexpr unsigned buf_size = 18;
26  
    char buf_[buf_size + 1];
26  
    char buf_[buf_size + 1];
27  
    std::size_t size_ = 0;
27  
    std::size_t size_ = 0;
28  

28  

29  
    void
29  
    void
30  
    construct_unsigned(
30  
    construct_unsigned(
31  
        std::uint64_t n) noexcept
31  
        std::uint64_t n) noexcept
32  
    {
32  
    {
33  
        buf_[buf_size] = '\0';
33  
        buf_[buf_size] = '\0';
34  
        auto const end =
34  
        auto const end =
35  
            &buf_[buf_size];
35  
            &buf_[buf_size];
36  
        auto p = end;
36  
        auto p = end;
37  
        if(n == 0)
37  
        if(n == 0)
38  
        {
38  
        {
39  
            *--p = '0';
39  
            *--p = '0';
40  
        }
40  
        }
41  
        else
41  
        else
42  
        {
42  
        {
43  
            while(n > 0)
43  
            while(n > 0)
44  
            {
44  
            {
45  
                *--p = '0' + (n%10);
45  
                *--p = '0' + (n%10);
46  
                n /= 10;
46  
                n /= 10;
47  
            }
47  
            }
48  
        }
48  
        }
49  
        size_ = end - p;
49  
        size_ = end - p;
50  
    }
50  
    }
51  

51  

52  
public:
52  
public:
53  
    number_string() = default;
53  
    number_string() = default;
54  
    number_string(
54  
    number_string(
55  
        number_string const&) = default;
55  
        number_string const&) = default;
56  
    number_string& operator=
56  
    number_string& operator=
57  
        (number_string const&) = default;
57  
        (number_string const&) = default;
58  

58  

59  
    explicit
59  
    explicit
60  
    number_string(
60  
    number_string(
61  
        std::uint64_t n) noexcept
61  
        std::uint64_t n) noexcept
62  
    {
62  
    {
63  
        construct_unsigned(n);
63  
        construct_unsigned(n);
64  
    }
64  
    }
65  

65  

66  
    char const*
66  
    char const*
67  
    data() const noexcept
67  
    data() const noexcept
68  
    {
68  
    {
69  
        return &buf_[
69  
        return &buf_[
70  
            buf_size] - size_;
70  
            buf_size] - size_;
71  
    }
71  
    }
72  

72  

73  
    std::size_t
73  
    std::size_t
74  
    size() const noexcept
74  
    size() const noexcept
75  
    {
75  
    {
76  
        return size_;
76  
        return size_;
77  
    }
77  
    }
78  

78  

79  
    core::string_view
79  
    core::string_view
80  
    str() const noexcept
80  
    str() const noexcept
81  
    {
81  
    {
82  
        return core::string_view(
82  
        return core::string_view(
83  
            data(), size());
83  
            data(), size());
84  
    }
84  
    }
85  

85  

86  
    operator
86  
    operator
87  
    core::string_view() const noexcept
87  
    core::string_view() const noexcept
88  
    {
88  
    {
89  
        return str();
89  
        return str();
90  
    }
90  
    }
91  
};
91  
};
92  

92  

93  
} // detail
93  
} // detail
94  
} // http
94  
} // http
95  
} // boost
95  
} // boost
96  

96  

97  
#endif
97  
#endif