Add a new API for creating parcel handle 69/285169/8
authorHwankyu Jhun <h.jhun@samsung.com>
Wed, 7 Dec 2022 06:06:53 +0000 (06:06 +0000)
committerHwanKyu Jhun <h.jhun@samsung.com>
Thu, 2 Feb 2023 07:31:42 +0000 (07:31 +0000)
To create a parcel handle without the header, a new API is added.

Adds:
 - rpc_port_parcel_create_without_header()

Change-Id: Ic4d0b79ea580243e988a02261a3c4b586f27bdd4
Signed-off-by: Hwankyu Jhun <h.jhun@samsung.com>
include/rpc-port-parcel.h
src/parcel-internal.cc
src/parcel-internal.hh
src/rpc-port-parcel.cc
test/unit_tests/rpc_port_parcel_test.cc

index 73fdbfe..29cd7df 100644 (file)
@@ -542,6 +542,20 @@ int rpc_port_parcel_get_raw(rpc_port_parcel_h h, void **raw, unsigned int *size)
 int rpc_port_parcel_create_from_raw(rpc_port_parcel_h *h, const void *raw, unsigned int size);
 
 /**
+ * @brief Creates the rpc port parcel handle without the header.
+ * @since_tizen 7.5
+ * @remarks You must release @h using rpc_port_parcel_destroy().
+ * @param[out] h The rpc port parcel handle
+ * @return @c 0 on success,
+ *         otherwise a negative error value
+ * @retval #RPC_PORT_ERROR_NONE Successful
+ * @retval #RPC_PORT_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #RPC_PORT_ERROR_OUT_OF_MEMORY Out of memory
+ * @see rpc_port_parcel_destroy()
+ */
+int rpc_port_parcel_create_without_header(rpc_port_parcel_h *h);
+
+/**
  * @}
  */
 
