Fix for ASAN Issues(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
45 message::message(const void *msg, size_t sz)
46 : m_size(sz)
47 , m_capacity(sz)
48 , m_msg((char *)msg)
49 , ref_cnt(0)
50 {
51         m_header.id = sequence++;
52         m_header.type = UNDEFINED_TYPE;
53         m_header.length = m_size;
54         m_header.err = 0;
55 }
56
57 message::message(const message &msg)
58 : m_size(msg.m_size)
59 , m_capacity(msg.m_capacity)
60 , m_msg(new(std::nothrow) char[(sizeof(char) * msg.m_capacity)])
61 , ref_cnt(0)
62 {
63         ::memcpy(&m_header, &msg.m_header, sizeof(message_header));
64         ::memcpy(m_msg, msg.m_msg, msg.m_size);
65 }
66
67 message::message(int error)
68 : m_size(0)
69 , m_capacity(0)
70 , m_msg(NULL)
71 , ref_cnt(0)
72 {
73         m_header.id = sequence++;
74         m_header.type = UNDEFINED_TYPE;
75         m_header.length = 0;
76         m_header.err = error;
77 }
78
79 message::~message()
80 {
81         if (m_msg && ref_cnt == 0) {
82                 delete [] m_msg;
83                 m_msg = NULL;
84         }
85 }
86
87 void message::enclose(const void *msg, const size_t sz)
88 {
89         if (!msg || sz == 0)
90                 return;
91
92         if (m_capacity < sz)
93                 return;
94
95         ::memcpy(reinterpret_cast<char *>(m_msg), msg, sz);
96         m_size = sz;
97         m_header.length = sz;
98 }
99
100 void message::enclose(int error)
101 {
102         m_header.err = error;
103         m_header.length = 0;
104         m_size = 0;
105 }
106
107 void message::disclose(void *msg)
108 {
109         if (!msg || !m_msg)
110                 return;
111
112         ::memcpy(msg, m_msg, m_size);
113 }
114
115 uint32_t message::type(void)
116 {
117         return m_header.type;
118 }
119
120 void message::set_type(uint32_t msg_type)
121 {
122         m_header.type = msg_type;
123 }
124
125 size_t message::size(void)
126 {
127         return m_size;
128 }
129
130 /* TODO: remove ref/unref and use reference counting automatically */
131 void message::ref(void)
132 {
133         ref_cnt++;
134 }
135
136 void message::unref(void)
137 {
138         ref_cnt--;
139
140         if (ref_cnt > 0 || !m_msg)
141                 return;
142
143         free(m_msg);
144         m_msg = NULL;
145         delete this;
146 }
147
148 int message::ref_count(void)
149 {
150         return ref_cnt;
151 }
152
153 message_header *message::header(void)
154 {
155         return &m_header;
156 }
157
158 char *message::body(void)
159 {
160         return m_msg;
161 }