Fix for ASAN Issue: alloc-dealloc mismatch
[platform/core/system/sensord.git] / src / shared / message.cpp
1 /*
2  * sensord
3  *
4  * Copyright (c) 2017 Samsung Electronics Co., Ltd.
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *
18  */
19
20 #include "message.h"
21
22 #include <sensor_log.h>
23 #include <atomic>
24 #include <memory>
25
26
27 using namespace ipc;
28
29 #define UNDEFINED_TYPE -2
30
31 static std::atomic<uint64_t> sequence(0);
32
33 message::message(size_t capacity)
34 : m_size(0)
35 , m_capacity(capacity)
36 , m_msg(new(std::nothrow) char[sizeof(char) *capacity])
37 , ref_cnt(0)
38 {
39         m_header.id = sequence++;
40         m_header.type = UNDEFINED_TYPE;
41         m_header.length = m_size;
42         m_header.err = 0;
43
44         for (int i = 0; i < MAX_HEADER_RESERVED; ++i)
45                 m_header.ancillary[i] = NULL;
46 }
47
48 message::message(const void *msg, size_t sz)
49 : m_size(sz)
50 , m_capacity(sz)
51 , m_msg((char *)msg)
52 , ref_cnt(0)
53 {
54         m_header.id = sequence++;
55         m_header.type = UNDEFINED_TYPE;
56         m_header.length = m_size;
57         m_header.err = 0;
58
59         for (int i = 0; i < MAX_HEADER_RESERVED; ++i)
60                 m_header.ancillary[i] = NULL;
61 }
62
63 message::message(const message &msg)
64 : m_size(msg.m_size)
65 , m_capacity(msg.m_capacity)
66 , m_msg(new(std::nothrow) char[(sizeof(char) * msg.m_capacity)])
67 , ref_cnt(0)
68 {
69         ::memcpy(&m_header, &msg.m_header, sizeof(message_header));
70         ::memcpy(m_msg, msg.m_msg, msg.m_size);
71 }
72
73 message::message(int error)
74 : m_size(0)
75 , m_capacity(0)
76 , m_msg(NULL)
77 , ref_cnt(0)
78 {
79         m_header.id = sequence++;
80         m_header.type = UNDEFINED_TYPE;
81         m_header.length = 0;
82         m_header.err = error;
83
84         for (int i = 0; i < MAX_HEADER_RESERVED; ++i)
85                 m_header.ancillary[i] = NULL;
86 }
87
88 message::~message()
89 {
90         if (m_msg && ref_cnt == 0) {
91                 delete [] m_msg;
92                 m_msg = NULL;
93         }
94 }
95
96 void message::enclose(const void *msg, const size_t sz)
97 {
98         if (!msg || sz == 0)
99                 return;
100
101         if (m_capacity < sz)
102                 return;
103
104         ::memcpy(reinterpret_cast<char *>(m_msg), msg, sz);
105         m_size = sz;
106         m_header.length = sz;
107 }
108
109 void message::enclose(int error)
110 {
111         m_header.err = error;
112         m_header.length = 0;
113         m_size = 0;
114 }
115
116 void message::disclose(void *msg)
117 {
118         if (!msg || !m_msg)
119                 return;
120
121         ::memcpy(msg, m_msg, m_size);
122 }
123
124 uint32_t message::type(void)
125 {
126         return m_header.type;
127 }
128
129 void message::set_type(uint32_t msg_type)
130 {
131         m_header.type = msg_type;
132 }
133
134 size_t message::size(void)
135 {
136         return m_size;
137 }
138
139 /* TODO: remove ref/unref and use reference counting automatically */
140 void message::ref(void)
141 {
142         ref_cnt++;
143 }
144
145 void message::unref(void)
146 {
147         ref_cnt--;
148
149         if (ref_cnt > 0 || !m_msg)
150                 return;
151
152         delete [] m_msg;
153         m_msg = NULL;
154         delete this;
155 }
156
157 int message::ref_count(void)
158 {
159         return ref_cnt;
160 }
161
162 message_header *message::header(void)
163 {
164         return &m_header;
165 }
166
167 char *message::body(void)
168 {
169         return m_msg;
170 }