index 5cb299d..75f4302 100644 (file)
 namespace rpc_port {
 namespace internal {
 
-Parcel::Parcel() {}
+Parcel::Parcel(bool without_header)
+    : header_(without_header ? nullptr : new ParcelHeader()) {
+}
 
 Parcel::~Parcel() {}
 
 void Parcel::WriteToParcel(tizen_base::Parcel* parcel) const {
-  parcel->WriteParcelable(header_);
+  if (header_.get() != nullptr) {
+    parcel->WriteParcelable(*header_.get());
+    parcel->WriteUInt32(handle_.GetDataSize());
+  }
 
-  parcel->WriteUInt32(handle_.GetDataSize());
   parcel->Write(handle_.GetData(), handle_.GetDataSize());
 }
 
 void Parcel::ReadFromParcel(tizen_base::Parcel* parcel) {
-  parcel->ReadParcelable(&header_);
+  if (header_.get() != nullptr) {
+    parcel->ReadParcelable(header_.get());
 
-  uint32_t size = 0;
-  parcel->ReadUInt32(&size);
-  if (size > 0) {
-    auto* buf = static_cast<uint8_t*>(malloc(size));
-    if (buf == nullptr) {
-      _E("Out of memory");
-      return;
-    }
+    uint32_t size = 0;
+    parcel->ReadUInt32(&size);
+    if (size > 0) {
+      auto* buf = static_cast<uint8_t*>(malloc(size));
+      if (buf == nullptr) {
+        _E("Out of memory");
+        return;
+      }
 
-    parcel->Read(buf, size);
-    handle_ = std::move(tizen_base::Parcel(buf, size, false));
+      parcel->Read(buf, size);
+      handle_ = std::move(tizen_base::Parcel(buf, size, false));
+    }
+  } else {
+    handle_ = std::move(
+        tizen_base::Parcel(parcel->GetData(), parcel->GetDataSize()));
   }
 }
 
 const ParcelHeader* Parcel::GetParcelHeader() {
-  return &header_;
+  return header_.get();
 }
 
 parcel_h Parcel::GetHandle() const {
index 6c907b8..3d0911d 100644 (file)
@@ -31,7 +31,7 @@ namespace internal {
 
 class Parcel : public tizen_base::Parcelable {
  public:
-   Parcel();
+   Parcel(bool without_header = false);
    ~Parcel();
 
   void WriteToParcel(tizen_base::Parcel* parcel) const override;
@@ -44,7 +44,7 @@ class Parcel : public tizen_base::Parcelable {
   tizen_base::Parcel* GetRawParcel() const;
 
  private:
-  ParcelHeader header_;
+  std::unique_ptr<ParcelHeader> header_;
   tizen_base::Parcel handle_;
   std::unique_ptr<tizen_base::Parcel> raw_parcel_ { nullptr };
 };
index 098a53a..e665b5e 100644 (file)
@@ -453,6 +453,9 @@ RPC_API int rpc_port_parcel_get_header(rpc_port_parcel_h h,
 
   auto* parcel = static_cast<internal::Parcel*>(h);
   auto* parcel_header = parcel->GetParcelHeader();
+  if (parcel_header == nullptr)
+    return RPC_PORT_ERROR_INVALID_PARAMETER;
+
   *header = reinterpret_cast<rpc_port_parcel_header_h>(
       const_cast<internal::ParcelHeader*>(parcel_header));
   return RPC_PORT_ERROR_NONE;
@@ -553,3 +556,15 @@ RPC_API int rpc_port_parcel_create_from_raw(rpc_port_parcel_h* h,
   *h = parcel;
   return RPC_PORT_ERROR_NONE;
 }
+
+RPC_API int rpc_port_parcel_create_without_header(rpc_port_parcel_h* h) {
+  if (h == nullptr)
+    return RPC_PORT_ERROR_INVALID_PARAMETER;
+
+  auto* parcel = new (std::nothrow) internal::Parcel(true);
+  if (parcel == nullptr)
+    return RPC_PORT_ERROR_OUT_OF_MEMORY;
+
+  *h = static_cast<rpc_port_parcel_h>(parcel);
+  return RPC_PORT_ERROR_NONE;
+}
index 63038ca..07de128 100644 (file)
@@ -524,7 +524,7 @@ TEST_F(ParcelTest, rpc_port_parcel_create_from_raw_P) {
 }
 
 /*
- * @testcase rpc_port_parcel_create_from_raw_B
+ * @testcase rpc_port_parcel_create_from_raw_N
  * @description Creates the rpc parcel handle with given the raw data.
  * @apicovered rpc_port_parcel_create_from_raw
  */
@@ -532,3 +532,34 @@ TEST_F(ParcelTest, rpc_port_parcel_create_from_raw_N) {
   int ret = rpc_port_parcel_create_from_raw(nullptr, nullptr, 0);
   ASSERT_EQ(ret, RPC_PORT_ERROR_INVALID_PARAMETER);
 }
+
+/*
+ * @testcase rpc_port_parcel_create_without_header_P
+ * @description Creates the rpc parcel handle without the header.
+ * @apicovered rpc_port_parcel_create_without_header
+ */
+TEST_F(ParcelTest, rpc_port_parcel_create_without_header_P) {
+  rpc_port_parcel_h parcel = nullptr;
+  int ret = rpc_port_parcel_create_without_header(&parcel);
+  ASSERT_EQ(ret, RPC_PORT_ERROR_NONE);
+  ASSERT_NE(parcel, nullptr);
+
+  std::unique_ptr<std::remove_pointer<rpc_port_parcel_h>::type,
+      decltype(rpc_port_parcel_destroy)*> parcel_auto(
+          parcel, rpc_port_parcel_destroy);
+
+  rpc_port_parcel_header_h header = nullptr;
+  ret = rpc_port_parcel_get_header(parcel, &header);
+  ASSERT_EQ(ret, RPC_PORT_ERROR_INVALID_PARAMETER);
+  ASSERT_EQ(header, nullptr);
+}
+
+/*
+ * @testcase rpc_port_parcel_create_without_header_N
+ * @description Creates the rpc parcel handle without the header.
+ * @apicovered rpc_port_parcel_create_without_header
+ */
+TEST_F(ParcelTest, rpc_port_parcel_create_without_header_N) {
+  int ret = rpc_port_parcel_create_without_header(nullptr);
+  ASSERT_EQ(ret, RPC_PORT_ERROR_INVALID_PARAMETER);
+}