--- /dev/null
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 "result_parcelable.hh"
+
+#include <vector>
+
+namespace pkgmgr_common {
+namespace parcel {
+
+void RemoveArgs() {}
+
+void RemoveArg(char *str) {
+ if (str == nullptr)
+ return;
+
+ free(str);
+}
+
+void RemoveArg(int n) {}
+
+template<typename T, typename... SubArgs>
+void RemoveArgs(T t, SubArgs... args) {
+ RemoveArg(t);
+ RemoveArgs(args...);
+}
+
+template<typename... Args>
+ResultParcelable<Args...>::ResultParcelable(
+ std::vector<std::tuple<Args...>>&& args) : args_(std::move(args)) {}
+
+template<typename... Args>
+ResultParcelable<Args...>::~ResultParcelable() {
+ for (auto& arg : args_) {
+ std::apply([](auto&... xs) {
+ (RemoveArgs(xs), ...);
+ }, arg);
+ }
+}
+
+template<typename... Args>
+void ResultParcelable<Args...>::WriteToParcel(
+ tizen_base::Parcel* parcel) const {
+ WriteInt(parcel, args_.size());
+
+ for (const std::tuple<Args...>& arg : args_) {
+ auto tmp_tuple = std::tuple_cat(std::make_tuple(this, parcel), arg);
+ std::apply([](const ResultParcelable<Args...> *a,
+ tizen_base::Parcel *parcel, auto&... xs) {
+ (a->WriteArgs(parcel, xs), ...);
+ }, tmp_tuple);
+ }
+}
+
+template <std::size_t... Ns , typename... Ts>
+auto tail_impl(std::index_sequence<Ns...> , std::tuple<Ts...> t) {
+ return std::make_tuple(std::get<Ns+2u>(t)...);
+}
+
+template <typename... Ts>
+auto tail(std::tuple<Ts...> t) {
+ return tail_impl(std::make_index_sequence<sizeof...(Ts) - 2u>(), t);
+}
+
+template<typename... Args>
+void ResultParcelable<Args...>::ReadFromParcel(tizen_base::Parcel* parcel) {
+ int len = 0;
+ ReadInt(parcel, &len);
+
+ for (int i = 0; i < len ; ++i) {
+ std::tuple<ResultParcelable<Args...> *, tizen_base::Parcel *, Args...> tmp_tuple;
+ std::get<0>(tmp_tuple) = this;
+ std::get<1>(tmp_tuple) = parcel;
+ std::apply([](ResultParcelable<Args...> *a,
+ tizen_base::Parcel *parcel, auto&... xs) {
+ (a->ReadArgs(parcel, &xs), ...);
+ }, tmp_tuple);
+ auto result = tail(tmp_tuple);
+ args_.emplace_back(std::move(result));
+ }
+}
+
+template<typename... Args>
+const std::vector<std::tuple<Args...>>& ResultParcelable<Args...>::GetResult() {
+ return args_;
+}
+
+template<typename... Args>
+template<typename T, typename... SubArgs>
+void ResultParcelable<Args...>::WriteArgs(
+ tizen_base::Parcel* parcel, const T& t, const SubArgs&... args) const {
+ WriteArg(parcel, t);
+ WriteArgs(parcel, args...);
+}
+
+template<typename... Args>
+void ResultParcelable<Args...>::WriteArgs(tizen_base::Parcel *parcel) const {}
+
+template<typename... Args>
+void ResultParcelable<Args...>::WriteArg(
+ tizen_base::Parcel* parcel, const char *str) const {
+ WriteString(parcel, str);
+}
+
+template<typename... Args>
+void ResultParcelable<Args...>::WriteArg(
+ tizen_base::Parcel* parcel, const int n) const {
+ WriteInt(parcel, n);
+}
+
+template<typename... Args>
+void ResultParcelable<Args...>::ReadArgs(tizen_base::Parcel* parcel) {}
+
+template<typename... Args>
+template<typename T, typename... SubArgs>
+void ResultParcelable<Args...>::ReadArgs(
+ tizen_base::Parcel* parcel, T* t, SubArgs*... args) {
+ ReadArg(parcel, t);
+ ReadArgs(parcel, args...);
+}
+
+template<typename... Args>
+void ResultParcelable<Args...>::ReadArg(
+ tizen_base::Parcel* parcel, char **str) {
+ ReadString(parcel, str);
+}
+
+template<typename... Args>
+void ResultParcelable<Args...>::ReadArg(
+ tizen_base::Parcel* parcel, int* n) {
+ ReadInt(parcel, n);
+}
+
+// for unit test
+template class ResultParcelable<char *, int>;
+
+} // namespace parcel
+} // namespace pkgmgr_common
--- /dev/null
+#ifndef RESULT_PARCELABLE_HH_
+#define RESULT_PARCELABLE_HH_
+
+#include "abstract_parcelable.hh"
+
+#include <vector>
+#include <tuple>
+
+namespace pkgmgr_common {
+namespace parcel {
+
+#ifndef EXPORT_API
+#define EXPORT_API __attribute__((visibility("default")))
+#endif
+
+template <typename... Args>
+class EXPORT_API ResultParcelable : public AbstractParcelable {
+ public:
+ class EXPORT_API Factory : IFactory {
+ public:
+ std::unique_ptr<AbstractParcelable> CreateParcel();
+ };
+
+ ResultParcelable() = default;
+ ResultParcelable(std::vector<std::tuple<Args...>>&& args);
+ ~ResultParcelable();
+
+ void WriteToParcel(tizen_base::Parcel* parcel) const override;
+ void ReadFromParcel(tizen_base::Parcel* parcel) override;
+
+ template<typename T, typename... SubArgs>
+ void WriteArgs(tizen_base::Parcel* parcel, const T& t, const SubArgs&... arg) const;
+ void WriteArgs(tizen_base::Parcel* parcel) const;
+
+ template<typename T, typename... SubArgs>
+ void ReadArgs(tizen_base::Parcel* parcel, T* t, SubArgs*... args);
+ void ReadArgs(tizen_base::Parcel* parcel);
+
+ const std::vector<std::tuple<Args...>>& GetResult();
+
+ private:
+ void WriteArg(tizen_base::Parcel* parcel, const char *str) const;
+ void WriteArg(tizen_base::Parcel* parcel, int n) const;
+ void ReadArg(tizen_base::Parcel* parcel, char **str);
+ void ReadArg(tizen_base::Parcel* parcel, int* n);
+
+ std::vector<std::tuple<Args...>> args_;
+};
+
+} // namespace parcel
+} // namespace pkgmgr_common
+
+#endif // RESULT_PARCELABLE_HH_
#include <cstdio>
#include <parcel.hh>
#include <iostream>
+#include <tuple>
#include "common/parcel/abstract_parcelable.hh"
#include "common/parcel/appinfo_parcelable.hh"
#include "common/parcel/certinfo_parcelable.hh"
#include "common/parcel/filter_parcelable.hh"
#include "common/parcel/pkginfo_parcelable.hh"
+#include "common/parcel/result_parcelable.hh"
#include "common/parcel/string_parcelable.hh"
#include "pkgmgrinfo_basic.h"
EXPECT_TRUE(IsEqualCertInfo(
origin_parcelable.GetCertInfo(), new_parcelable.GetCertInfo()));
}
+
+TEST_F(ParcelTest, ResultParcelable) {
+ tizen_base::Parcel parcel;
+ std::vector<std::tuple<char *, int>> vt;
+ vt.emplace_back(std::make_tuple(strdup("a"), 1));
+ vt.emplace_back(std::make_tuple(strdup("c"), 2));
+
+ pp::ResultParcelable<char *, int> origin_parcelable(std::move(vt));
+ pp::ResultParcelable<char *, int> new_parcelable;
+ parcel.WriteParcelable(origin_parcelable);
+ parcel.ReadParcelable(&new_parcelable);
+
+ const std::vector<std::tuple<char *, int>>& origin_result = origin_parcelable.GetResult();
+ const std::vector<std::tuple<char *, int>>& new_result = new_parcelable.GetResult();
+
+ EXPECT_EQ(origin_result.size(), new_result.size());
+ for (unsigned int i = 0; i < origin_result.size(); ++i) {
+ const std::tuple<char *, int> a = origin_result[i];
+ const std::tuple<char *, int> b = new_result[i];
+ EXPECT_EQ(strcmp(std::get<0>(a), std::get<0>(b)), 0);
+ EXPECT_EQ(std::get<1>(a), std::get<1>(b));
+ }
+}