sensord: ipc: add message class 14/123114/2
authorkibak.yoon <kibak.yoon@samsung.com>
Tue, 4 Apr 2017 12:02:29 +0000 (21:02 +0900)
committerkibak.yoon <kibak.yoon@samsung.com>
Wed, 5 Apr 2017 00:53:00 +0000 (09:53 +0900)
- this class is a helper class for enconding/decoding the byte data.
- message object includes the message header automatically.
  - this header provides message id/type/size/error.

Change-Id: I03dc830baebf7a9bceac97013e9931f333f8f9d2
Signed-off-by: kibak.yoon <kibak.yoon@samsung.com>
src/shared/message.cpp [new file with mode: 0644]
src/shared/message.h [new file with mode: 0644]

diff --git a/src/shared/message.cpp b/src/shared/message.cpp
new file mode 100644 (file)
index 0000000..d7455eb
--- /dev/null
@@ -0,0 +1,159 @@
+/*
+ * sensord
+ *
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include "message.h"
+
+#include <sensor_log.h>
+#include <atomic>
+
+using namespace ipc;
+
+#define UNDEFINED_TYPE -2
+
+static std::atomic<uint64_t> sequence(0);
+
+message::message(size_t capacity)
+: m_size(0)
+, m_capacity(capacity)
+, m_msg((char *)malloc(sizeof(char) * capacity))
+, ref_cnt(0)
+{
+       m_header.id = sequence++;
+       m_header.type = UNDEFINED_TYPE;
+       m_header.length = m_size;
+       m_header.err = 0;
+}
+
+message::message(const void *msg, size_t sz)
+: m_size(sz)
+, m_capacity(sz)
+, m_msg((char *)msg)
+, ref_cnt(0)
+{
+       m_header.id = sequence++;
+       m_header.type = UNDEFINED_TYPE;
+       m_header.length = m_size;
+       m_header.err = 0;
+}
+
+message::message(const message &msg)
+: m_size(msg.m_size)
+, m_capacity(msg.m_capacity)
+, m_msg((char *)malloc(sizeof(char) * msg.m_capacity))
+, ref_cnt(0)
+{
+       ::memcpy(&m_header, &msg.m_header, sizeof(message_header));
+       ::memcpy(m_msg, msg.m_msg, msg.m_size);
+}
+
+message::message(int error)
+: m_size(0)
+, m_capacity(0)
+, m_msg(NULL)
+, ref_cnt(0)
+{
+       m_header.id = sequence++;
+       m_header.type = UNDEFINED_TYPE;
+       m_header.length = 0;
+       m_header.err = error;
+}
+
+message::~message()
+{
+       if (m_msg && ref_cnt == 0) {
+               free(m_msg);
+               m_msg = NULL;
+       }
+}
+
+void message::enclose(const void *msg, const size_t sz)
+{
+       if (!msg || sz == 0)
+               return;
+
+       if (m_capacity < sz)
+               return;
+
+       ::memcpy(reinterpret_cast<char *>(m_msg), msg, sz);
+       m_size = sz;
+       m_header.length = sz;
+}
+
+void message::enclose(int error)
+{
+       m_header.err = error;
+       m_header.length = 0;
+       m_size = 0;
+}
+
+void message::disclose(void *msg)
+{
+       if (!msg || !m_msg)
+               return;
+
+       ::memcpy(msg, m_msg, m_size);
+}
+
+uint32_t message::type(void)
+{
+       return m_header.type;
+}
+
+void message::set_type(uint32_t msg_type)
+{
+       m_header.type = msg_type;
+}
+
+size_t message::size(void)
+{
+       return m_size;
+}
+
+/* TODO: remove ref/unref and use reference counting automatically */
+void message::ref(void)
+{
+       ref_cnt++;
+}
+
+void message::unref(void)
+{
+       ref_cnt--;
+
+       if (ref_cnt > 0 || !m_msg)
+               return;
+
+       free(m_msg);
+       m_msg = NULL;
+       delete this;
+}
+
+int message::ref_count(void)
+{
+       return ref_cnt;
+}
+
+message_header *message::header(void)
+{
+       return &m_header;
+}
+
+char *message::body(void)
+{
+       return m_msg;
+}
diff --git a/src/shared/message.h b/src/shared/message.h
new file mode 100644 (file)
index 0000000..111cd9b
--- /dev/null
@@ -0,0 +1,74 @@
+/*
+ * sensord
+ *
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef __MESSAGE_H__
+#define __MESSAGE_H__
+
+#include <stdlib.h> /* size_t */
+#include <atomic>
+
+#define MAX_MSG_CAPACITY 4096
+#define MAX_HEADER_RESERVED 3
+
+namespace ipc {
+
+typedef struct message_header {
+       uint64_t id;
+       uint32_t type;
+       size_t length;
+       int32_t err;
+       void *ancillary[MAX_HEADER_RESERVED];
+} message_header;
+
+class message {
+public:
+       message(size_t capacity = MAX_MSG_CAPACITY);
+       message(const void *msg, size_t size);
+       message(const message &msg);
+       message(int err);
+       ~message();
+
+       void enclose(const void *msg, const size_t size);
+       void enclose(int error);
+       void disclose(void *msg);
+
+       uint32_t type(void);
+       void set_type(uint32_t type);
+
+       size_t size(void);
+
+       void ref(void);
+       void unref(void);
+       int  ref_count(void);
+
+       message_header *header(void);
+       char *body(void);
+
+private:
+       message_header m_header;
+       size_t m_size;
+       size_t m_capacity;
+
+       char *m_msg;
+       std::atomic<int> ref_cnt;
+};
+
+}
+
+#endif /* __MESSAGE_H__ */