Coverage Report

Created: 2023-09-25 06:13

/src/msgpack-c/include/msgpack/v1/sbuffer.hpp
Line
Count
Source (jump to first uncovered line)
1
//
2
// MessagePack for C++ simple buffer implementation
3
//
4
// Copyright (C) 2008-2016 FURUHASHI Sadayuki and KONDO Takatoshi
5
//
6
//    Distributed under the Boost Software License, Version 1.0.
7
//    (See accompanying file LICENSE_1_0.txt or copy at
8
//    http://www.boost.org/LICENSE_1_0.txt)
9
//
10
#ifndef MSGPACK_V1_SBUFFER_HPP
11
#define MSGPACK_V1_SBUFFER_HPP
12
13
#include "msgpack/v1/cpp_config_decl.hpp"
14
#include "msgpack/v1/sbuffer_decl.hpp"
15
#include "msgpack/assert.hpp"
16
17
#include <stdexcept>
18
#include <cstring>
19
20
namespace msgpack {
21
22
/// @cond
23
MSGPACK_API_VERSION_NAMESPACE(v1) {
24
/// @endcond
25
26
class sbuffer {
27
public:
28
    sbuffer(size_t initsz = MSGPACK_SBUFFER_INIT_SIZE):m_size(0), m_alloc(initsz)
29
1.19k
    {
30
1.19k
        if(initsz == 0) {
31
0
            m_data = MSGPACK_NULLPTR;
32
1.19k
        } else {
33
1.19k
            m_data = (char*)::malloc(initsz);
34
1.19k
            if(!m_data) {
35
0
                throw std::bad_alloc();
36
0
            }
37
1.19k
        }
38
1.19k
    }
39
40
    ~sbuffer()
41
1.19k
    {
42
1.19k
        ::free(m_data);
43
1.19k
    }
44
45
#if !defined(MSGPACK_USE_CPP03)
46
    sbuffer(const sbuffer&) = delete;
47
    sbuffer& operator=(const sbuffer&) = delete;
48
49
    sbuffer(sbuffer&& other) :
50
        m_size(other.m_size), m_data(other.m_data), m_alloc(other.m_alloc)
51
0
    {
52
0
        other.m_size = other.m_alloc = 0;
53
0
        other.m_data = MSGPACK_NULLPTR;
54
0
    }
55
56
    sbuffer& operator=(sbuffer&& other)
57
0
    {
58
0
        ::free(m_data);
59
0
60
0
        m_size = other.m_size;
61
0
        m_alloc = other.m_alloc;
62
0
        m_data = other.m_data;
63
0
64
0
        other.m_size = other.m_alloc = 0;
65
0
        other.m_data = MSGPACK_NULLPTR;
66
0
67
0
        return *this;
68
0
    }
69
#endif // !defined(MSGPACK_USE_CPP03)
70
71
    void write(const char* buf, size_t len)
72
1.30M
    {
73
1.30M
        MSGPACK_ASSERT(buf || len == 0);
74
75
1.30M
        if (!buf) return;
76
77
1.30M
        if(m_alloc - m_size < len) {
78
132
            expand_buffer(len);
79
132
        }
80
1.30M
        std::memcpy(m_data + m_size, buf, len);
81
1.30M
        m_size += len;
82
1.30M
    }
83
84
    char* data()
85
0
    {
86
0
        return m_data;
87
0
    }
88
89
    const char* data() const
90
0
    {
91
0
        return m_data;
92
0
    }
93
94
    size_t size() const
95
0
    {
96
0
        return m_size;
97
0
    }
98
99
    char* release()
100
0
    {
101
0
        char* tmp = m_data;
102
0
        m_size = 0;
103
0
        m_data = MSGPACK_NULLPTR;
104
0
        m_alloc = 0;
105
0
        return tmp;
106
0
    }
107
108
    void clear()
109
0
    {
110
0
        m_size = 0;
111
0
    }
112
113
private:
114
    void expand_buffer(size_t len)
115
132
    {
116
132
        size_t nsize = (m_alloc > 0) ?
117
132
                m_alloc * 2 : MSGPACK_SBUFFER_INIT_SIZE;
118
119
132
        while(nsize < m_size + len) {
120
0
            size_t tmp_nsize = nsize * 2;
121
0
            if (tmp_nsize <= nsize) {
122
0
                nsize = m_size + len;
123
0
                break;
124
0
            }
125
0
            nsize = tmp_nsize;
126
0
        }
127
128
132
        void* tmp = ::realloc(m_data, nsize);
129
132
        if(!tmp) {
130
0
            throw std::bad_alloc();
131
0
        }
132
133
132
        m_data = static_cast<char*>(tmp);
134
132
        m_alloc = nsize;
135
132
    }
136
137
#if defined(MSGPACK_USE_CPP03)
138
private:
139
    sbuffer(const sbuffer&);
140
    sbuffer& operator=(const sbuffer&);
141
#endif  // defined(MSGPACK_USE_CPP03)
142
143
private:
144
    size_t m_size;
145
    char* m_data;
146
    size_t m_alloc;
147
};
148
149
/// @cond
150
}  // MSGPACK_API_VERSION_NAMESPACE(v1)
151
/// @endcond
152
153
}  // namespace msgpack
154
155
#endif // MSGPACK_V1_SBUFFER_HPP