Refactor Unit in C++ and rust generator for improving performance 69/315369/1
authorpjh9216 <jh9216.park@samsung.com>
Mon, 25 Nov 2024 00:54:53 +0000 (09:54 +0900)
committerpjh9216 <jh9216.park@samsung.com>
Mon, 2 Dec 2024 01:00:44 +0000 (10:00 +0900)
- Modify unit protocol
- Change unit key from string to i32
- Fix warnings

Change-Id: I271c0ed0274c533d2ea7b802928480cfa98a2f85
Signed-off-by: pjh9216 <jh9216.park@samsung.com>
30 files changed:
idlc/gen/generator.h
idlc/gen/version2/cpp_generator_base.cc
idlc/gen/version2/cpp_generator_base.hh
idlc/gen/version2/cpp_generator_base_cb.hh
idlc/gen/version2/cpp_group_body_generator.cc
idlc/gen/version2/cpp_group_body_generator.hh
idlc/gen/version2/cpp_group_body_generator_cb.hh
idlc/gen/version2/cpp_group_header_generator.cc
idlc/gen/version2/cpp_group_header_generator.hh
idlc/gen/version2/cpp_group_header_generator_cb.hh
idlc/gen/version2/cpp_proxy_body_generator.cc
idlc/gen/version2/cpp_proxy_body_generator.hh
idlc/gen/version2/cpp_proxy_body_generator_cb.hh
idlc/gen/version2/cpp_proxy_header_generator.cc
idlc/gen/version2/cpp_proxy_header_generator.hh
idlc/gen/version2/cpp_proxy_header_generator_cb.hh
idlc/gen/version2/cpp_stub_body_generator.cc
idlc/gen/version2/cpp_stub_body_generator.hh
idlc/gen/version2/cpp_stub_body_generator_cb.hh
idlc/gen/version2/cpp_stub_header_generator.cc
idlc/gen/version2/cpp_stub_header_generator.hh
idlc/gen/version2/cpp_stub_header_generator_cb.hh
idlc/gen/version2/rs_gen_base.cc
idlc/gen/version2/rs_gen_base_cb.h
idlc/gen/version2/rs_group_gen.cc
idlc/gen/version2/rs_group_gen_cb.h
idlc/gen/version2/rs_proxy_gen.cc
idlc/gen/version2/rs_proxy_gen_cb.h
idlc/gen/version2/rs_stub_gen.cc
idlc/gen/version2/rs_stub_gen_cb.h

index a46440a4131c6606f820422d9ea41999b7a34b16..d3abae20841de1394800d8c211daedc66c2e5967 100644 (file)
@@ -48,6 +48,16 @@ class Generator {
   bool IsDelegateType(const BaseType& type);
   std::string GetInterfaceNameFromDelegate(const BaseType& type);
 
+  int32_t GetHashCode(std::string_view str) const {
+    int32_t hash = 0;
+
+    for (auto& a : str) {
+      hash = 31 * hash + a;
+    }
+
+    return hash;
+  }
+
   void EnableNamespace(bool enable) {
     hasNamespace_ = enable;
   }
index f631a38602f9dd2c6458a0e0141e203db04ad560..212839aa73f5b923e224a75cf838896e80c02cff 100644 (file)
@@ -27,15 +27,11 @@ namespace version2 {
 namespace {
 
 bool IsObject(const BaseType& type) {
-  if (type.IsEnumType())
-    return false;
-
-  if (type.IsUserDefinedType() ||
-      type.GetMetaType() != nullptr ||
-      type.GetKeyType() != nullptr ||
-      type.ToString() == "string" ||
-      type.ToString() == "bundle" ||
-      type.ToString() == "file")
+  if (type.IsEnumType()) return false;
+
+  if (type.IsUserDefinedType() || type.GetMetaType() != nullptr ||
+      type.GetKeyType() != nullptr || type.ToString() == "string" ||
+      type.ToString() == "bundle" || type.ToString() == "file")
     return true;
 
   return false;
@@ -51,53 +47,33 @@ std::string GetBaseTypeName(const std::shared_ptr<Structure>& base) {
 }  // namespace
 
 CppGeneratorBase::CppGeneratorBase(std::shared_ptr<Document> doc,
-    bool thread_enabled)
-    : Generator(std::move(doc)),
-      thread_enabled_(thread_enabled) {
+                                   bool thread_enabled)
+    : Generator(std::move(doc)), thread_enabled_(thread_enabled) {
   type_map_ = {
-    {"char", "char"},
-    {"int", "int"},
-    {"short", "short"},
-    {"long", "long long"},
-    {"string", "std::string"},
-    {"bool", "bool"},
-    {"list", "std::list"},
-    {"float", "float"},
-    {"double", "double"},
-    {"file", "File"},
-    {"bundle", "Bundle"},
-    {"void", "void"},
-    {"array", "std::vector"},
-    {"map", "std::map"},
-    {"set", "std::set"},
+      {"char", "char"},          {"int", "int"},
+      {"short", "short"},        {"long", "long long"},
+      {"string", "std::string"}, {"bool", "bool"},
+      {"list", "std::list"},     {"float", "float"},
+      {"double", "double"},      {"file", "File"},
+      {"bundle", "Bundle"},      {"void", "void"},
+      {"array", "std::vector"},  {"map", "std::map"},
+      {"set", "std::set"},
   };
 
   parcel_type_map_ = {
-    {"char", "byte"},
-    {"int", "int32"},
-    {"short", "int16"},
-    {"long", "int64"},
-    {"string", "string"},
-    {"bool", "bool"},
-    {"float", "float"},
-    {"double", "double"},
-    {"bundle", "bundle"},
-    {"file", "string"},
+      {"char", "byte"},   {"int", "int32"},     {"short", "int16"},
+      {"long", "int64"},  {"string", "string"}, {"bool", "bool"},
+      {"float", "float"}, {"double", "double"}, {"bundle", "bundle"},
+      {"file", "string"},
   };
 
   type_init_map_ = {
-    {"char", "0"},
-    {"int", "0"},
-    {"short", "0"},
-    {"long", "0"},
-    {"bool", "false"},
-    {"float", "0.0f"},
-    {"double", "0.0"},
+      {"char", "0"},     {"int", "0"},      {"short", "0"},    {"long", "0"},
+      {"bool", "false"}, {"float", "0.0f"}, {"double", "0.0"},
   };
 
   for (auto& block : GetDocument().GetBlocks()) {
-    if (block->GetType() != Block::TYPE_STRUCTURE)
-      continue;
+    if (block->GetType() != Block::TYPE_STRUCTURE) continue;
 
     auto& st = static_cast<const Structure&>(*block);
     AddTypeName(st);
@@ -115,42 +91,11 @@ void CppGeneratorBase::AddTypeName(const Structure& st) {
   struct_types_[std::move(name)] = std::move(type_name);
 }
 
-void CppGeneratorBase::GenVersion(std::ofstream& stream) {
-  ReplaceAll(CB_VERSION)
-      .Change("<VERSION>", std::string(FULLVER))
-      .Transform([&](std::string code) { return RemoveLine(std::move(code)); })
-      .Out(stream);
-}
-
-void CppGeneratorBase::GenIncludeDefaultHeaders(std::ofstream& stream,
-    bool is_body) {
+std::string CppGeneratorBase::GenIncludeDefaultHeaders(bool is_body) {
   if (is_body)
-    stream << CB_BODY_HEADER;
+    return CB_BODY_HEADER;
   else
-    stream << CB_HEADER;
-}
-
-void CppGeneratorBase::GenLogTag(std::ofstream& stream,
-    const std::string& log_tag) {
-  ReplaceAll(CB_LOG_TAG)
-      .Change("<LOG_TAG>", log_tag)
-      .Out(stream);
-}
-
-void CppGeneratorBase::GenLogDefinition(std::ofstream& stream) {
-  stream << CB_LOG_DEF;
-}
-
-void CppGeneratorBase::GenVersionDefinition(std::ofstream& stream) {
-  ReplaceAll(CB_TIDL_VERSION)
-      .Change("<VERSION>", std::string(FULLVER))
-      .Out(stream);
-  stream << NLine(1);
-}
-
-void CppGeneratorBase::GenExportAPI(std::ofstream& stream) {
-  stream << CB_EXPORT_API;
-  stream << NLine(1);
+    return CB_HEADER;
 }
 
 std::string CppGeneratorBase::GenExceptions() {
@@ -163,8 +108,7 @@ std::string CppGeneratorBase::GenParameters(const Elements& elms) {
   bool first = true;
   std::string code;
   for (const auto& elm : elms) {
-    if (!first)
-      code += ", ";
+    if (!first) code += ", ";
 
     code += ConvertTypeToString(elm->GetType()) + " " + elm->GetID();
     first = false;
@@ -177,44 +121,40 @@ std::string CppGeneratorBase::GenMethodIds(const Interface& iface) {
   int value = 2;
   std::string code;
   for (const auto& decl : iface.GetDeclarations()) {
-    if (decl->GetMethodType() == Declaration::MethodType::DELEGATE)
-      continue;
+    if (decl->GetMethodType() == Declaration::MethodType::DELEGATE) continue;
 
     code += ReplaceAll(CB_ENUM)
-        .Change("<NAME>", decl->GetID())
-        .Change("<VALUE>", std::to_string(value++));
+                .Replace("NAME", decl->GetID())
+                .Replace("VALUE", std::to_string(value++));
     code += NLine(1);
   }
 
-  if (code.empty())
-    return code;
+  if (code.empty()) return code;
 
   return RemoveLine(
-      std::string(ReplaceAll(CB_METHOD_IDS).Change("<IDS>", code)));
+      std::string(ReplaceAll(CB_METHOD_IDS).Replace("IDS", code)));
 }
 
 std::string CppGeneratorBase::GenDelegateIds(const Interface& iface) {
   int value = 1;
   std::string code;
   for (const auto& decl : iface.GetDeclarations()) {
-    if (decl->GetMethodType() != Declaration::MethodType::DELEGATE)
-      continue;
+    if (decl->GetMethodType() != Declaration::MethodType::DELEGATE) continue;
 
     code += ReplaceAll(CB_ENUM)
-        .Change("<NAME>", decl->GetID())
-        .Change("<VALUE>", std::to_string(value++));
+                .Replace("NAME", decl->GetID())
+                .Replace("VALUE", std::to_string(value++));
     code += NLine(1);
   }
 
-  if (code.empty())
-    return code;
+  if (code.empty()) return code;
 
   return RemoveLine(
-      std::string(ReplaceAll(CB_DELEGATE_IDS).Change("<IDS>", code)));
+      std::string(ReplaceAll(CB_DELEGATE_IDS).Replace("IDS", code)));
 }
 
 std::string CppGeneratorBase::RemoveLine(std::string lines,
-    unsigned int line_num) {
+                                         unsigned int line_num) {
   std::stringstream ss(lines);
   std::string result;
   std::string line;
@@ -222,8 +162,7 @@ std::string CppGeneratorBase::RemoveLine(std::string lines,
 
   while (std::getline(ss, line, '\n')) {
     line_count++;
-    if (line_num == line_count)
-      continue;
+    if (line_num == line_count) continue;
 
     result += Trim(line);
     result += NLine(1);
@@ -233,7 +172,7 @@ std::string CppGeneratorBase::RemoveLine(std::string lines,
 }
 
 std::string CppGeneratorBase::RemoveLastLine(std::string lines,
-    unsigned int line_num) {
+                                             unsigned int line_num) {
   std::stringstream ss(lines);
   std::vector<std::string> tmp_lines;
   std::string line;
@@ -251,37 +190,30 @@ std::string CppGeneratorBase::RemoveLastLine(std::string lines,
   return result;
 }
 
-std::string CppGeneratorBase::Tab(int cnt) {
-  return std::string(cnt * 2, ' ');
-}
+std::string CppGeneratorBase::Tab(int cnt) { return std::string(cnt * 2, ' '); }
 
-std::string CppGeneratorBase::NLine(int cnt) {
-  return std::string(cnt, '\n');
-}
+std::string CppGeneratorBase::NLine(int cnt) { return std::string(cnt, '\n'); }
 
 std::string CppGeneratorBase::ConvertTypeToString(const BaseType& type,
-    bool full_name) {
-  if (type.IsEnumType())
-    return GetEnumTypeString(type.ToString());
+                                                  bool full_name) {
+  if (type.IsEnumType()) return GetEnumTypeString(type.ToString());
 
   if (type.IsUserDefinedType()) {
     if (IsDelegateType(type)) {
       std::string name = type.ToString();
-      if (full_name)
-        name = GetInterfaceNameFromDelegate(type) + "::" + name;
+      if (full_name) name = GetInterfaceNameFromDelegate(type) + "::" + name;
 
       return "std::unique_ptr<" + name + ">";
     }
 
-    if (type.ToString() == "remote_exception")
-      return "RemoteException";
+    if (type.ToString() == "remote_exception") return "RemoteException";
 
     return type.ToString();
   }
 
   if (type.GetMetaType() != nullptr) {
     return type_map_[type.ToString()] + "<" +
-        ConvertTypeToString(*(type.GetMetaType())) + ">";
+           ConvertTypeToString(*(type.GetMetaType())) + ">";
   }
 
   if (type.GetKeyType() != nullptr && type.GetValueType() != nullptr) {
@@ -294,8 +226,7 @@ std::string CppGeneratorBase::ConvertTypeToString(const BaseType& type,
 }
 
 std::string CppGeneratorBase::GetReturnType(const BaseType& type) {
-  if (IsObject(type))
-    return "const " + ConvertTypeToString(type) + "&";
+  if (IsObject(type)) return "const " + ConvertTypeToString(type) + "&";
 
   return ConvertTypeToString(type);
 }
@@ -307,8 +238,7 @@ std::string CppGeneratorBase::GetParameterType(const BaseType& type) {
 std::string CppGeneratorBase::GetParameters(const Parameters& params) {
   std::string code;
   for (const auto& param : params) {
-    if (!code.empty())
-      code += ", ";
+    if (!code.empty()) code += ", ";
 
     std::string ref;
     auto direction = param->GetParameterType().GetDirection();
@@ -316,8 +246,8 @@ std::string CppGeneratorBase::GetParameters(const Parameters& params) {
         direction == ParameterType::Direction::REF)
       ref = "&";
 
-    code += ConvertTypeToString(param->GetParameterType().GetBaseType()) +
-        ref + " " + param->GetID();
+    code += ConvertTypeToString(param->GetParameterType().GetBaseType()) + ref +
+            " " + param->GetID();
   }
 
   return code;
@@ -325,11 +255,9 @@ std::string CppGeneratorBase::GetParameters(const Parameters& params) {
 
 std::string CppGeneratorBase::GenParameters(const Structure& st) {
   std::string params;
-  if (st.GetBase() != nullptr)
-    params += GenParameters(*st.GetBase());
+  if (st.GetBase() != nullptr) params += GenParameters(*st.GetBase());
 
-  if (!params.empty())
-    params += ", ";
+  if (!params.empty()) params += ", ";
 
   return params + GenParameters(st.GetElements());
 }
@@ -342,8 +270,7 @@ std::string CppGeneratorBase::GenStructuresForHeader(bool use_file) {
     code += NLine(1);
   }
   for (auto& block : GetDocument().GetBlocks()) {
-    if (block->GetType() != Block::TYPE_STRUCTURE)
-      continue;
+    if (block->GetType() != Block::TYPE_STRUCTURE) continue;
 
     auto& st = static_cast<Structure&>(*block);
     code += GenStructureForHeader(st) + NLine(1);
@@ -358,34 +285,34 @@ std::string CppGeneratorBase::GenStructureForHeader(const Structure& st) {
   if (params.empty()) {
     if (st.GetBase() == nullptr) {
       code = ReplaceAll(CB_HEADER_STRUCTURE_BASE_EMPTY)
-                 .Change("<CLS_NAME>", st.GetID())
-                 .Change("<ENUMS>\n", GenEnumerations(st.GetEnums()));
+                 .Replace("CLS_NAME", st.GetID())
+                 .Replace("ENUMS", GenEnumerations(st.GetEnums()));
     } else {
       code = ReplaceAll(CB_HEADER_INHERITED_STRUCTURE_BASE_EMPTY)
-                 .Change("<CLS_NAME>", st.GetID())
-                 .Change("<BASE_CLS_NAME>", st.GetBase()->GetID())
-                 .Change("<ENUMS>\n", GenEnumerations(st.GetEnums()));
+                 .Replace("CLS_NAME", st.GetID())
+                 .Replace("BASE_CLS_NAME", st.GetBase()->GetID())
+                 .Replace("ENUMS", GenEnumerations(st.GetEnums()));
     }
   } else {
     if (st.GetBase() == nullptr) {
       code = ReplaceAll(CB_HEADER_STRUCTURE_BASE)
-                 .Change("<CLS_NAME>", st.GetID())
-                 .Change("<PARAMS>", GenParameters(st.GetElements()))
-                 .Change("<ENUMS>\n", GenEnumerations(st.GetEnums()))
-                 .Change("<GETTER_SETTER>",
-                         GenStructureGetterSetterForHeader(st.GetElements()))
-                 .Change("<MEMBERS>\n",
-                         GenStructureMembersForHeader(st.GetElements()));
+                 .Replace("CLS_NAME", st.GetID())
+                 .Replace("PARAMS", GenParameters(st.GetElements()))
+                 .Replace("ENUMS", GenEnumerations(st.GetEnums()))
+                 .Replace("GETTER_SETTER",
+                          GenStructureGetterSetterForHeader(st.GetElements()))
+                 .Replace("MEMBERS",
+                          GenStructureMembersForHeader(st.GetElements()));
     } else {
       code = ReplaceAll(CB_HEADER_INHERITED_STRUCTURE_BASE)
-                 .Change("<CLS_NAME>", st.GetID())
-                 .Change("<BASE_CLS_NAME>", st.GetBase()->GetID())
-                 .Change("<PARAMS>", params)
-                 .Change("<ENUMS>\n", GenEnumerations(st.GetEnums()))
-                 .Change("<GETTER_SETTER>",
-                         GenStructureGetterSetterForHeader(st.GetElements()))
-                 .Change("<MEMBERS>\n",
-                         GenStructureMembersForHeader(st.GetElements()));
+                 .Replace("CLS_NAME", st.GetID())
+                 .Replace("BASE_CLS_NAME", st.GetBase()->GetID())
+                 .Replace("PARAMS", params)
+                 .Replace("ENUMS", GenEnumerations(st.GetEnums()))
+                 .Replace("GETTER_SETTER",
+                          GenStructureGetterSetterForHeader(st.GetElements()))
+                 .Replace("MEMBERS",
+                          GenStructureMembersForHeader(st.GetElements()));
     }
   }
 
@@ -398,10 +325,10 @@ std::string CppGeneratorBase::GenStructureGetterSetterForHeader(
   for (auto& elm : elms) {
     code += Tab(1);
     code += ReplaceAll(CB_HEADER_STRUCTURE_GETTER_SETTER)
-                .Change("<RETURN_TYPE>", GetReturnType(elm->GetType()))
-                .Change("<NAME>", elm->GetID())
-                .Change("<PARAM_TYPE>", GetParameterType(elm->GetType()))
-                .Change("<PARAM_NAME>", elm->GetID());
+                .Replace("RETURN_TYPE", GetReturnType(elm->GetType()))
+                .Replace("NAME", elm->GetID())
+                .Replace("PARAM_TYPE", GetParameterType(elm->GetType()))
+                .Replace("PARAM_NAME", elm->GetID());
   }
 
   return code;
@@ -413,8 +340,8 @@ std::string CppGeneratorBase::GenStructureMembersForHeader(
   for (auto& elm : elms) {
     code += Tab(1);
     code += ReplaceAll(CB_HEADER_STRUCTURE_MEMBER)
-                .Change("<TYPE>", ConvertTypeToString(elm->GetType()))
-                .Change("<NAME>", elm->GetID());
+                .Replace("TYPE", ConvertTypeToString(elm->GetType()))
+                .Replace("NAME", elm->GetID());
     code += NLine(1);
   }
 
@@ -444,8 +371,7 @@ std::string CppGeneratorBase::SmartIndent(const std::string& str) {
       continue;
     }
 
-    if (trimmed_line.find("class") != std::string::npos)
-      inside_class++;
+    if (trimmed_line.find("class") != std::string::npos) inside_class++;
 
     if (previous_line.find("if (") != std::string::npos ||
         previous_line.find("for (") != std::string::npos ||
@@ -465,8 +391,7 @@ std::string CppGeneratorBase::SmartIndent(const std::string& str) {
       }
 
       code += indentation + trimmed_line + NLine(1);
-      if (else_statement)
-        indentation += Tab(1);
+      if (else_statement) indentation += Tab(1);
 
       if (trimmed_line.find("namespace ") == std::string::npos &&
           trimmed_line.find('}') == std::string::npos)
@@ -476,14 +401,12 @@ std::string CppGeneratorBase::SmartIndent(const std::string& str) {
       continue;
     }
 
-    if (control_flow_statement_with_single_line)
-      indentation += Tab(1);
+    if (control_flow_statement_with_single_line) indentation += Tab(1);
 
     if (trimmed_line.find('}') != std::string::npos)
       indentation = indentation.substr(0, indentation.length() - 2);
 
-    if (trimmed_line.find("};") != std::string::npos)
-      inside_class--;
+    if (trimmed_line.find("};") != std::string::npos) inside_class--;
 
     if (inside_class != 0 &&
         (trimmed_line.find("public:") != std::string::npos ||
@@ -491,10 +414,11 @@ std::string CppGeneratorBase::SmartIndent(const std::string& str) {
          trimmed_line.find("protected:") != std::string::npos))
       is_access_modifier = true;
 
-    code += (is_access_modifier ?
-        indentation.substr(0, indentation.length() - 1) : indentation) +
+    code +=
+        (is_access_modifier ? indentation.substr(0, indentation.length() - 1)
+                            : indentation) +
         trimmed_line + NLine(1);
-    is_access_modifier  = false;
+    is_access_modifier = false;
     if (control_flow_statement_with_single_line) {
       indentation = indentation.substr(0, indentation.length() - 2);
       control_flow_statement_with_single_line = false;
@@ -512,8 +436,7 @@ std::string CppGeneratorBase::Trim(std::string str) {
     return str;
 
   auto first = str.find_first_not_of(" \t\r\n");
-  if (first == std::string::npos)
-    return "";
+  if (first == std::string::npos) return "";
 
   auto last = str.find_last_not_of(" \t\r\n");
   return str.substr(first, (last - first + 1));
@@ -521,8 +444,7 @@ std::string CppGeneratorBase::Trim(std::string str) {
 
 std::string CppGeneratorBase::GenStructures(bool use_file) {
   std::string code(CB_BODY_BUNDLE);
-  if (use_file)
-    code += CB_BODY_FILE;
+  if (use_file) code += CB_BODY_FILE;
 
   for (auto& block : GetDocument().GetBlocks()) {
     if (block->GetType() == Block::Type::TYPE_STRUCTURE) {
@@ -539,24 +461,24 @@ std::string CppGeneratorBase::GenStructure(const Structure& st) {
   std::string code;
   if (params.empty()) {
     code = ReplaceAll(CB_BODY_STRUCTURE_BASE_EMPTY)
-               .Change("<CLS_NAME>", st.GetID());
+               .Replace("CLS_NAME", st.GetID());
   } else {
     if (st.GetBase() == nullptr) {
       code =
           ReplaceAll(CB_BODY_STRUCTURE_BASE)
-              .Change("<CLS_NAME>", st.GetID())
-              .Change("<PARAMS>", params)
-              .Change("<MEMBER_INIT>", GenStructureMemberInit(st.GetElements()))
-              .Change("<GETTER_SETTER>", GenStructureGetterSetter(st));
+              .Replace("CLS_NAME", st.GetID())
+              .Replace("PARAMS", params)
+              .Replace("MEMBER_INIT", GenStructureMemberInit(st.GetElements()))
+              .Replace("GETTER_SETTER", GenStructureGetterSetter(st));
     } else {
       code =
           ReplaceAll(CB_BODY_INHERITED_STRUCTURE_BASE)
-              .Change("<CLS_NAME>", st.GetID())
-              .Change("<BASE_CLS_NAME>", st.GetBase()->GetID())
-              .Change("<BASE_ARGS>", GenStructureBaseArgs(*st.GetBase()))
-              .Change("<PARAMS>", params)
-              .Change("<MEMBER_INIT>", GenStructureMemberInit(st.GetElements()))
-              .Change("<GETTER_SETTER>", GenStructureGetterSetter(st));
+              .Replace("CLS_NAME", st.GetID())
+              .Replace("BASE_CLS_NAME", st.GetBase()->GetID())
+              .Replace("BASE_ARGS", GenStructureBaseArgs(*st.GetBase()))
+              .Replace("PARAMS", params)
+              .Replace("MEMBER_INIT", GenStructureMemberInit(st.GetElements()))
+              .Replace("GETTER_SETTER", GenStructureGetterSetter(st));
     }
   }
 
@@ -565,11 +487,9 @@ std::string CppGeneratorBase::GenStructure(const Structure& st) {
 
 std::string CppGeneratorBase::GenStructureBaseArgs(const Structure& st) {
   std::string code;
-  if (st.GetBase() != nullptr)
-    code += GenStructureBaseArgs(*st.GetBase());
+  if (st.GetBase() != nullptr) code += GenStructureBaseArgs(*st.GetBase());
 
-  if (!code.empty())
-    code += ", ";
+  if (!code.empty()) code += ", ";
 
   return code + GenStructureBaseArgs(st.GetElements());
 }
@@ -577,8 +497,7 @@ std::string CppGeneratorBase::GenStructureBaseArgs(const Structure& st) {
 std::string CppGeneratorBase::GenStructureBaseArgs(const Elements& elms) {
   std::string code;
   for (auto& elm : elms) {
-    if (!code.empty())
-      code += ", ";
+    if (!code.empty()) code += ", ";
 
     code += GetSetterValue(elm->GetType(), elm->GetID());
   }
@@ -589,12 +508,11 @@ std::string CppGeneratorBase::GenStructureBaseArgs(const Elements& elms) {
 std::string CppGeneratorBase::GenStructureMemberInit(const Elements& elms) {
   std::string code;
   for (auto& elm : elms) {
-    if (!code.empty())
-      code += ", ";
+    if (!code.empty()) code += ", ";
 
     code += ReplaceAll(CB_BODY_STRUCTURE_MEMBER_INIT)
-        .Change("<NAME>", elm->GetID())
-        .Change("<VALUE>", GetSetterValue(elm->GetType(), elm->GetID()));
+                .Replace("NAME", elm->GetID())
+                .Replace("VALUE", GetSetterValue(elm->GetType(), elm->GetID()));
   }
 
   return code;
@@ -604,31 +522,31 @@ std::string CppGeneratorBase::GenStructureGetterSetter(const Structure& st) {
   std::string code;
   for (auto& elm : st.GetElements()) {
     code += ReplaceAll(CB_BODY_STRUCTURE_GETTER_SETTER)
-        .Change("<RETURN_TYPE>", GetReturnType(elm->GetType()))
-        .Change("<CLS_NAME>", st.GetID())
-        .Change("<NAME>", elm->GetID())
-        .Change("<PARAM_TYPE>", GetParameterType(elm->GetType()))
-        .Change("<PARAM_NAME>", elm->GetID())
-        .Change("<VALUE>", GetSetterValue(elm->GetType(), elm->GetID()));
+                .Replace("RETURN_TYPE", GetReturnType(elm->GetType()))
+                .Replace("CLS_NAME", st.GetID())
+                .Replace("NAME", elm->GetID())
+                .Replace("PARAM_TYPE", GetParameterType(elm->GetType()))
+                .Replace("PARAM_NAME", elm->GetID())
+                .Replace("VALUE", GetSetterValue(elm->GetType(), elm->GetID()));
   }
 
   return RemoveLine(code);
 }
 
 std::string CppGeneratorBase::GetSetterValue(const BaseType& type,
-    const std::string& value) {
+                                             const std::string& value) {
   return IsObject(type) ? "std::move(" + value + ")" : value;
 }
 
-void CppGeneratorBase::InitUnitTypes(bool use_file) {
+void CppGeneratorBase::InitUnitTypes(bool use_file, bool is_group) {
   AddUnitType("int", BaseType("int", ""), "");
   AddUnitType("bool", BaseType("bool", ""), "");
   AddUnitType("string", BaseType("string", ""), "");
   AddUnitType("bundle", BaseType("bundle", ""), "");
-  if (use_file)
-    AddUnitType("file", BaseType("file", ""), "");
+  if (use_file) AddUnitType("file", BaseType("file", ""), "");
 
-  AddUnitType("remote_exception", BaseType("remote_exception", "", true), "");
+  if (!is_group)
+    AddUnitType("remote_exception", BaseType("remote_exception", "", true), "");
 
   for (auto& block : GetDocument().GetBlocks()) {
     if (block->GetType() == Block::TYPE_INTERFACE) {
@@ -640,9 +558,12 @@ void CppGeneratorBase::InitUnitTypes(bool use_file) {
       }
 
       for (const auto& decl : iface.GetDeclarations()) {
-        AddUnitType(iface.GetID() + "::CallbackBase",
-                    BaseType(iface.GetID() + "::CallbackBase", "", true),
-                    iface.GetID());
+        if (!is_group) {
+          AddUnitType(iface.GetID() + "::CallbackBase",
+                      BaseType(iface.GetID() + "::CallbackBase", "", true),
+                      iface.GetID());
+        }
+
         if (decl->GetMethodType() == Declaration::MethodType::DELEGATE) {
           AddUnitType(decl->GetID(), BaseType(decl->GetID(), "", true),
                       iface.GetID());
@@ -715,7 +636,7 @@ std::string CppGeneratorBase::GetUnitTypeKey(std::string name,
 }
 
 void CppGeneratorBase::AddUnitType(std::string name, BaseType type,
-    const std::string& block_id) {
+                                   const std::string& block_id) {
   if (type.GetMetaType() != nullptr) {
     auto meta_type = type.GetMetaType();
     if (!meta_type->IsEnumType()) {
@@ -742,22 +663,30 @@ void CppGeneratorBase::AddUnitType(std::string name, BaseType type,
   unit_types_[std::move(name)] = std::move(type);
 }
 
-std::string CppGeneratorBase::GenUnitMap(bool use_file) {
-  InitUnitTypes(use_file);
+std::string CppGeneratorBase::GenUnitMap(bool use_file, bool is_group) {
+  InitUnitTypes(use_file, is_group);
   std::string code = GenUnit();
-  code += ReplaceAll(CB_UNIT_MAP)
-      .Change("<UNIT_MAP_READ_WRITE>", GenUnitMapReadWrite());
+  code +=
+      ReplaceAll(CB_UNIT_MAP)
+          .Repeat("UNIT_MAP_READ_WRITE", unit_types_,
+                  [&](auto& r, const auto& i) {
+                    auto& param_type = i.second;
+                    r.Replace("TYPE", std::to_string(GetHashCode(
+                                          GetFullNameFromType(param_type))))
+                        .Replace("TYPE_STR", GetFullNameFromType(param_type))
+                        .Replace("PARAM_TYPE",
+                                 ConvertTypeToString(param_type, true));
+                    return true;
+                  });
   code += GenUnitSerializerBodies();
   return code;
 }
 
 std::string CppGeneratorBase::GetFullNameFromType(const BaseType& type) {
   auto found = struct_types_.find(type.GetFullName(true));
-  if (found != struct_types_.end())
-    return found->second;
+  if (found != struct_types_.end()) return found->second;
 
-  if (type.IsEnumType())
-    return "int";
+  if (type.IsEnumType()) return "int";
 
   if (IsDelegateType(type) ||
       type.ToString().find("::CallbackBase") != std::string::npos)
@@ -767,22 +696,9 @@ std::string CppGeneratorBase::GetFullNameFromType(const BaseType& type) {
   return GetEnumTypeString(name, true);
 }
 
-std::string CppGeneratorBase::GenUnitMapReadWrite() {
-  std::string code;
-  for (auto& iter : unit_types_) {
-    auto& param_type = iter.second;
-    code += ReplaceAll(CB_UNIT_MAP_READ_WRITE)
-        .Change("<TYPE>", GetFullNameFromType(param_type))
-        .Change("<PARAM_TYPE>", ConvertTypeToString(param_type, true));
-  }
-
-  return RemoveLine(code);
-}
-
 std::string CppGeneratorBase::GenUnit() {
   return std::string(
-      ReplaceAll(CB_UNIT)
-          .Change("<SERIALIZER>", GenUnitSerializerHeaders()));
+      ReplaceAll(CB_UNIT).Replace("SERIALIZER", GenUnitSerializerHeaders()));
 }
 
 std::string CppGeneratorBase::GenUnitSerializerHeaders() {
@@ -790,7 +706,7 @@ std::string CppGeneratorBase::GenUnitSerializerHeaders() {
   for (auto& iter : unit_types_) {
     auto& type = iter.second;
     code += ReplaceAll(CB_UNIT_SERIALIZER_HEADER)
-        .Change("<TYPE>", ConvertTypeToString(type, true));
+                .Replace("TYPE", ConvertTypeToString(type, true));
   }
 
   return code;
@@ -801,25 +717,36 @@ std::string CppGeneratorBase::GenUnitSerializerBodies() {
   for (auto& iter : unit_types_) {
     auto& type = iter.second;
     code += ReplaceAll(CB_UNIT_SERIALIZER_BODY)
-        .Change("<TYPE>", ConvertTypeToString(type, true))
-        .Change("<IMPL_SERIALIZER>\n", GenUnitImplSerializer(type))
-        .Change("<IMPL_DESERIALIZER>\n", GenUnitImplDeserializer(type));
+                .Replace("TAG", GenCaptureTag(type))
+                .Replace("TYPE", ConvertTypeToString(type, true))
+                .Replace("IMPL_SERIALIZER", GenUnitImplSerializer(type))
+                .Replace("IMPL_DESERIALIZER", GenUnitImplDeserializer(type));
   }
 
   return code;
 }
 
+std::string CppGeneratorBase::GenCaptureTag(const BaseType& type) {
+  if (type.ToString() == "int" || type.ToString() == "bool" ||
+      type.ToString() == "float" || type.ToString() == "double" ||
+      type.ToString() == "char" || type.ToString() == "short" ||
+      type.ToString() == "long")
+    return "";
+
+  return "&";
+}
+
 std::string CppGeneratorBase::GenUnitImplSerializer(const BaseType& type) {
   std::string code;
   if (type.IsEnumType()) {
     code = CB_UNIT_IMPL_SERIALIZER_ENUM;
   } else if (type.IsUserDefinedType() || type.GetMetaType() != nullptr ||
-      type.GetKeyType() != nullptr) {
+             type.GetKeyType() != nullptr) {
     if (IsDelegateType(type)) {
       code = CB_UNIT_IMPL_SERIALIZER_DELEGATE;
     } else {
       code = ReplaceAll(CB_UNIT_IMPL_SERIALIZER_USER_DEFINED)
-          .Change("<UNIT_MAP_WRITE>", GenUnitMapWrite(type));
+                 .Replace("UNIT_MAP_WRITE", GenUnitMapWrite(type));
     }
   } else if (type.ToString() == "string") {
     code = CB_UNIT_IMPL_SERIALIZER_STRING;
@@ -829,7 +756,7 @@ std::string CppGeneratorBase::GenUnitImplSerializer(const BaseType& type) {
     code = CB_UNIT_IMPL_SERIALIZER_FILE;
   } else {
     code = ReplaceAll(CB_UNIT_IMPL_SERIALIZER_BASE)
-        .Change("<PARCEL_TYPE>", GetParcelType(type));
+               .Replace("PARCEL_TYPE", GetParcelType(type));
   }
 
   return RemoveLine(code);
@@ -837,11 +764,10 @@ std::string CppGeneratorBase::GenUnitImplSerializer(const BaseType& type) {
 
 std::string CppGeneratorBase::GenUnitMapBaseWrite(const Structure& st) {
   std::string code;
-  if (st.GetBase() != nullptr)
-    code += GenUnitMapBaseWrite(*st.GetBase());
+  if (st.GetBase() != nullptr) code += GenUnitMapBaseWrite(*st.GetBase());
 
   for (auto& elm : st.GetElements())
-    code += ReplaceAll(CB_UNIT_MAP_BASE_WRITE).Change("<NAME>", elm->GetID());
+    code += ReplaceAll(CB_UNIT_MAP_BASE_WRITE).Replace("NAME", elm->GetID());
 
   return code;
 }
@@ -853,7 +779,17 @@ std::string CppGeneratorBase::GenUnitMapWrite(const BaseType& type) {
   } else if (type.ToString() == "remote_exception") {
     code = CB_UNIT_MAP_REMOTE_EXCEPTION_WRITE;
   } else if (type.ToString() == "array") {
-    code = CB_UNIT_MAP_ARRAY_WRITE;
+    if (type.GetFullName() == "array<char>" ||
+        type.GetFullName() == "array<bool>" ||
+        type.GetFullName() == "array<int>" ||
+        type.GetFullName() == "array<short>" ||
+        type.GetFullName() == "array<long>" ||
+        type.GetFullName() == "array<double>" ||
+        type.GetFullName() == "array<float>") {
+      code = CB_UNIT_MAP_ARRAY_WRITE_OPT;
+    } else {
+      code = CB_UNIT_MAP_ARRAY_WRITE;
+    }
   } else if (type.ToString() == "list") {
     code = CB_UNIT_MAP_LIST_WRITE;
   } else if (type.ToString() == "map") {
@@ -863,11 +799,11 @@ std::string CppGeneratorBase::GenUnitMapWrite(const BaseType& type) {
   } else {
     for (auto& block : GetDocument().GetBlocks()) {
       if (block->GetType() == Block::TYPE_STRUCTURE) {
-         auto& st = static_cast<const Structure&>(*block);
-         if (st.GetID() == type.ToString()) {
+        auto& st = static_cast<const Structure&>(*block);
+        if (st.GetID() == type.ToString()) {
           code = GenUnitMapBaseWrite(st);
           break;
-         }
+        }
       }
     }
   }
@@ -879,15 +815,15 @@ std::string CppGeneratorBase::GenUnitImplDeserializer(const BaseType& type) {
   std::string code;
   if (type.IsEnumType()) {
     code = ReplaceAll(CB_UNIT_IMPL_DESERIALIZER_ENUM)
-        .Change("<TYPE>", ConvertTypeToString(type));
+               .Replace("TYPE", ConvertTypeToString(type));
   } else if (type.IsUserDefinedType() || type.GetMetaType() != nullptr ||
-      type.GetKeyType() != nullptr) {
+             type.GetKeyType() != nullptr) {
     if (IsDelegateType(type)) {
       code = ReplaceAll(CB_UNIT_IMPL_DESERIALIZER_DELEGATE)
-          .Change("<IFACE_NAME>", GetInterfaceNameFromDelegate(type));
+                 .Replace("IFACE_NAME", GetInterfaceNameFromDelegate(type));
     } else {
       code = ReplaceAll(CB_UNIT_IMPL_DESERIALIZER_USER_DEFINED)
-          .Change("<UNIT_MAP_READ>\n", GenUnitMapRead(type));
+                 .Replace("UNIT_MAP_READ", GenUnitMapRead(type));
     }
   } else if (type.ToString() == "string") {
     code = CB_UNIT_IMPL_DESERIALIZER_STRING;
@@ -897,9 +833,9 @@ std::string CppGeneratorBase::GenUnitImplDeserializer(const BaseType& type) {
     code = CB_UNIT_IMPL_DESERIALIZER_FILE;
   } else {
     code = ReplaceAll(CB_UNIT_IMPL_DESERIALIZER_BASE)
-        .Change("<TYPE>", ConvertTypeToString(type))
-        .Change("<PARCEL_TYPE>", GetParcelType(type))
-        .Change("<SET_INIT_VALUE>", GetSettingInitValue(type));
+               .Replace("TYPE", ConvertTypeToString(type))
+               .Replace("PARCEL_TYPE", GetParcelType(type))
+               .Replace("SET_INIT_VALUE", GetSettingInitValue(type));
   }
 
   return RemoveLine(code);
@@ -907,14 +843,13 @@ std::string CppGeneratorBase::GenUnitImplDeserializer(const BaseType& type) {
 
 std::string CppGeneratorBase::GenUnitMapBaseRead(const Structure& st) {
   std::string code;
-  if (st.GetBase() != nullptr)
-    code += GenUnitMapBaseRead(*st.GetBase());
+  if (st.GetBase() != nullptr) code += GenUnitMapBaseRead(*st.GetBase());
 
   for (auto& elm : st.GetElements()) {
     code += ReplaceAll(CB_UNIT_MAP_BASE_READ)
-        .Change("<TYPE>", ConvertTypeToString(elm->GetType()))
-        .Change("<NAME>", elm->GetID())
-        .Change("<SET_INIT_VALUE>", GetSettingInitValue(elm->GetType()));
+                .Replace("TYPE", ConvertTypeToString(elm->GetType()))
+                .Replace("NAME", elm->GetID())
+                .Replace("SET_INIT_VALUE", GetSettingInitValue(elm->GetType()));
   }
 
   return code;
@@ -927,20 +862,33 @@ std::string CppGeneratorBase::GenUnitMapRead(const BaseType& type) {
   } else if (type.ToString() == "remote_exception") {
     code = CB_UNIT_MAP_REMOTE_EXCEPTION_READ;
   } else if (type.ToString() == "array") {
-    code = ReplaceAll(CB_UNIT_MAP_ARRAY_READ)
-        .Change("<TYPE>", ConvertTypeToString(*type.GetMetaType()))
-        .Change("<SET_INIT_VALUE>", GetSettingInitValue(*type.GetMetaType()));
+    if (type.GetFullName() == "array<char>" ||
+        type.GetFullName() == "array<bool>" ||
+        type.GetFullName() == "array<int>" ||
+        type.GetFullName() == "array<short>" ||
+        type.GetFullName() == "array<long>" ||
+        type.GetFullName() == "array<double>" ||
+        type.GetFullName() == "array<float>") {
+      code = CB_UNIT_MAP_ARRAY_READ_OPT;
+    } else {
+      code = ReplaceAll(CB_UNIT_MAP_ARRAY_READ)
+                 .Replace("TYPE", ConvertTypeToString(*type.GetMetaType()))
+                 .Replace("SET_INIT_VALUE",
+                          GetSettingInitValue(*type.GetMetaType()));
+    }
   } else if (type.ToString() == "list") {
     code = ReplaceAll(CB_UNIT_MAP_LIST_READ)
-        .Change("<TYPE>", ConvertTypeToString(*type.GetMetaType()))
-        .Change("<SET_INIT_VALUE>", GetSettingInitValue(*type.GetMetaType()));
+               .Replace("TYPE", ConvertTypeToString(*type.GetMetaType()))
+               .Replace("SET_INIT_VALUE",
+                        GetSettingInitValue(*type.GetMetaType()));
   } else if (type.ToString() == "map") {
-    code = ReplaceAll(CB_UNIT_MAP_MAP_READ)
-        .Change("<KEY_TYPE>", ConvertTypeToString(*type.GetKeyType()))
-        .Change("<VALUE_TYPE>", ConvertTypeToString(*type.GetValueType()));
+    code =
+        ReplaceAll(CB_UNIT_MAP_MAP_READ)
+            .Replace("KEY_TYPE", ConvertTypeToString(*type.GetKeyType()))
+            .Replace("VALUE_TYPE", ConvertTypeToString(*type.GetValueType()));
   } else if (type.ToString() == "set") {
     code = ReplaceAll(CB_UNIT_MAP_SET_READ)
-        .Change("<KEY_TYPE>", ConvertTypeToString(*type.GetMetaType()));
+               .Replace("KEY_TYPE", ConvertTypeToString(*type.GetMetaType()));
   } else {
     for (auto& block : GetDocument().GetBlocks()) {
       if (block->GetType() == Block::TYPE_STRUCTURE) {
@@ -957,8 +905,7 @@ std::string CppGeneratorBase::GenUnitMapRead(const BaseType& type) {
 }
 
 std::string CppGeneratorBase::GetParcelType(const BaseType& type) {
-  if (type.IsEnumType())
-    return "int32";
+  if (type.IsEnumType()) return "int32";
 
   return parcel_type_map_[type.ToString()];
 }
@@ -968,11 +915,10 @@ std::string CppGeneratorBase::GenPrivateSharing(const Parameter& param) {
   auto& type = param.GetParameterType().GetBaseType();
   if (BaseType::IsFile(&type)) {
     if (type.GetMetaType() != nullptr) {
-      code = ReplaceAll(CB_PRIVATE_SHARING_ARRAY)
-          .Change("<NAME>", param.GetID());
+      code =
+          ReplaceAll(CB_PRIVATE_SHARING_ARRAY).Replace("NAME", param.GetID());
     } else {
-      code = ReplaceAll(CB_PRIVATE_SHARING)
-          .Change("<NAME>", param.GetID());
+      code = ReplaceAll(CB_PRIVATE_SHARING).Replace("NAME", param.GetID());
     }
   }
 
@@ -981,19 +927,17 @@ std::string CppGeneratorBase::GenPrivateSharing(const Parameter& param) {
 
 std::string CppGeneratorBase::GetSettingInitValue(const BaseType& type) {
   auto found = type_init_map_.find(type.ToString());
-  if (found == type_init_map_.end())
-    return {};
+  if (found == type_init_map_.end()) return {};
 
   std::string code = " = " + found->second;
   return code;
 }
 
 std::string CppGeneratorBase::GetClassNameFromEnumType(
-  const std::string& type) {
+    const std::string& type) {
   for (auto& block : GetDocument().GetBlocks()) {
     for (const auto& e : block->GetEnums()) {
-      if (e->GetID() == type)
-        return block->GetID();
+      if (e->GetID() == type) return block->GetID();
     }
   }
 
@@ -1001,13 +945,12 @@ std::string CppGeneratorBase::GetClassNameFromEnumType(
 }
 
 std::string CppGeneratorBase::GetEnumTypeString(const std::string& type,
-    bool use_underbar) {
+                                                bool use_underbar) {
   std::string concatenated_char = use_underbar ? "_" : "::";
   auto pos = type.find('.');
   if (pos == std::string::npos) {
     std::string cls_name = GetClassNameFromEnumType(type);
-    if (!cls_name.empty())
-      return cls_name + concatenated_char + type;
+    if (!cls_name.empty()) return cls_name + concatenated_char + type;
 
     return type;
   }
@@ -1029,8 +972,8 @@ std::string CppGeneratorBase::GenEnumerations(const Enums& enums) {
     }
 
     code += ReplaceAll(CB_ENUM_BASE)
-        .Change("<NAME>", e->GetID())
-        .Change("<ENUMS>", enum_fields);
+                .Replace("NAME", e->GetID())
+                .Replace("ENUMS", enum_fields);
     code += NLine(1);
   }
 
@@ -1045,5 +988,9 @@ std::string CppGeneratorBase::GenRemoteExceptionForHeader() {
   return std::string(CB_HEADER_REMOTE_EXCEPTION);
 }
 
+std::string CppGeneratorBase::GenRpcPortInternals() {
+  return std::string(CB_RPC_PORT_INTERNAL_APIS);
+}
+
 }  // namespace version2
 }  // namespace tidl
index 4f5677a9d9febef7866a11ffcb0ab815b87f3021..01b3b37072e5bcb209edaf8499feab4ad7fc333b 100644 (file)
@@ -34,13 +34,7 @@ class CppGeneratorBase : public tidl::Generator {
                             bool thread_enabled = false);
   virtual ~CppGeneratorBase() = default;
 
-  void GenVersion(std::ofstream& stream);
-  void GenIncludeDefaultHeaders(std::ofstream& stream, bool is_body = true);
-  void GenLogTag(std::ofstream& stream, const std::string& log_tag);
-  void GenLogDefinition(std::ofstream& stream);
-  void GenVersionDefinition(std::ofstream& stream);
-  void GenExportAPI(std::ofstream& stream);
-
+  std::string GenIncludeDefaultHeaders(bool is_body = true);
   std::string GenExceptions();
   std::string GenStructuresForHeader(bool use_file = true);
   std::string GenMethodIds(const Interface& iface);
@@ -58,12 +52,13 @@ class CppGeneratorBase : public tidl::Generator {
   std::string SmartIndent(const std::string& str);
   std::string GenStructures(bool use_file = true);
   std::string GetSetterValue(const BaseType& type, const std::string& value);
-  std::string GenUnitMap(bool use_file = true);
+  std::string GenUnitMap(bool use_file = true, bool is_group = false);
   std::string GenPrivateSharing(const Parameter& param);
   std::string GetSettingInitValue(const BaseType& type);
   std::string GenEnumerations(const Enums& enums);
   std::string GenRemoteException();
   std::string GenRemoteExceptionForHeader();
+  std::string GenRpcPortInternals();
 
  private:
   void AddTypeName(const Structure& st);
@@ -76,12 +71,11 @@ class CppGeneratorBase : public tidl::Generator {
   std::string GenStructureBaseArgs(const Elements& elms);
   std::string GenStructureMemberInit(const Elements& elms);
   std::string GenStructureGetterSetter(const Structure& st);
-  void InitUnitTypes(bool use_file);
+  void InitUnitTypes(bool use_file, bool is_group);
   std::string GetUnitTypeKey(std::string name, const BaseType& type,
                              const std::string& block_id);
   void AddUnitType(std::string name, BaseType type,
                    const std::string& block_id);
-  std::string GenUnitMapReadWrite();
   std::string GenUnit();
   std::string GenUnitSerializerHeaders();
   std::string GenUnitSerializerBodies();
@@ -96,6 +90,7 @@ class CppGeneratorBase : public tidl::Generator {
   std::string GetClassNameFromEnumType(const std::string& type);
   std::string GetEnumTypeString(const std::string& type,
                                 bool use_underbar = false);
+  std::string GenCaptureTag(const BaseType& type);
 
  private:
   bool thread_enabled_;
index a8c753c42219fffe8a5d553609a0b93ef45a8193..f36ae065567ca79532e105fc4346bd2864675b36 100644 (file)
@@ -76,36 +76,6 @@ R"__cpp_cb(
 #include <queue>
 )__cpp_cb";
 
-/**
- * <LOG_TAG> The log tag of dlog.
- */
-constexpr const char CB_LOG_TAG[] =
-R"__cpp_cb(
-#undef LOG_TAG
-#define LOG_TAG "<LOG_TAG>"
-)__cpp_cb";
-
-constexpr const char CB_LOG_DEF[] =
-R"__cpp_cb(
-#undef _E
-#define _E(fmt, ...) dlog_print(DLOG_ERROR, LOG_TAG, "%s: %s(%d) > " fmt, basename(const_cast<char*>(__FILE__)), __FUNCTION__, __LINE__, ##__VA_ARGS__)
-
-#undef _W
-#define _W(fmt, ...) dlog_print(DLOG_WARN, LOG_TAG, "%s: %s(%d) > " fmt, basename(const_cast<char*>(__FILE__)), __FUNCTION__, __LINE__, ##__VA_ARGS__)
-
-#undef _I
-#define _I(fmt, ...) dlog_print(DLOG_INFO, LOG_TAG, "%s: %s(%d) > " fmt, basename(const_cast<char*>(__FILE__)), __FUNCTION__, __LINE__, ##__VA_ARGS__)
-
-#undef _D
-#define _D(fmt, ...) dlog_print(DLOG_DEBUG, LOG_TAG, "%s: %s(%d) > " fmt, basename(const_cast<char*>(__FILE__)), __FUNCTION__, __LINE__, ##__VA_ARGS__)
-)__cpp_cb";
-
-constexpr const char CB_TIDL_VERSION[] =
-R"__cpp_cb(
-#undef TIDL_VERSION
-#define TIDL_VERSION "<VERSION>"
-)__cpp_cb";
-
 constexpr const char CB_EXCEPTIONS[] =
 R"__cpp_cb(
 class Exception {};
@@ -135,52 +105,6 @@ class RemoteException : public Exception {
 };
 )__cpp_cb";
 
-/**
- * <FILE_NAMESPACE> The namespace of the file.
- * <STRUCTURES> The definition of structures.
- * <BASE_IMPL> The definition of base implementation.
- * <INTERFACES> The definition of interfaces.
- */
-constexpr const char CB_NAMESPACE_PROXY[] =
-R"__cpp_cb(
-namespace rpc_port {
-namespace <FILE_NAMESPACE> {
-
-<STRUCTURES>
-
-namespace proxy {
-
-<BASE_IMPL>
-<INTERFACES>
-
-}  // namespace proxy
-}  // namespace <FILE_NAMESPACE>
-}  // namespace rpc_port
-)__cpp_cb";
-
-/**
- * <FILE_NAMESPACE> The namespace of the file.
- * <STRUCTURES> The definition of structures.
- * <BASE_IMPL> The base implementation.
- * <INTERFACES> The definition of interfaces.
- */
-constexpr const char CB_NAMESPACE_STUB[] =
-R"__cpp_cb(
-namespace rpc_port {
-namespace <FILE_NAMESPACE> {
-
-<STRUCTURES>
-
-namespace stub {
-
-<BASE_IMPL>
-<INTERFACES>
-
-}  // namespace stub
-}  // namespace <FILE_NAMESPACE>
-}  // namespace rpc_port
-)__cpp_cb";
-
 constexpr const char CB_HEADER_BUNDLE[] =
 R"__cpp_cb(
 class Bundle final {
@@ -353,24 +277,24 @@ R"__cpp_cb(
 Bundle::Bundle() {
   handle_ = bundle_create();
   if (handle_ == nullptr)
-    throw new std::bad_alloc();
+    throw std::bad_alloc();
 }
 
 Bundle::Bundle(bundle* handle, bool copy, bool own) : handle_(handle), own_(own) {
   if (handle == nullptr)
-    throw new std::invalid_argument("handle is nullptr");
+    throw std::invalid_argument("handle is nullptr");
 
   if (copy) {
     handle_ = bundle_dup(handle);
     if (handle_ == nullptr)
-      throw new std::bad_alloc();
+      throw std::bad_alloc();
   }
 }
 
 Bundle::Bundle(std::string raw) {
   handle_ = bundle_decode(reinterpret_cast<const bundle_raw*>(raw.c_str()), raw.length());
   if (handle_ == nullptr)
-    throw new std::bad_alloc();
+    throw std::bad_alloc();
 }
 
 Bundle::~Bundle() {
@@ -381,7 +305,7 @@ Bundle::~Bundle() {
 Bundle::Bundle(const Bundle& b) {
   handle_ = bundle_dup(b.handle_);
   if (handle_ == nullptr)
-    throw new std::bad_alloc();
+    throw std::bad_alloc();
 }
 
 Bundle& Bundle::operator = (const Bundle& b) {
@@ -391,7 +315,7 @@ Bundle& Bundle::operator = (const Bundle& b) {
 
     handle_ = bundle_dup(b.handle_);
     if (handle_ == nullptr)
-      throw new std::bad_alloc();
+      throw std::bad_alloc();
 
     own_ = true;
   }
@@ -529,87 +453,67 @@ constexpr const char CB_UNIT[] =
 R"__cpp_cb(
 class Unit {
  public:
-  Unit() {
-    rpc_port_parcel_create_without_header(&parcel_);
-  }
+  Unit() {}
 
-  Unit(std::string name, std::string type) : name_(std::move(name)), type_(std::move(type)) {
-    rpc_port_parcel_create_without_header(&parcel_);
-  }
+  Unit(int32_t name, int32_t type) : name_(name), type_(type) {}
 
-  ~Unit() {
-    if (parcel_ != nullptr)
-      rpc_port_parcel_destroy(parcel_);
-  }
+  const int32_t& GetName() const { return name_; }
 
-  const std::string& GetName() const {
-    return name_;
-  }
+  void SetName(int32_t name) { name_ = name; }
 
-  void SetName(std::string name) {
-    name_ = std::move(name);
-  }
+  const int32_t& GetType() const { return type_; }
 
-  const std::string& GetType() const {
-    return type_;
-  }
+  void SetType(int32_t type) { type_ = type; }
 
-  void SetType(std::string type) {
-    type_ = std::move(type);
-  }
+  void Serialize(rpc_port_parcel_h parcel) {
+    rpc_port_parcel_write_int32(parcel, name_);
+    rpc_port_parcel_write_int32(parcel, type_);
 
-  rpc_port_parcel_h GetParcel() const {
-    return parcel_;
-  }
+    unsigned int size_pos = 0;
+    rpc_port_parcel_get_data_size(parcel, &size_pos);
+    rpc_port_parcel_reserve(parcel, sizeof(unsigned int));
 
-  void Serialize(rpc_port_parcel_h parcel) const {
-    rpc_port_parcel_write_string(parcel, GetName().c_str());
-    rpc_port_parcel_write_string(parcel, GetType().c_str());
+    for (auto& i : cmds_) {
+      i(parcel);
+    }
 
-    void* raw = nullptr;
-    unsigned int size = 0;
-    rpc_port_parcel_get_raw(GetParcel(), &raw, &size);
-    rpc_port_parcel_write_array_count(parcel, size & INT_MAX);
-    rpc_port_parcel_burst_write(parcel, static_cast<unsigned char*>(raw), size);
+    unsigned int cur_pos;
+    rpc_port_parcel_get_data_size(parcel, &cur_pos);
+    size_t size = cur_pos - size_pos - sizeof(unsigned int);
+    rpc_port_parcel_set_data_size(parcel, size_pos);
+    rpc_port_parcel_write_int32(parcel, size);
+    rpc_port_parcel_set_data_size(parcel, cur_pos);
+    cmds_.clear();
   }
 
   void Deserialize(rpc_port_parcel_h parcel) {
-    char* name = nullptr;
-    rpc_port_parcel_read_string(parcel, &name);
-    if (name != nullptr) {
-      SetName(name);
-      free(name);
-    }
-
-    char* type = nullptr;
-    rpc_port_parcel_read_string(parcel, &type);
-    if (type != nullptr) {
-      SetType(type);
-      free(type);
-    }
+    rpc_port_parcel_read_int32(parcel, reinterpret_cast<int*>(&name_));
+    rpc_port_parcel_read_int32(parcel, reinterpret_cast<int*>(&type_));
 
     int size = 0;
     rpc_port_parcel_read_array_count(parcel, &size);
-    if (size == 0)
-      return;
+    if (size == 0) return;
 
-    unsigned char* raw = reinterpret_cast<unsigned char*>(malloc(size));
-    if (raw == nullptr) {
-      _E("malloc() is failed");
-      return;
-    }
+    uint32_t start_pos = 0;
+    rpc_port_parcel_get_reader(parcel, &start_pos);
 
-    rpc_port_parcel_burst_read(parcel, raw, size);
-    rpc_port_parcel_burst_write(GetParcel(), raw, size);
-    free(raw);
+    rpc_port_parcel_h sub_parcel_raw = nullptr;
+    rpc_port_parcel_create_from_parcel(&sub_parcel_raw, parcel, start_pos,
+                                       size);
+    sub_parcel_.reset(sub_parcel_raw);
+    rpc_port_parcel_reserve(sub_parcel_.get(), size);
+    rpc_port_parcel_set_reader(parcel, start_pos + size);
   }
 
   <SERIALIZER>
 
  private:
-  std::string name_;
-  std::string type_;
-  rpc_port_parcel_h parcel_ = nullptr;
+  int32_t name_;
+  int32_t type_;
+  std::vector<std::function<void(rpc_port_parcel_h)>> cmds_;
+  std::unique_ptr<std::remove_pointer_t<rpc_port_parcel_h>,
+                  decltype(rpc_port_parcel_destroy)*>
+      sub_parcel_{nullptr, rpc_port_parcel_destroy};
 };
 
 )__cpp_cb";
@@ -619,7 +523,7 @@ class Unit {
  */
 constexpr const char CB_UNIT_SERIALIZER_HEADER[] =
 R"__cpp_cb(
-void Write(const <TYPE>& value);
+void Write(const <TYPE>& value, rpc_port_parcel_h parcel = nullptr);
 void Read(<TYPE>& value);
 )__cpp_cb";
 
@@ -630,8 +534,15 @@ void Read(<TYPE>& value);
  */
 constexpr const char CB_UNIT_SERIALIZER_BODY[] =
 R"__cpp_cb(
-void Unit::Write(const <TYPE>& value) {
-  <IMPL_SERIALIZER>
+void Unit::Write(const <TYPE>& value, rpc_port_parcel_h parcel) {
+  auto cb = [<TAG>value, this](auto* p) {
+    <IMPL_SERIALIZER>
+  };
+
+  if (parcel)
+    cb(parcel);
+  else
+    cmds_.push_back(std::move(cb));
 }
 
 void Unit::Read(<TYPE>& value) {
@@ -644,48 +555,49 @@ void Unit::Read(<TYPE>& value) {
  */
 constexpr const char CB_UNIT_IMPL_SERIALIZER_USER_DEFINED[] =
 R"__cpp_cb(
-UnitMap unit_map;
 <UNIT_MAP_WRITE>
-unit_map.Serialize(GetParcel());
 )__cpp_cb";
 
 constexpr const char CB_UNIT_MAP_ARRAY_WRITE[] =
 R"__cpp_cb(
-unit_map.Write("size", static_cast<int>(value.size() & INT_MAX));
+rpc_port_parcel_write_array_count(p, static_cast<int>(value.size() & INT_MAX));
 
-for (size_t index = 0; index < value.size(); ++index)
-  unit_map.Write(std::to_string(index), value[index]);
+for (auto& i : value)
+  Write(i, p);
+)__cpp_cb";
+
+constexpr const char CB_UNIT_MAP_ARRAY_WRITE_OPT[] =
+R"__cpp_cb(
+rpc_port_parcel_write_array_count(p, static_cast<int>(value.size() & INT_MAX));
+rpc_port_parcel_burst_write(p, reinterpret_cast<const unsigned char*>(value.data()), value.size()
+    * sizeof(std::remove_reference_t<decltype(value)>::value_type));
 )__cpp_cb";
 
 constexpr const char CB_UNIT_MAP_LIST_WRITE[] =
 R"__cpp_cb(
-unit_map.Write("length", static_cast<int>(value.size() & INT_MAX));
+rpc_port_parcel_write_array_count(p, static_cast<int>(value.size() & INT_MAX));
 
-int index = 0;
-for (auto& data : value)
-  unit_map.Write(std::to_string(index++), data);
+for (auto& i : value)
+  Write(i, p);
 )__cpp_cb";
 
 constexpr const char CB_UNIT_MAP_MAP_WRITE[] =
 R"__cpp_cb(
-unit_map.Write("size", static_cast<int>(value.size() & INT_MAX));
-
-int index = 0;
-for (auto& iter : value) {
-  auto& key = iter.first;
-  unit_map.Write("key-" + std::to_string(index), key);
-  auto& val = iter.second;
-  unit_map.Write("value-" + std::to_string(index++), val);
+rpc_port_parcel_write_array_count(p, static_cast<int>(value.size() & INT_MAX));
+
+for (auto& [k, v] : value) {
+  Write(k, p);
+  Write(v, p);
 }
 )__cpp_cb";
 
 constexpr const char CB_UNIT_MAP_SET_WRITE[] =
 R"__cpp_cb(
-unit_map.Write("size", static_cast<int>(value.size() & INT_MAX));
+rpc_port_parcel_write_array_count(p, static_cast<int>(value.size() & INT_MAX));
 
-int index = 0;
-for (auto& key : value)
-  unit_map.Write("key-" + std::to_string(index++), key);
+for (auto& v : value) {
+  Write(v, p);
+}
 )__cpp_cb";
 
 /**
@@ -693,44 +605,42 @@ for (auto& key : value)
  */
 constexpr const char CB_UNIT_MAP_BASE_WRITE[] =
 R"__cpp_cb(
-unit_map.Write("<NAME>", value.Get<NAME>());
+Write(value.Get<NAME>(), p);
 )__cpp_cb";
 
 constexpr const char CB_UNIT_MAP_CALLBACKBASE_WRITE[] =
 R"__cpp_cb(
-unit_map.Write("id", value.GetId());
-unit_map.Write("seq_id", value.GetSeqId());
-unit_map.Write("once", value.IsOnce());
+rpc_port_parcel_write_int32(p, value.GetId());
+rpc_port_parcel_write_int32(p, value.GetSeqId());
+rpc_port_parcel_write_bool(p, value.IsOnce());
 )__cpp_cb";
 
 constexpr const char CB_UNIT_MAP_REMOTE_EXCEPTION_WRITE[] =
 R"__cpp_cb(
-unit_map.Write("cause", value.GetCause());
-unit_map.Write("message", value.GetMessage());
+rpc_port_parcel_write_int32(p, value.GetCause());
+rpc_port_parcel_write_string(p, value.GetMessage().c_str());
 )__cpp_cb";
 
 constexpr const char CB_UNIT_IMPL_SERIALIZER_DELEGATE[] =
 R"__cpp_cb(
-UnitMap unit_map;
-unit_map.Write("id", value->GetId());
-unit_map.Write("seq_id", value->GetSeqId());
-unit_map.Write("once", value->IsOnce());
-unit_map.Serialize(GetParcel());
+rpc_port_parcel_write_int32(p, value->GetId());
+rpc_port_parcel_write_int32(p, value->GetSeqId());
+rpc_port_parcel_write_bool(p, value->IsOnce());
 )__cpp_cb";
 
 constexpr const char CB_UNIT_IMPL_SERIALIZER_BUNDLE[] =
 R"__cpp_cb(
-rpc_port_parcel_write_bundle(GetParcel(), value.GetHandle());
+rpc_port_parcel_write_bundle(p, value.GetHandle());
 )__cpp_cb";
 
 constexpr const char CB_UNIT_IMPL_SERIALIZER_STRING[] =
 R"__cpp_cb(
-rpc_port_parcel_write_string(GetParcel(), value.c_str());
+rpc_port_parcel_write_string(p, value.c_str());
 )__cpp_cb";
 
 constexpr const char CB_UNIT_IMPL_SERIALIZER_FILE[] =
 R"__cpp_cb(
-rpc_port_parcel_write_string(GetParcel(), value.GetFileName().c_str());
+rpc_port_parcel_write_string(p, value.GetFileName().c_str());
 )__cpp_cb";
 
 /**
@@ -738,12 +648,12 @@ rpc_port_parcel_write_string(GetParcel(), value.GetFileName().c_str());
  */
 constexpr const char CB_UNIT_IMPL_SERIALIZER_BASE[] =
 R"__cpp_cb(
-rpc_port_parcel_write_<PARCEL_TYPE>(GetParcel(), value);
+rpc_port_parcel_write_<PARCEL_TYPE>(p, value);
 )__cpp_cb";
 
 constexpr const char CB_UNIT_IMPL_SERIALIZER_ENUM[] =
 R"__cpp_cb(
-rpc_port_parcel_write_int32(GetParcel(), static_cast<int>(value));
+rpc_port_parcel_write_int32(p, static_cast<int>(value));
 )__cpp_cb";
 
 /**
@@ -751,8 +661,6 @@ rpc_port_parcel_write_int32(GetParcel(), static_cast<int>(value));
  */
 constexpr const char CB_UNIT_IMPL_DESERIALIZER_USER_DEFINED[] =
 R"__cpp_cb(
-UnitMap unit_map;
-unit_map.Deserialize(GetParcel());
 <UNIT_MAP_READ>
 )__cpp_cb";
 
@@ -762,26 +670,35 @@ unit_map.Deserialize(GetParcel());
 constexpr const char CB_UNIT_MAP_ARRAY_READ[] =
 R"__cpp_cb(
 int tmp_size = 0;
-unit_map.Read("size", tmp_size);
+rpc_port_parcel_read_array_count(sub_parcel_.get(), &tmp_size);
 
 for (int index = 0; index < tmp_size; ++index) {
   <TYPE> tmp_value<SET_INIT_VALUE>;
-  unit_map.Read(std::to_string(index), tmp_value);
+  Read(tmp_value);
   value.push_back(tmp_value);
 }
 )__cpp_cb";
 
+constexpr const char CB_UNIT_MAP_ARRAY_READ_OPT[] =
+R"__cpp_cb(
+int cnt = 0;
+rpc_port_parcel_read_array_count(sub_parcel_.get(), &cnt);
+int size = cnt * sizeof(std::remove_reference_t<decltype(value)>::value_type);
+value.resize(cnt);
+rpc_port_parcel_burst_read(sub_parcel_.get(), reinterpret_cast<unsigned char*>(&value[0]), size);
+)__cpp_cb";
+
 /**
  * <TYPE> The type of the value of the list.
  */
 constexpr const char CB_UNIT_MAP_LIST_READ[] =
 R"__cpp_cb(
-int tmp_length = 0;
-unit_map.Read("length", tmp_length);
+int tmp_size = 0;
+rpc_port_parcel_read_array_count(sub_parcel_.get(), &tmp_size);
 
-for (int index = 0; index < tmp_length; ++index) {
+for (int index = 0; index < tmp_size; ++index) {
   <TYPE> tmp_value<SET_INIT_VALUE>;
-  unit_map.Read(std::to_string(index), tmp_value);
+  Read(tmp_value);
   value.push_back(tmp_value);
 }
 )__cpp_cb";
@@ -793,13 +710,13 @@ for (int index = 0; index < tmp_length; ++index) {
 constexpr const char CB_UNIT_MAP_MAP_READ[] =
 R"__cpp_cb(
 int tmp_size = 0;
-unit_map.Read("size", tmp_size);
+rpc_port_parcel_read_array_count(sub_parcel_.get(), &tmp_size);
 
 for (int index = 0; index < tmp_size; ++index) {
   <KEY_TYPE> tmp_key;
-  unit_map.Read("key-" + std::to_string(index), tmp_key);
+  Read(tmp_key);
   <VALUE_TYPE> tmp_value;
-  unit_map.Read("value-" + std::to_string(index), tmp_value);
+  Read(tmp_value);
   value[tmp_key] = tmp_value;
 }
 )__cpp_cb";
@@ -810,11 +727,11 @@ for (int index = 0; index < tmp_size; ++index) {
 constexpr const char CB_UNIT_MAP_SET_READ[] =
 R"__cpp_cb(
 int tmp_size = 0;
-unit_map.Read("size", tmp_size);
+rpc_port_parcel_read_array_count(sub_parcel_.get(), &tmp_size);
 
 for (int index = 0; index < tmp_size; ++index) {
   <KEY_TYPE> tmp_key;
-  unit_map.Read("key-" + std::to_string(index), tmp_key);
+  Read(tmp_key);
   value.insert(tmp_key);
 }
 )__cpp_cb";
@@ -826,34 +743,39 @@ for (int index = 0; index < tmp_size; ++index) {
 constexpr const char CB_UNIT_MAP_BASE_READ[] =
 R"__cpp_cb(
 <TYPE> tmp_<NAME><SET_INIT_VALUE>;
-unit_map.Read("<NAME>", tmp_<NAME>);
+Read(tmp_<NAME>);
 value.Set<NAME>(tmp_<NAME>);
 )__cpp_cb";
 
 constexpr const char CB_UNIT_MAP_CALLBACKBASE_READ[] =
 R"__cpp_cb(
-int tmp_id = 0;
-unit_map.Read("id", tmp_id);
-value.SetId(tmp_id);
+int id = 0;
+int seq_id = 0;
+bool once = false;
 
-int tmp_seq_id = 0;
-unit_map.Read("seq_id", tmp_seq_id);
-value.SetSeqId(tmp_seq_id);
+rpc_port_parcel_read_int32(sub_parcel_.get(), &id);
+rpc_port_parcel_read_int32(sub_parcel_.get(), &seq_id);
+rpc_port_parcel_read_bool(sub_parcel_.get(), &once);
 
-bool tmp_once = false;
-unit_map.Read("once", tmp_once);
-value.SetOnce(tmp_once);
+value.SetId(id);
+value.SetSeqId(seq_id);
+value.SetOnce(once);
 )__cpp_cb";
 
 constexpr const char CB_UNIT_MAP_REMOTE_EXCEPTION_READ[] =
 R"__cpp_cb(
-int tmp_cause = 0;
-unit_map.Read("cause", tmp_cause);
+char* tmp_str = nullptr;
+int cause = 0;
+std::string message;
 
-std::string tmp_message;
-unit_map.Read("message", tmp_message);
+rpc_port_parcel_read_int32(sub_parcel_.get(), &cause);
+rpc_port_parcel_read_string(sub_parcel_.get(), &tmp_str);
+if (tmp_str != nullptr) {
+  message = tmp_str;
+  free(tmp_str);
+}
 
-value = RemoteException(tmp_cause, std::move(tmp_message));
+value = RemoteException(cause, std::move(message));
 )__cpp_cb";
 
 /**
@@ -861,33 +783,30 @@ value = RemoteException(tmp_cause, std::move(tmp_message));
  */
 constexpr const char CB_UNIT_IMPL_DESERIALIZER_DELEGATE[] =
 R"__cpp_cb(
-UnitMap unit_map;
-unit_map.Deserialize(GetParcel());
-
-int tmp_id = 0;
-unit_map.Read("id", tmp_id);
-value->SetId(tmp_id);
+int id = 0;
+int seq_id = 0;
+bool once = false;
 
-int tmp_seq_id = 0;
-unit_map.Read("seq_id", tmp_seq_id);
-value->SetSeqId(tmp_seq_id);
+rpc_port_parcel_read_int32(sub_parcel_.get(), &id);
+rpc_port_parcel_read_int32(sub_parcel_.get(), &seq_id);
+rpc_port_parcel_read_bool(sub_parcel_.get(), &once);
 
-bool tmp_once = false;
-unit_map.Read("once", tmp_once);
-value->SetOnce(tmp_once);
+value->SetId(id);
+value->SetSeqId(seq_id);
+value->SetOnce(once);
 )__cpp_cb";
 
 constexpr const char CB_UNIT_IMPL_DESERIALIZER_BUNDLE[] =
 R"__cpp_cb(
 bundle* tmp_b = nullptr;
-rpc_port_parcel_read_bundle(GetParcel(), &tmp_b);
+rpc_port_parcel_read_bundle(sub_parcel_.get(), &tmp_b);
 value = Bundle(tmp_b, false, true);
 )__cpp_cb";
 
 constexpr const char CB_UNIT_IMPL_DESERIALIZER_STRING[] =
 R"__cpp_cb(
 char* tmp_str = nullptr;
-rpc_port_parcel_read_string(GetParcel(), &tmp_str);
+rpc_port_parcel_read_string(sub_parcel_.get(), &tmp_str);
 if (tmp_str != nullptr) {
   value = std::string(tmp_str);
   free(tmp_str);
@@ -897,7 +816,7 @@ if (tmp_str != nullptr) {
 constexpr const char CB_UNIT_IMPL_DESERIALIZER_FILE[] =
 R"__cpp_cb(
 char* tmp_filename = nullptr;
-rpc_port_parcel_read_string(GetParcel(), &tmp_filename);
+rpc_port_parcel_read_string(sub_parcel_.get(), &tmp_filename);
 if (tmp_filename != nullptr) {
   value = File(tmp_filename);
   free(tmp_filename);
@@ -912,7 +831,7 @@ if (tmp_filename != nullptr) {
 constexpr const char CB_UNIT_IMPL_DESERIALIZER_BASE[] =
 R"__cpp_cb(
 <TYPE> tmp_value<SET_INIT_VALUE>;
-rpc_port_parcel_read_<PARCEL_TYPE>(GetParcel(), &tmp_value);
+rpc_port_parcel_read_<PARCEL_TYPE>(sub_parcel_.get(), &tmp_value);
 value = tmp_value;
 )__cpp_cb";
 
@@ -922,7 +841,7 @@ value = tmp_value;
 constexpr const char CB_UNIT_IMPL_DESERIALIZER_ENUM[] =
 R"__cpp_cb(
 int tmp_value = -1;
-rpc_port_parcel_read_int32(GetParcel(), &tmp_value);
+rpc_port_parcel_read_int32(sub_parcel_.get(), &tmp_value);
 value = static_cast<<TYPE>>(tmp_value);
 )__cpp_cb";
 
@@ -935,27 +854,22 @@ class UnitMap {
  public:
   UnitMap() {}
 
-  void Clear() {
-    map_.clear();
-  }
+  void Clear() { map_.clear(); }
 
-  size_t GetSize() const {
-    return map_.size();
-  }
+  size_t GetSize() const { return map_.size(); }
 
-  void Insert(std::string name, std::shared_ptr<Unit> unit) {
-    map_[std::move(name)] = std::move(unit);
+  void Insert(int32_t name, std::shared_ptr<Unit> unit) {
+    map_[name] = std::move(unit);
   }
 
-  std::shared_ptr<Unit> Lookup(const std::string& name) const {
+  std::shared_ptr<Unit> Lookup(int32_t name) const {
     auto found = map_.find(name);
-    if (found == map_.end())
-      return nullptr;
+    if (found == map_.end()) return nullptr;
 
     return found->second;
   }
 
-  void Serialize(rpc_port_parcel_h parcel) const {
+  void Serialize(rpc_port_parcel_h parcel) const && {
     rpc_port_parcel_write_array_count(parcel, GetSize() & INT_MAX);
     for (auto& iter : map_) {
       auto& unit = iter.second;
@@ -966,47 +880,42 @@ class UnitMap {
   void Deserialize(rpc_port_parcel_h parcel) {
     int size = 0;
     rpc_port_parcel_read_array_count(parcel, &size);
+    rpc_port_parcel_pin(parcel);
     for (int i = 0; i < size; ++i) {
       auto unit = std::make_shared<Unit>();
       unit->Deserialize(parcel);
-      std::string name = unit->GetName();
-      Insert(std::move(name), std::move(unit));
+      auto name = unit->GetName();
+      Insert(name, std::move(unit));
     }
   }
 
-  <UNIT_MAP_READ_WRITE>
+  <UNIT_MAP_READ_WRITE*>
+  void Read(int32_t name, <PARAM_TYPE>& value) const {
+    auto unit = Lookup(name);
+    if (unit == nullptr) {
+      _E("Failed to find %d", name);
+      return;
+    }
 
- private:
-  std::unordered_map<std::string, std::shared_ptr<Unit>> map_;
-};
-)__cpp_cb";
+    if (unit->GetType() != <TYPE> /*<TYPE_STR>*/) {
+      _E("type(%d) is not <TYPE>", unit->GetType());
+      return;
+    }
 
-/**
- * <PARAM_TYPE> The parameter type of the value.
- * <TYPE> The type name of the value.
- */
-constexpr const char CB_UNIT_MAP_READ_WRITE[] =
-R"__cpp_cb(
-void Read(const std::string& name, <PARAM_TYPE>& value) const {
-  auto unit = Lookup(name);
-  if (unit == nullptr) {
-    _E("Failed to find %s", name.c_str());
-    return;
+    unit->Read(value);
   }
 
-  if (unit->GetType().compare(0, strlen("<TYPE>"), "<TYPE>") != 0) {
-    _E("type(%s) is not <TYPE>", unit->GetType().c_str());
-    return;
+  UnitMap&& Write(int32_t name, const <PARAM_TYPE>& value) && {
+    auto unit = std::make_shared<Unit>(name, <TYPE> /*<TYPE_STR>*/);
+    unit->Write(value);
+    Insert(name, std::move(unit));
+    return std::move(*this);
   }
 
-  unit->Read(value);
-}
-
-void Write(std::string name, const <PARAM_TYPE>& value) {
-  auto unit = std::make_shared<Unit>(name, "<TYPE>");
-  unit->Write(value);
-  Insert(std::move(name), std::move(unit));
-}
+  </UNIT_MAP_READ_WRITE*>
+ private:
+  std::unordered_map<int32_t, std::shared_ptr<Unit>> map_;
+};
 )__cpp_cb";
 
 /**
@@ -1031,10 +940,94 @@ R"__cpp_cb(
 }
 )__cpp_cb";
 
-constexpr const char CB_EXPORT_API[] =
+constexpr const char CB_RPC_PORT_INTERNAL_APIS[] =
 R"__cpp_cb(
-#undef EXPORT_API
-#define EXPORT_API extern "C" __attribute__ ((visibility("default")))
+
+using rpc_port_parcel_reserve_t = int (*)(rpc_port_parcel_h h, unsigned int size);
+
+using rpc_port_parcel_create_from_parcel_t = int (*)(rpc_port_parcel_h* h,
+                                                     rpc_port_parcel_h origin_parcel,
+                                                     unsigned int start_pos,
+                                                     unsigned int size);
+using rpc_port_parcel_set_data_size_t = int (*)(rpc_port_parcel_h h, unsigned int size);
+using rpc_port_parcel_get_data_size_t = int (*)(rpc_port_parcel_h h, unsigned int* size);
+using rpc_port_parcel_pin_t = int (*)(rpc_port_parcel_h h);
+using rpc_port_parcel_get_reader_t = int (*)(rpc_port_parcel_h h, unsigned int* reader_pos);
+using rpc_port_parcel_set_reader_t = int (*)(rpc_port_parcel_h h, unsigned int reader_pos);
+
+rpc_port_parcel_reserve_t rpc_port_parcel_reserve;
+rpc_port_parcel_create_from_parcel_t rpc_port_parcel_create_from_parcel;
+rpc_port_parcel_set_data_size_t rpc_port_parcel_set_data_size;
+rpc_port_parcel_get_data_size_t rpc_port_parcel_get_data_size;
+rpc_port_parcel_pin_t rpc_port_parcel_pin;
+rpc_port_parcel_get_reader_t rpc_port_parcel_get_reader;
+rpc_port_parcel_set_reader_t rpc_port_parcel_set_reader;
+
+class RpcPortInternals {
+ public:
+  RpcPortInternals() {
+    std::string symbol = "rpc_port_parcel_reserve";
+    rpc_port_parcel_reserve = reinterpret_cast<rpc_port_parcel_reserve_t>(
+        dlsym(RTLD_DEFAULT, symbol.c_str()));
+    if (rpc_port_parcel_reserve == nullptr) {
+      _E("Failed to find symbol(%s). Please check rpc-port version", symbol.c_str());
+      return;
+    }
+
+    symbol = "rpc_port_parcel_create_from_parcel";
+    rpc_port_parcel_create_from_parcel = reinterpret_cast<rpc_port_parcel_create_from_parcel_t>(
+        dlsym(RTLD_DEFAULT, symbol.c_str()));
+    if (rpc_port_parcel_create_from_parcel == nullptr) {
+      _E("Failed to find symbol(%s). Please check rpc-port version", symbol.c_str());
+      return;
+    }
+
+    symbol = "rpc_port_parcel_set_data_size";
+    rpc_port_parcel_set_data_size =
+        reinterpret_cast<rpc_port_parcel_set_data_size_t>(
+            dlsym(RTLD_DEFAULT, symbol.c_str()));
+    if (rpc_port_parcel_set_data_size == nullptr) {
+      _E("Failed to find symbol(%s). Please check rpc-port version", symbol.c_str());
+      return;
+    }
+
+    symbol = "rpc_port_parcel_get_data_size";
+    rpc_port_parcel_get_data_size =
+        reinterpret_cast<rpc_port_parcel_get_data_size_t>(
+            dlsym(RTLD_DEFAULT, symbol.c_str()));
+    if (rpc_port_parcel_get_data_size == nullptr) {
+      _E("Failed to find symbol(%s). Please check rpc-port version", symbol.c_str());
+      return;
+    }
+
+    symbol = "rpc_port_parcel_pin";
+    rpc_port_parcel_pin = reinterpret_cast<rpc_port_parcel_pin_t>(
+        dlsym(RTLD_DEFAULT, symbol.c_str()));
+    if (rpc_port_parcel_pin == nullptr) {
+      _E("Failed to find symbol(%s). Please check rpc-port version", symbol.c_str());
+      return;
+    }
+
+    symbol = "rpc_port_parcel_get_reader";
+    rpc_port_parcel_get_reader = reinterpret_cast<rpc_port_parcel_get_reader_t>(
+        dlsym(RTLD_DEFAULT, symbol.c_str()));
+    if (rpc_port_parcel_get_reader == nullptr) {
+      _E("Failed to find symbol(%s). Please check rpc-port version", symbol.c_str());
+      return;
+    }
+
+    symbol = "rpc_port_parcel_set_reader";
+    rpc_port_parcel_set_reader = reinterpret_cast<rpc_port_parcel_set_reader_t>(
+        dlsym(RTLD_DEFAULT, symbol.c_str()));
+    if (rpc_port_parcel_set_reader == nullptr) {
+      _E("Failed to find symbol(%s). Please check rpc-port version", symbol.c_str());
+      return;
+    }
+  }
+};
+
+RpcPortInternals rpc_port_internals_;
+
 )__cpp_cb";
 
 }  // namespace version2
index 7f1c5abc0c79046fc9c0f182458dcfc716a4a59e..b1791e0097e998fd4bc573cdb80fcac286a0d5ba 100644 (file)
@@ -27,41 +27,38 @@ CppGroupBodyGenerator::CppGroupBodyGenerator(std::shared_ptr<Document> doc)
     : CppGeneratorBase(std::move(doc)) {}
 
 void CppGroupBodyGenerator::OnInitGen(std::ofstream& stream) {
-  GenVersion(stream);
-  GenHeader(stream);
-  GenLogTag(stream, "RPC_PORT_GROUP");
-  GenLogDefinition(stream);
-  GenVersionDefinition(stream);
-  GenNamespace(stream);
+  ReplaceAll(CB_MAIN_GROUP_BODY)
+      .Replace("VERSION", std::string(FULLVER))
+      .Replace("RPC_PORT_INTERNALS", GenRpcPortInternals())
+      .ReplaceBlock("HEADER", [&](auto& r) { GenHeader(r); })
+      .ReplaceBlock("NAMESPACE", [&](auto& r) { GenNamespace(r); })
+      .Out(stream);
 }
 
 void CppGroupBodyGenerator::OnFiniGen(std::ofstream& stream) {}
 
-void CppGroupBodyGenerator::GenHeader(std::ofstream& stream) {
+void CppGroupBodyGenerator::GenHeader(ReplaceAll& r) {
   std::string key(".cc");
   std::string header_file = FileName;
   std::size_t found = header_file.rfind(key);
   if (found != std::string::npos)
     header_file.replace(found, key.length(), ".h");
 
-  ReplaceAll(CB_HEADER).Change("<HEADER_FILE>", header_file).Out(stream);
+  r.Replace("HEADER_FILE", header_file);
 }
 
-void CppGroupBodyGenerator::GenNamespace(std::ofstream& stream) {
-  ReplaceAll(CB_NAMESPACE)
-      .ChangeToLower("<FILE_NAMESPACE>", GetFileNamespace())
-      .Change("<STRUCTURES>", GenStructures(false))
-      .Change("<UNIT_MAP>", GenUnitMap(false))
-      .Change("<INTERFACES>", GenInterfaces())
-      .Transform([&](std::string str) { return SmartIndent(str); })
-      .Out(stream);
+void CppGroupBodyGenerator::GenNamespace(ReplaceAll& r) {
+  r.ChangeToLower("<FILE_NAMESPACE>", GetFileNamespace())
+      .Replace("STRUCTURES", GenStructures(false))
+      .Replace("UNIT_MAP", GenUnitMap(false, true))
+      .Replace("INTERFACES", GenInterfaces())
+      .Transform([&](std::string str) { return SmartIndent(str); });
 }
 
 std::string CppGroupBodyGenerator::GenInterfaces() {
   std::string code;
   for (auto& block : GetDocument().GetBlocks()) {
-    if (block->GetType() != Block::TYPE_INTERFACE)
-      continue;
+    if (block->GetType() != Block::TYPE_INTERFACE) continue;
 
     auto& iface = static_cast<const Interface&>(*block);
     code += GenInterface(iface);
@@ -73,23 +70,16 @@ std::string CppGroupBodyGenerator::GenInterfaces() {
 std::string CppGroupBodyGenerator::GenInterface(const Interface& iface) {
   return std::string(
       ReplaceAll(CB_INTERFACE)
-          .Change("<CLS_NAME>", iface.GetID())
-          .Change("<IMPL_DISPATCH_FUNC_INIT>\n",
-              GenInterfaceImplDispatchFuncInit(iface))
-          .Change("<IMPL_METHOD>", GenInterfaceMethod(iface))
-          .Change("<IMPL_DISPATCH_FUNC>", GenInterfaceImplDispatchFunc(iface)));
-}
-
-std::string CppGroupBodyGenerator::GenInterfaceImplDispatchFuncInit(
-    const Interface& iface) {
-  std::string code;
-  for (auto& decl : iface.GetDeclarations()) {
-    code += ReplaceAll(CB_INTERFACE_IMPL_DISPATCH_FUNC_INIT)
-        .Change("<NAME>", decl->GetID())
-        .Change("<CLS_NAME>", iface.GetID());
-  }
-
-  return RemoveLine(code);
+          .Replace("HASH_METHOD", std::to_string(GetHashCode("[METHOD]")))
+          .Repeat("IMPL_DISPATCH_FUNC_INIT", iface.GetDeclarations(),
+                  [&](auto& r, const auto& i) {
+                    r.Replace("NAME", i->GetID())
+                        .Replace("CLS_NAME", iface.GetID());
+                    return true;
+                  })
+          .Replace("CLS_NAME", iface.GetID())
+          .Replace("IMPL_METHOD", GenInterfaceMethod(iface))
+          .Replace("IMPL_DISPATCH_FUNC", GenInterfaceImplDispatchFunc(iface)));
 }
 
 std::string CppGroupBodyGenerator::GenInterfaceImplDispatchFunc(
@@ -97,36 +87,28 @@ std::string CppGroupBodyGenerator::GenInterfaceImplDispatchFunc(
   std::string code;
   for (auto& decl : iface.GetDeclarations()) {
     code += ReplaceAll(CB_INTERFACE_DISPATCH_FUNC)
-        .Change("<CLS_NAME>", iface.GetID())
-        .Change("<DESERIALIZE>", GenInterfaceImplDispatchFuncDeserialize(*decl))
-        .Change("<NAME>", decl->GetID())
-        .Change("<PARAMS>", GenInterfaceImplDispatchFuncParams(*decl));
+                .Replace("CLS_NAME", iface.GetID())
+                .Repeat("DESERIALIZE", decl->GetParameters(),
+                        [&](auto& r, const auto& i) {
+                          auto& type = i->GetParameterType().GetBaseType();
+                          r.Replace("TYPE", ConvertTypeToString(type))
+                              .Replace("HASH_NAME",
+                                       std::to_string(GetHashCode(i->GetID())))
+                              .Replace("NAME", i->GetID());
+                          return true;
+                        })
+                .Replace("NAME", decl->GetID())
+                .Replace("PARAMS", GenInterfaceImplDispatchFuncParams(*decl));
   }
 
   return RemoveLine(code);
 }
 
-std::string CppGroupBodyGenerator::GenInterfaceImplDispatchFuncDeserialize(
-    const Declaration& decl) {
-  std::string code;
-  for (auto& param : decl.GetParameters()) {
-    auto& type = param->GetParameterType().GetBaseType();
-    std::string str = std::string(
-        ReplaceAll(CB_INTERFACE_DISPATCH_FUNC_UNIT_MAP_READ)
-        .Change("<TYPE>", ConvertTypeToString(type))
-        .Change("<NAME>", param->GetID()));
-    code += RemoveLine(str);
-  }
-
-  return code;
-}
-
 std::string CppGroupBodyGenerator::GenInterfaceImplDispatchFuncParams(
     const Declaration& decl) {
   std::string code;
   for (auto& param : decl.GetParameters()) {
-    if (!code.empty())
-      code += ", ";
+    if (!code.empty()) code += ", ";
 
     code += param->GetID();
   }
@@ -138,21 +120,17 @@ std::string CppGroupBodyGenerator::GenInterfaceMethod(const Interface& iface) {
   std::string code;
   for (auto& decl : iface.GetDeclarations()) {
     code += ReplaceAll(CB_INTERFACE_METHOD)
-        .Change("<CLS_NAME>", iface.GetID())
-        .Change("<NAME>", decl->GetID())
-        .Change("<PARAMS>", GetParameters(decl->GetParameters()))
-        .Change("<SERIALIZE>", GenInterfaceMethodSerialize(*decl));
-  }
-
-  return RemoveLine(code);
-}
-
-std::string CppGroupBodyGenerator::GenInterfaceMethodSerialize(
-    const Declaration& decl) {
-  std::string code;
-  for (auto& param : decl.GetParameters()) {
-    code += ReplaceAll(CB_INTERFACE_METHOD_UNIT_MAP_WRITE)
-        .Change("<NAME>", param->GetID());
+                .Replace("HASH_METHOD", std::to_string(GetHashCode("[METHOD]")))
+                .Replace("CLS_NAME", iface.GetID())
+                .Replace("PARAMS", GetParameters(decl->GetParameters()))
+                .Repeat("SERIALIZE", decl->GetParameters(),
+                        [&](auto& r, const auto& i) {
+                          r.Replace("HASH_NAME",
+                                    std::to_string(GetHashCode(i->GetID())))
+                              .Replace("NAME", i->GetID());
+                          return true;
+                        })
+                .Replace("NAME", decl->GetID());
   }
 
   return RemoveLine(code);
index 86a38c4fc49394f4914cafdcf24605520dfbc7e5..2897a1fcffef7a40d5ce3c58b2a459edce71e393 100644 (file)
@@ -34,8 +34,8 @@ class CppGroupBodyGenerator : public CppGeneratorBase {
   void OnFiniGen(std::ofstream& stream) override;
 
  private:
-  void GenHeader(std::ofstream& stream);
-  void GenNamespace(std::ofstream& stream);
+  void GenHeader(ReplaceAll& r);
+  void GenNamespace(ReplaceAll& r);
   std::string GenInterfaces();
   std::string GenInterface(const Interface& iface);
   std::string GenInterfaceImplDispatchFuncInit(const Interface& iface);
index bd39a1bcf6110d998931fa626aad8a7eae68e683..354bab55142a60d9d439d65495dbf6b276b1d9a2 100644 (file)
 namespace tidl {
 namespace version2 {
 
+constexpr const char CB_MAIN_GROUP_BODY[] =
+R"__cpp_cb(
 /**
- * <HEADER_FILE> The header file name.
+ * Generated by tidlc <VERSION>.
  */
-constexpr const char CB_HEADER[] =
-R"__cpp_cb(
+
+<HEADER!>
 #include "<HEADER_FILE>"
 
 #include <stdlib.h>
 #include <assert.h>
+#include <dlfcn.h>
 #include <dlog.h>
 
 #include <climits>
-)__cpp_cb";
+#include <stdexcept>
+</HEADER!>
 
-/**
- * <FILE_NAMESPACE> The namespace of the file.
- * <STRCUTURES> The implementation of structures.
- * <UNIT_MAP> The implementation of unit map.
- * <INTERFACES> The implementation of interfaces.
- */
-constexpr const char CB_NAMESPACE[] =
-R"__cpp_cb(
+#undef LOG_TAG
+#define LOG_TAG "RPC_PORT_GROUP"
+
+#undef _E
+#define _E(fmt, ...) dlog_print(DLOG_ERROR, LOG_TAG, "%s: %s(%d) > " fmt, basename(const_cast<char*>(__FILE__)), __FUNCTION__, __LINE__, ##__VA_ARGS__)
+
+#undef _W
+#define _W(fmt, ...) dlog_print(DLOG_WARN, LOG_TAG, "%s: %s(%d) > " fmt, basename(const_cast<char*>(__FILE__)), __FUNCTION__, __LINE__, ##__VA_ARGS__)
+
+#undef _I
+#define _I(fmt, ...) dlog_print(DLOG_INFO, LOG_TAG, "%s: %s(%d) > " fmt, basename(const_cast<char*>(__FILE__)), __FUNCTION__, __LINE__, ##__VA_ARGS__)
+
+#undef _D
+#define _D(fmt, ...) dlog_print(DLOG_DEBUG, LOG_TAG, "%s: %s(%d) > " fmt, basename(const_cast<char*>(__FILE__)), __FUNCTION__, __LINE__, ##__VA_ARGS__)
+
+#undef TIDL_VERSION
+#define TIDL_VERSION "<VERSION>"
+
+<RPC_PORT_INTERNALS>
+
+<NAMESPACE!>
 namespace rpc_port {
 namespace <FILE_NAMESPACE> {
 
@@ -53,6 +70,9 @@ namespace group {
 }  // namespace group
 }  // namespace <FILE_NAMESPACE>
 }  // namespace rpc_port
+
+</NAMESPACE!>
+
 )__cpp_cb";
 
 /**
@@ -65,7 +85,9 @@ constexpr const char CB_INTERFACE[] =
 R"__cpp_cb(
 <CLS_NAME>::<CLS_NAME>(std::string sender_appid, bool is_system) : sender_appid_(std::move(sender_appid)), is_system_(is_system) {
   dispatch_funcs_ = {
-    <IMPL_DISPATCH_FUNC_INIT>
+    <IMPL_DISPATCH_FUNC_INIT*>
+      { static_cast<int>(MethodId::<NAME>), std::bind(&<CLS_NAME>::Dispatch<NAME>, this, std::placeholders::_1) },
+    </IMPL_DISPATCH_FUNC_INIT*>
   };
 
   Subscribe();
@@ -140,34 +162,26 @@ void <CLS_NAME>::EventCb(const char* event_name, bundle* event_data, void* user_
 
   UnitMap unit_map;
   unit_map.Deserialize(parcel);
-  rpc_port_parcel_destroy(parcel);
 
   int cmd = -1;
-  unit_map.Read("[METHOD]", cmd);
+  unit_map.Read(<HASH_METHOD> /*[METHOD]*/, cmd);
 
   auto found = handle->dispatch_funcs_.find(cmd);
   if (found == handle->dispatch_funcs_.end()) {
     _E("Unknown command(%d)", cmd);
+    rpc_port_parcel_destroy(parcel);
     return;
   }
 
   auto& func = found->second;
   func(unit_map);
+  rpc_port_parcel_destroy(parcel);
 }
 
 <IMPL_METHOD>
 <IMPL_DISPATCH_FUNC>
 )__cpp_cb";
 
-/**
- * <NAME> The method name of the interface.
- * <CLS_NAME> The interface name.
- */
-constexpr const char CB_INTERFACE_IMPL_DISPATCH_FUNC_INIT[] =
-R"__cpp_cb(
-{ static_cast<int>(MethodId::<NAME>), std::bind(&<CLS_NAME>::Dispatch<NAME>, this, std::placeholders::_1) },
-)__cpp_cb";
-
 /**
  * <CLS_NAME> The interface name.
  * <NAME> The method name.
@@ -177,21 +191,15 @@ R"__cpp_cb(
 constexpr const char CB_INTERFACE_DISPATCH_FUNC[] =
 R"__cpp_cb(
 void <CLS_NAME>::Dispatch<NAME>(const UnitMap& unit_map) {
-  <DESERIALIZE>
+  <DESERIALIZE*>
+  <TYPE> <NAME>;
+  unit_map.Read(<HASH_NAME> /*<NAME>*/, <NAME>);
+  </DESERIALIZE*>
+
   On<NAME>(<PARAMS>);
 }
 )__cpp_cb";
 
-/**
- * <TYPE> The parameter type.
- * <NAME> The parameter name.
- */
-constexpr const char CB_INTERFACE_DISPATCH_FUNC_UNIT_MAP_READ[] =
-R"__cpp_cb(
-<TYPE> <NAME>;
-unit_map.Read("<NAME>", <NAME>);
-)__cpp_cb";
-
 /**
  * <CLS_NAME> The interface name.
  * <NAME> The method name of the interface.
@@ -201,12 +209,14 @@ unit_map.Read("<NAME>", <NAME>);
 constexpr const char CB_INTERFACE_METHOD[] =
 R"__cpp_cb(
 void <CLS_NAME>::<NAME>(<PARAMS>) {
-  UnitMap unit_map;
-  unit_map.Write("[METHOD]", static_cast<int>(MethodId::<NAME>));
-  <SERIALIZE>
   rpc_port_parcel_h parcel = nullptr;
   rpc_port_parcel_create(&parcel);
-  unit_map.Serialize(parcel);
+  UnitMap()
+      .Write(<HASH_METHOD> /*[METHOD]*/, static_cast<int>(MethodId::<NAME>))
+      <SERIALIZE*>
+      .Write(<HASH_NAME> /*<HASH_NAME>*/, <NAME>)
+      </SERIALIZE*>
+      .Serialize(parcel);
   bundle* b = GetBundleFromParcel(parcel);
   rpc_port_parcel_destroy(parcel);
   if (b == nullptr) {
@@ -224,14 +234,6 @@ void <CLS_NAME>::<NAME>(<PARAMS>) {
 }
 )__cpp_cb";
 
-/**
- * <NAME> The parameter name.
- */
-constexpr const char CB_INTERFACE_METHOD_UNIT_MAP_WRITE[] =
-R"__cpp_cb(
-unit_map.Write("<NAME>", <NAME>);
-)__cpp_cb";
-
 }  // namespace version2
 }  // namespace tidl
 
index b3798c01ccde3833a27570af7a7fcfb29036c57a..7508884c8cbd8f6184eafcd0c43c5891e43b0c17 100644 (file)
@@ -27,67 +27,41 @@ CppGroupHeaderGenerator::CppGroupHeaderGenerator(std::shared_ptr<Document> doc)
     : CppGeneratorBase(std::move(doc)) {}
 
 void CppGroupHeaderGenerator::OnInitGen(std::ofstream& stream) {
-  GenVersion(stream);
-  stream << CB_HEADER;
-  GenNamespace(stream);
-}
-
-void CppGroupHeaderGenerator::OnFiniGen(std::ofstream& stream) {}
-
-void CppGroupHeaderGenerator::GenNamespace(std::ofstream& stream) {
-  ReplaceAll(CB_NAMESPACE)
+  ReplaceAll(CB_MAIN_GROUP_HEADER)
+      .Replace("VERSION", std::string(FULLVER))
       .ChangeToLower("<FILE_NAMESPACE>", GetFileNamespace())
-      .Change("<STRUCTURES>", GenStructuresForHeader(false))
-      .Change("<EXCEPTIONS>", GenExceptions())
-      .Change("<INTERFACES>", GenInterfaces())
+      .Replace("STRUCTURES", GenStructuresForHeader(false))
+      .Replace("EXCEPTIONS", GenExceptions())
+      .Repeat("INTERFACES", GetDocument().GetBlocks(),
+              [&](auto& r, const auto& i) {
+                if (i->GetType() != Block::Type::TYPE_INTERFACE) return false;
+                auto& iface = static_cast<const Interface&>(*i);
+                GenInterface(r, iface);
+                return true;
+              })
       .Transform([&](std::string code) { return SmartIndent(code); })
       .Out(stream);
 }
 
-std::string CppGroupHeaderGenerator::GenInterfaces() {
-  std::string code;
-  for (auto& block : GetDocument().GetBlocks()) {
-    if (block->GetType() != Block::Type::TYPE_INTERFACE)
-      continue;
-
-    auto& iface = static_cast<const Interface&>(*block);
-    code += GenInterface(iface);
-    code += NLine(1);
-  }
-
-  return RemoveLine(code);
-}
-
-std::string CppGroupHeaderGenerator::GenInterface(const Interface& iface) {
-  return std::string(
-      ReplaceAll(CB_INTERFACE)
-          .Change("<CLS_NAME>", iface.GetID())
-          .Change("<ENUMS>", GenEnumerations(iface.GetEnums()))
-          .Change("<PUBLIC_MEMBERS>", GenInterfacePublicMembers(iface))
-          .Change("<PRIVATE_MEMBERS>", GenInterfacePrivateMembers(iface)));
-}
-
-std::string CppGroupHeaderGenerator::GenInterfacePublicMembers(
-    const Interface& iface) {
-  std::string code;
-  for (auto& decl : iface.GetDeclarations()) {
-    code += ReplaceAll(CB_METHOD)
-        .Change("<NAME>", decl->GetID())
-        .Change("<PARAMS>", GetParameters(decl->GetParameters()));
-  }
-
-  return RemoveLine(code);
-}
-
-std::string CppGroupHeaderGenerator::GenInterfacePrivateMembers(
-    const Interface& iface) {
-  std::string code = GenMethodIds(iface);
-  for (auto& decl : iface.GetDeclarations()) {
-    code += ReplaceAll(CB_DISPATCH_FUNC)
-        .Change("<NAME>", decl->GetID());
-  }
+void CppGroupHeaderGenerator::OnFiniGen(std::ofstream& stream) {}
 
-  return code;
+void CppGroupHeaderGenerator::GenInterface(ReplaceAll& r,
+                                           const Interface& iface) {
+  r.Replace("CLS_NAME", iface.GetID())
+      .Replace("ENUMS", GenEnumerations(iface.GetEnums()))
+      .Repeat("PUBLIC_MEMBERS", iface.GetDeclarations(),
+              [&](auto& r, const auto& i) {
+                r.Replace("MEMBER_NAME", i->GetID())
+                    .Replace("MEMBER_PARAMS",
+                             GetParameters(i->GetParameters()));
+                return true;
+              })
+      .Replace("METHOD_ID", GenMethodIds(iface))
+      .Repeat("DISPATCHS", iface.GetDeclarations(),
+              [&](auto& r, const auto& i) {
+                r.Replace("NAME", i->GetID());
+                return true;
+              });
 }
 
 }  // namespace version2
index 4469f8f7967aeac7d8d7e6c7ecc35144d058471f..e0bf439f3abfef5fbba175cc0fde976fe2ee93d5 100644 (file)
@@ -34,11 +34,7 @@ class CppGroupHeaderGenerator : public CppGeneratorBase {
   void OnFiniGen(std::ofstream& stream) override;
 
  private:
-  void GenNamespace(std::ofstream& stream);
-  std::string GenInterfaces();
-  std::string GenInterface(const Interface& iface);
-  std::string GenInterfacePublicMembers(const Interface& iface);
-  std::string GenInterfacePrivateMembers(const Interface& iface);
+  void GenInterface(ReplaceAll& r, const Interface& iface);
 };
 
 }  // namespace version2
index 1312cc361ddb26c109cba09e57aa78a85a1c2afb..229c57ee293414633b78f8036eacae2e4c9124fc 100644 (file)
 namespace tidl {
 namespace version2 {
 
-constexpr const char CB_HEADER[] =
+constexpr const char CB_MAIN_GROUP_HEADER[] =
 R"__cpp_cb(
+/**
+ * Generated by tidlc <VERSION>.
+ */
+
 #pragma once
 
 #include <app_event.h>
@@ -31,21 +35,13 @@ R"__cpp_cb(
 #include <atomic>
 #include <list>
 #include <functional>
+#include <map>
 #include <memory>
 #include <mutex>
 #include <string>
 #include <vector>
 #include <unordered_map>
-)__cpp_cb";
 
-/**
- * <FILE_NAMESPACE> The namespace of the file.
- * <STRCUTURES> The structure definitions.
- * <EXCEPTIONS> The exceptions.
- * <INTERFACES> The interface definitions.
- */
-constexpr const char CB_NAMESPACE[] =
-R"__cpp_cb(
 namespace rpc_port {
 namespace <FILE_NAMESPACE> {
 
@@ -53,31 +49,26 @@ namespace <FILE_NAMESPACE> {
 namespace group {
 
 <EXCEPTIONS>
-<INTERFACES>
-}  // namespace group
-}  // namespace <FILE_NAMESPACE>
-}  // namespace rpc_port
-)__cpp_cb";
 
-/**
- * <CLS_NAME> The class name of the interface.
- * <PUBLIC_MEMBERS> The implementation of public members of the interface.
- * <PRIVATE_MEMBERS> The implementation of private members of the interface.
- */
-constexpr const char CB_INTERFACE[] =
-R"__cpp_cb(
+<INTERFACES*>
 class <CLS_NAME> {
  public:
   <CLS_NAME>(std::string sender_appid, bool is_system = false);
   virtual ~<CLS_NAME>();
   <ENUMS>
 
-  <PUBLIC_MEMBERS>
+  <PUBLIC_MEMBERS*>
+  void <MEMBER_NAME>(<MEMBER_PARAMS>);
+  virtual void On<MEMBER_NAME>(<MEMBER_PARAMS>) {}
+  </PUBLIC_MEMBERS*>
 
  private:
   using DispatchFunc = std::function<void(const UnitMap& unit_map)>;
 
-  <PRIVATE_MEMBERS>
+  <METHOD_ID>
+  <DISPATCHS*>
+  void Dispatch<NAME>(const UnitMap& unit_map);
+  </DISPATCHS*>
 
   bundle* GetBundleFromParcel(rpc_port_parcel_h parcel);
   rpc_port_parcel_h GetParcelFromBundle(bundle* b);
@@ -93,24 +84,12 @@ class <CLS_NAME> {
   bool is_system_;
   std::unordered_map<int, DispatchFunc> dispatch_funcs_;
 };
-)__cpp_cb";
 
-/**
- * <NAME> The method name.
- * <PARAMS> The parameters of the method.
- */
-constexpr const char CB_METHOD[] =
-R"__cpp_cb(
-void <NAME>(<PARAMS>);
-virtual void On<NAME>(<PARAMS>) {}
-)__cpp_cb";
+</INTERFACES*>
 
-/**
- * <NAME> The method name.
- */
-constexpr const char CB_DISPATCH_FUNC[] =
-R"__cpp_cb(
-void Dispatch<NAME>(const UnitMap& unit_map);
+}  // namespace group
+}  // namespace <FILE_NAMESPACE>
+}  // namespace rpc_port
 )__cpp_cb";
 
 }  // namespace version2
index 25b73b4e68384ea1621509f6cf57757486adf88f..94aac0d6e601d8fc827e811bbe226bc45b841861 100644 (file)
@@ -31,66 +31,48 @@ CppProxyBodyGenerator::CppProxyBodyGenerator(std::shared_ptr<Document> doc,
     : CppGeneratorBase(std::move(doc)), options_(std::move(options)) {}
 
 void CppProxyBodyGenerator::OnInitGen(std::ofstream& stream) {
-  GenVersion(stream);
-  GenIncludeProxyBodyHeader(stream);
-  GenIncludeDefaultHeaders(stream);
-  GenLogTag(stream, "RPC_PORT_PROXY");
-  GenLogDefinition(stream);
-  GenVersionDefinition(stream);
-  GenExportAPI(stream);
-  GenLemAnonymousNamespace(stream);
-  GenNamespace(stream);
-  GenLemAPI(stream);
+  ReplaceAll(CB_MAIN_PROXY_BODY)
+      .Replace("VERSION", std::string(FULLVER))
+      .Replace("FILENAME", GenIncludeProxyBodyHeader())
+      .Replace("INCLUDE_DEFAULT", GenIncludeDefaultHeaders())
+      .ChangeToLower("<FILE_NAMESPACE>", GetFileNamespace())
+      .Replace("STRUCTURES", GenLemBaseWithStructures())
+      .Replace("BASE_IMPL", GenBaseImpl())
+      .Replace("INTERFACES", GenInterfaces())
+      .Replace("LEM_APIS", GenLemAPI())
+      .Replace("RPC_PORT_INTERNALS", GenRpcPortInternals())
+      .Transform([&](std::string str) { return SmartIndent(str); })
+      .Out(stream);
 }
 
 void CppProxyBodyGenerator::OnFiniGen(std::ofstream& stream) {}
 
-void CppProxyBodyGenerator::GenIncludeProxyBodyHeader(std::ofstream& stream) {
+std::string CppProxyBodyGenerator::GenIncludeProxyBodyHeader() {
   std::string key(".cc");
   std::string header_file = FileName;
 
   auto found = header_file.rfind(key);
   if (found != std::string::npos)
     header_file.replace(found, key.length(), ".h");
-
-  ReplaceAll(CB_PROXY_BODY_HEADER)
-      .Change("<FILENAME>", header_file)
-      .Out(stream);
+  return header_file;
 }
 
-void CppProxyBodyGenerator::GenNamespace(std::ofstream& stream) {
-  ReplaceAll(CB_NAMESPACE_PROXY)
-      .ChangeToLower("<FILE_NAMESPACE>", GetFileNamespace())
-      .Change("<STRUCTURES>", GenLemBaseWithStructures())
-      .Change("<BASE_IMPL>", GenBaseImpl())
-      .Change("<INTERFACES>", GenInterfaces())
-      .Transform([&](std::string str) { return SmartIndent(str); })
-      .Out(stream);
-  stream << NLine(1);
-}
-
-void CppProxyBodyGenerator::GenLemAnonymousNamespace(std::ofstream& stream) {
-  stream << SmartIndent(CB_LEM_ANONYMOUS_NAMESPACE);
-  stream << NLine(1);
-}
-
-void CppProxyBodyGenerator::GenLemAPI(std::ofstream& stream) {
+std::string CppProxyBodyGenerator::GenLemAPI() {
   std::string input = basename(const_cast<char*>(options_->GetInput().c_str()));
   input = input.substr(0, input.find_last_of("."));
   std::string code = NLine(1);
   for (const auto& block : GetDocument().GetBlocks()) {
-    if (block->GetType() != Block::TYPE_INTERFACE)
-      continue;
+    if (block->GetType() != Block::TYPE_INTERFACE) continue;
 
     auto& iface = static_cast<Interface&>(*block);
     code += ReplaceAll(CB_LEM_API)
-        .Change("<CLS_NAME>", iface.GetID())
-        .ChangeToLower("<FILE_NAMESPACE>", GetFileNamespace())
-        .ChangeToLower("<INPUT_FILE>", input);
+                .Replace("CLS_NAME", iface.GetID())
+                .ChangeToLower("<FILE_NAMESPACE>", GetFileNamespace())
+                .ChangeToLower("<INPUT_FILE>", input);
     code += NLine(1);
   }
 
-  stream << SmartIndent(code);
+  return code;
 }
 
 std::string CppProxyBodyGenerator::GenLemBaseWithStructures() {
@@ -112,8 +94,7 @@ std::string CppProxyBodyGenerator::GenBaseImpl() {
 std::string CppProxyBodyGenerator::GenInterfaces() {
   std::string code;
   for (const auto& block : GetDocument().GetBlocks()) {
-    if (block->GetType() != Block::TYPE_INTERFACE)
-      continue;
+    if (block->GetType() != Block::TYPE_INTERFACE) continue;
 
     auto& iface = static_cast<Interface&>(*block);
     code += GenInterface(iface) + NLine(1);
@@ -125,54 +106,52 @@ std::string CppProxyBodyGenerator::GenInterfaces() {
 std::string CppProxyBodyGenerator::GenInterface(const Interface& iface) {
   return std::string(
       ReplaceAll(CB_INTERFACE_BASE)
-          .Change("<CLS_NAME>", iface.GetID())
-          .Change("<ENUMS>", GenEnumerations(iface.GetEnums()))
-          .Change("<CALLBACKS>", GenInterfaceCallbacks(iface))
-          .Change("<METHODS>", GenInterfaceMethods(iface)));
+          .Replace("HASH_METHOD", std::to_string(GetHashCode("[METHOD]")))
+          .Replace("HASH_DELEGATE", std::to_string(GetHashCode("delegate")))
+          .Replace("CLS_NAME", iface.GetID())
+          .Replace("ENUMS", GenEnumerations(iface.GetEnums()))
+          .Replace("CALLBACKS", GenInterfaceCallbacks(iface))
+          .Replace("METHODS", GenInterfaceMethods(iface)));
 }
 
 std::string CppProxyBodyGenerator::GenInterfaceCallbacks(
     const Interface& iface) {
   std::string code;
   code += ReplaceAll(CB_INTERFACE_CALKBACBASE_BASE)
-              .Change("<IFACE_NAME>", iface.GetID());
+              .Replace("IFACE_NAME", iface.GetID());
   code += NLine(1);
   for (const auto& decl : iface.GetDeclarations()) {
-    if (decl->GetMethodType() != Declaration::MethodType::DELEGATE)
-      continue;
-
-    code += ReplaceAll(CB_INTERFACE_CALLBACK)
-        .Change("<IFACE_NAME>", iface.GetID())
-        .Change("<CLS_NAME>", decl->GetID())
-        .Change("<PARAMS>", GetParameters(decl->GetParameters()))
-        .Change("<IMPL_RECEIVED_EVENT>\n",
-            GenInterfaceCallbackReceivedEvent(decl->GetParameters()));
+    if (decl->GetMethodType() != Declaration::MethodType::DELEGATE) continue;
+
+    code +=
+        ReplaceAll(CB_INTERFACE_CALLBACK)
+            .Repeat("MAP_READ", decl->GetParameters(),
+                    [&](auto& r, const auto& i) {
+                      auto& type = i->GetParameterType().GetBaseType();
+                      r.Replace("HASH_NAME",
+                                std::to_string(GetHashCode(i->GetID())))
+                          .Replace("TYPE", ConvertTypeToString(type))
+                          .Replace("NAME", i->GetID());
+                      return true;
+                    })
+            .Replace("IFACE_NAME", iface.GetID())
+            .Replace("CLS_NAME", decl->GetID())
+            .Replace("PARAMS", GetParameters(decl->GetParameters()))
+            .Replace("INVOKE_PARAMS", GenInvokeParams(decl->GetParameters()));
     code += NLine(1);
   }
 
   return RemoveLine(code);
 }
 
-std::string CppProxyBodyGenerator::GenInterfaceCallbackReceivedEvent(
-    const Parameters& params) {
+std::string CppProxyBodyGenerator::GenInvokeParams(const Parameters& params) {
   std::string callback_params;
-  std::string code;
   for (auto& param : params) {
-    auto& type = param->GetParameterType().GetBaseType();
-    code += ReplaceAll(CB_INTERFACE_CALLBACK_UNIT_MAP_READ)
-        .Change("<TYPE>", ConvertTypeToString(type))
-        .Change("<NAME>", param->GetID());
-
-    if (!callback_params.empty())
-      callback_params += ", ";
-
+    if (!callback_params.empty()) callback_params += ", ";
     callback_params += param->GetID() + "_";
   }
 
-  code += ReplaceAll(CB_INTERFACE_CALLBACK_INVOKE)
-      .Change("<PARAMS>", callback_params);
-
-  return RemoveLine(code);
+  return callback_params;
 }
 
 std::string CppProxyBodyGenerator::GenInterfaceMethods(const Interface& iface) {
@@ -187,61 +166,70 @@ std::string CppProxyBodyGenerator::GenInterfaceMethods(const Interface& iface) {
 }
 
 std::string CppProxyBodyGenerator::GenInterfaceMethod(const Interface& iface,
-    const Declaration& decl) {
+                                                      const Declaration& decl) {
+  auto reg_cb = [&](auto& r, const auto& i) {
+    if (i->GetParameterType().GetDirection() == ParameterType::Direction::OUT)
+      return false;
+    r.Remove("IF_DELEGATE_TYPE",
+             !IsDelegateType(i->GetParameterType().GetBaseType()))
+        .Remove("IF_NOT_DELEGATE_TYPE",
+                IsDelegateType(i->GetParameterType().GetBaseType()))
+        .Replace("NAME", i->GetID())
+        .Replace("PRIVATE_SHARING", GenPrivateSharing(*i));
+    return true;
+  };
+
   if (decl.GetMethodType() == Declaration::MethodType::ASYNC) {
     return std::string(
         ReplaceAll(CB_INTERFACE_METHOD_ASYNC_BASE)
-            .Change("<IFACE_NAME>", iface.GetID())
-            .Change("<NAME>", decl.GetID())
-            .Change("<PARAMS>", GetParameters(decl.GetParameters()))
-            .Change("<SERIALIZE>", GenInterfaceMethodSerialize(decl)));
+            .Repeat("REGISTER_CB", decl.GetParameters(), reg_cb)
+            .Repeat("SERIALIZE", decl.GetParameters(),
+                    [&](auto& r, const auto& i) {
+                      return GenInterfaceMethodSerialize(r, i);
+                    })
+            .Replace("HASH_METHOD", std::to_string(GetHashCode("[METHOD]")))
+            .Replace("IFACE_NAME", iface.GetID())
+            .Replace("NAME", decl.GetID())
+            .Replace("PARAMS", GetParameters(decl.GetParameters())));
   }
 
   return std::string(
       ReplaceAll(CB_INTERFACE_METHOD_BASE)
-          .Change("<RETURN_TYPE>", ConvertTypeToString(decl.GetType()))
-          .Change("<SET_INIT_VALUE>", GetSettingInitValue(decl.GetType()))
-          .Change("<IFACE_NAME>", iface.GetID())
-          .Change("<NAME>", decl.GetID())
-          .Change("<PARAMS>", GetParameters(decl.GetParameters()))
-          .Change("<SERIALIZE>", GenInterfaceMethodSerialize(decl))
-          .Change("<DESERIALIZE>", GenInterfaceMethodDeserialize(decl)));
-}
-
-std::string CppProxyBodyGenerator::GenInterfaceMethodSerialize(
-    const Declaration& decl) {
-  std::string code;
-  for (auto& param : decl.GetParameters()) {
-    if (param->GetParameterType().GetDirection() ==
-        ParameterType::Direction::OUT)
-      continue;
-
-    code += ReplaceAll(CB_INTERFACE_METHOD_UNIT_MAP_WRITE)
-        .Change("<NAME>", param->GetID());
-    if (IsDelegateType(param->GetParameterType().GetBaseType())) {
-      code += ReplaceAll(CB_INTERFACE_METHOD_DELEGATE_INSERT)
-          .Change("<NAME>", param->GetID());
-    } else {
-      code += GenPrivateSharing(*param);
-    }
-  }
-
-  return RemoveLine(code);
+          .Repeat("REGISTER_CB", decl.GetParameters(), reg_cb)
+          .Repeat("SERIALIZE", decl.GetParameters(),
+                  [&](auto& r, const auto& i) {
+                    return GenInterfaceMethodSerialize(r, i);
+                  })
+          .Repeat("DESERIALIZE", decl.GetParameters(),
+                  [&](auto& r, const auto& i) {
+                    if (i->GetParameterType().GetDirection() ==
+                        ParameterType::Direction::IN)
+                      return false;
+
+                    r.Replace("HASH_DNAME",
+                              std::to_string(GetHashCode(i->GetID())))
+                        .Replace("DNAME", i->GetID());
+                    return true;
+                  })
+          .Replace("HASH_REMOTE_EXCEPTION",
+                   std::to_string(GetHashCode("[REMOTE_EXCEPTION]")))
+          .Replace("HASH_RESULT", std::to_string(GetHashCode("[RESULT]")))
+          .Replace("HASH_METHOD", std::to_string(GetHashCode("[METHOD]")))
+          .Replace("RETURN_TYPE", ConvertTypeToString(decl.GetType()))
+          .Replace("SET_INIT_VALUE", GetSettingInitValue(decl.GetType()))
+          .Replace("IFACE_NAME", iface.GetID())
+          .Replace("NAME", decl.GetID())
+          .Replace("PARAMS", GetParameters(decl.GetParameters())));
 }
 
-std::string CppProxyBodyGenerator::GenInterfaceMethodDeserialize(
-    const Declaration& decl) {
-  std::string code;
-  for (auto& param : decl.GetParameters()) {
-    if (param->GetParameterType().GetDirection() ==
-        ParameterType::Direction::IN)
-      continue;
+bool CppProxyBodyGenerator::GenInterfaceMethodSerialize(
+    ReplaceAll& r, const std::unique_ptr<tidl::Parameter>& i) {
+  if (i->GetParameterType().GetDirection() == ParameterType::Direction::OUT)
+    return false;
 
-    code += ReplaceAll(CB_INTERFACE_METHOD_UNIT_MAP_READ)
-        .Change("<NAME>", param->GetID());
-  }
-
-  return RemoveLine(code);
+  r.Replace("HASH_SNAME", std::to_string(GetHashCode(i->GetID())))
+      .Replace("SNAME", i->GetID());
+  return true;
 }
 
 }  // namespace version2
index d4c2099be2a94838da0201ec58c1a0adeebffb79..46aaa814b98f1cf4d2e9c75e75f49edff677db03 100644 (file)
@@ -36,21 +36,19 @@ class CppProxyBodyGenerator : public CppGeneratorBase {
   void OnFiniGen(std::ofstream& stream) override;
 
  private:
-  void GenIncludeProxyBodyHeader(std::ofstream& stream);
-  void GenNamespace(std::ofstream& stream);
-  void GenLemAnonymousNamespace(std::ofstream& stream);
-  void GenLemAPI(std::ofstream& stream);
+  std::string GenIncludeProxyBodyHeader();
+  std::string GenLemAPI();
   std::string GenLemBaseWithStructures();
   std::string GenBaseImpl();
   std::string GenInterfaces();
   std::string GenInterface(const Interface& iface);
   std::string GenInterfaceCallbacks(const Interface& iface);
-  std::string GenInterfaceCallbackReceivedEvent(const Parameters& params);
+  std::string GenInvokeParams(const Parameters& params);
   std::string GenInterfaceMethods(const Interface& iface);
   std::string GenInterfaceMethod(const Interface& iface,
-      const Declaration& decl);
-  std::string GenInterfaceMethodSerialize(const Declaration& decl);
-  std::string GenInterfaceMethodDeserialize(const Declaration& decl);
+                                 const Declaration& decl);
+  bool GenInterfaceMethodSerialize(ReplaceAll& r,
+                                   const std::unique_ptr<tidl::Parameter>& i);
 
  private:
   std::shared_ptr<Options> options_;
index 57d83e3f3321cb649b627183cdd4f30f3a5bac6a..a0652b2755ea5ed97330f28a8cbc6be802bfe76a 100644 (file)
 namespace tidl {
 namespace version2 {
 
+constexpr const char CB_MAIN_PROXY_BODY[] =
+R"__cpp_cb(
 /**
- * <FILENAME> The filename of the proxy.
+ * Generated by tidlc <VERSION>.
  */
-constexpr const char CB_PROXY_BODY_HEADER[] =
-R"__cpp_cb(
+
 #include "<FILENAME>"
 
 #include <stdlib.h>
 #include <assert.h>
 #include <dlog.h>
+<INCLUDE_DEFAULT>
+
+#undef LOG_TAG
+#define LOG_TAG "RPC_PORT_PROXY"
+
+#undef _E
+#define _E(fmt, ...) dlog_print(DLOG_ERROR, LOG_TAG, "%s: %s(%d) > " fmt, basename(const_cast<char*>(__FILE__)), __FUNCTION__, __LINE__, ##__VA_ARGS__)
+
+#undef _W
+#define _W(fmt, ...) dlog_print(DLOG_WARN, LOG_TAG, "%s: %s(%d) > " fmt, basename(const_cast<char*>(__FILE__)), __FUNCTION__, __LINE__, ##__VA_ARGS__)
+
+#undef _I
+#define _I(fmt, ...) dlog_print(DLOG_INFO, LOG_TAG, "%s: %s(%d) > " fmt, basename(const_cast<char*>(__FILE__)), __FUNCTION__, __LINE__, ##__VA_ARGS__)
+
+#undef _D
+#define _D(fmt, ...) dlog_print(DLOG_DEBUG, LOG_TAG, "%s: %s(%d) > " fmt, basename(const_cast<char*>(__FILE__)), __FUNCTION__, __LINE__, ##__VA_ARGS__)
+
+#undef TIDL_VERSION
+#define TIDL_VERSION "<VERSION>"
+
+#undef EXPORT_API
+#define EXPORT_API extern "C" __attribute__ ((visibility("default")))
+
+namespace {
+
+std::atomic<unsigned int> seq_ { 0 };
+std::string appid_;
+
+const std::string& GetAppId() {
+  if (appid_.empty()) {
+    char* id = nullptr;
+    app_get_id(&id);
+    if (id == nullptr) {
+      _E("Failed to get app id");
+      return appid_;
+    }
+
+    appid_ = std::string(id);
+    free(id);
+  }
+
+  return appid_;
+}
+
+rpc_port_parcel_h Clone(rpc_port_parcel_h parcel) {
+  void* raw = nullptr;
+  unsigned int size = 0;
+  if (rpc_port_parcel_get_raw(parcel, &raw, &size) != RPC_PORT_ERROR_NONE) {
+    _E("Failed to get raw");
+    return nullptr;
+  }
+
+  rpc_port_parcel_h handle = nullptr;
+  rpc_port_parcel_create_from_raw(&handle, raw, size);
+  return handle;
+}
+
+<RPC_PORT_INTERNALS>
+
+}  // namespace
+
+namespace rpc_port {
+namespace <FILE_NAMESPACE> {
+
+<STRUCTURES>
+
+namespace proxy {
+
+<BASE_IMPL>
+<INTERFACES>
+
+}  // namespace proxy
+}  // namespace <FILE_NAMESPACE>
+}  // namespace rpc_port
+
+<LEM_APIS>
+
 )__cpp_cb";
 
 /**
@@ -86,27 +164,14 @@ R"__cpp_cb(
 void <IFACE_NAME>::<CLS_NAME>::OnReceived(<PARAMS>) {}
 
 void <IFACE_NAME>::<CLS_NAME>::OnReceivedEvent(const UnitMap& unit_map) {
-  <IMPL_RECEIVED_EVENT>
+  <MAP_READ*>
+  <TYPE> <NAME>_;
+  unit_map.Read(<HASH_NAME> /*<NAME>*/, <NAME>_);
+  </MAP_READ*>
+  OnReceived(<INVOKE_PARAMS>);
 }
 )__cpp_cb";
 
-/**
- * <NAME> The name of the parameter of the callback.
- */
-constexpr const char CB_INTERFACE_CALLBACK_UNIT_MAP_READ[] =
-R"__cpp_cb(
-<TYPE> <NAME>_;
-unit_map.Read("<NAME>", <NAME>_);
-)__cpp_cb";
-
-/**
- * <PARAMS> The parameters of the callback.
- */
-constexpr const char CB_INTERFACE_CALLBACK_INVOKE[] =
-R"__cpp_cb(
-OnReceived(<PARAMS>);
-)__cpp_cb";
-
 /**
  * <CLS_NAME> The class name of the interface.
  * <CALLBACKS> The callbacks of the interface.
@@ -212,7 +277,7 @@ void <CLS_NAME>::OnLocalReceived(rpc_port_parcel_h parcel) {
 
 void <CLS_NAME>::ProcessReceivedEvent(const UnitMap& unit_map) {
   CallbackBase callback;
-  unit_map.Read("delegate", callback);
+  unit_map.Read(<HASH_DELEGATE> /*delegate*/, callback);
 
   auto iter = delegate_list_.begin();
   while (iter != delegate_list_.end()) {
@@ -253,7 +318,7 @@ void <CLS_NAME>::ConsumeCommand(rpc_port_h port, int seq_num, UnitMap& unit_map)
     rpc_port_parcel_destroy(parcel);
 
     int cmd = -1;
-    unit_map.Read("[METHOD]", cmd);
+    unit_map.Read(<HASH_METHOD> /*[METHOD]*/, cmd);
     if (cmd == static_cast<int>(MethodId::__Result))
       return;
 
@@ -298,7 +363,7 @@ void <CLS_NAME>::OnReceivedCb(const char* endpoint, const char* port_name, void*
   rpc_port_parcel_destroy(parcel);
 
   int cmd = -1;
-  unit_map.Read("[METHOD]", cmd);
+  unit_map.Read(<HASH_METHOD> /*[METHOD]*/, cmd);
   if (cmd != static_cast<int>(MethodId::__Callback)) {
     _E("Invalid procotol");
     return;
@@ -329,10 +394,20 @@ void <IFACE_NAME>::<NAME>(<PARAMS>) {
   rpc_port_parcel_get_header(parcel_, &header_);
   rpc_port_parcel_header_set_tag(header_, TIDL_VERSION);
 
-  UnitMap map_;
-  map_.Write("[METHOD]", static_cast<int>(MethodId::<NAME>));
-  <SERIALIZE>
-  map_.Serialize(parcel_);;
+  UnitMap()
+      .Write(<HASH_METHOD> /*[METHOD]*/, static_cast<int>(MethodId::<NAME>))
+      <SERIALIZE*>
+      .Write(<HASH_SNAME> /*<SNAME>*/, <SNAME>)
+      </SERIALIZE*>
+      .Serialize(parcel_);
+  <REGISTER_CB*>
+  <IF_DELEGATE_TYPE?>
+  delegate_list_.push_back(std::move(<NAME>));
+  </IF_DELEGATE_TYPE?>
+  <IF_NOT_DELEGATE_TYPE?>
+  <PRIVATE_SHARING>
+  </IF_NOT_DELEGATE_TYPE?>
+  </REGISTER_CB*>
 
   std::lock_guard<std::recursive_mutex> lock(mutex_);
   int ret_;
@@ -376,10 +451,21 @@ R"__cpp_cb(
   int seq_num_ = -1;
   rpc_port_parcel_header_get_seq_num(header_, &seq_num_);
 
-  UnitMap map_;
-  map_.Write("[METHOD]", static_cast<int>(MethodId::<NAME>));
-  <SERIALIZE>
-  map_.Serialize(parcel_);
+  UnitMap()
+      .Write(<HASH_METHOD> /*[METHOD]*/, static_cast<int>(MethodId::<NAME>))
+      <SERIALIZE*>
+      .Write(<HASH_SNAME> /*<SNAME>*/, <SNAME>)
+      </SERIALIZE*>
+      .Serialize(parcel_);
+
+  <REGISTER_CB*>
+  <IF_DELEGATE_TYPE?>
+  delegate_list_.push_back(std::move(<NAME>));
+  </IF_DELEGATE_TYPE?>
+  <IF_NOT_DELEGATE_TYPE?>
+  <PRIVATE_SHARING>
+  </IF_NOT_DELEGATE_TYPE?>
+  </REGISTER_CB*>
 
   std::lock_guard<std::recursive_mutex> lock(mutex_);
   int ret_;
@@ -408,80 +494,20 @@ R"__cpp_cb(
     _E("received map size is zero");
   }
 
-  auto unit_ = received_map_.Lookup("[REMOTE_EXCEPTION]");
+  auto unit_ = received_map_.Lookup(<HASH_REMOTE_EXCEPTION> /*[REMOTE_EXCEPTION]*/);
   if (unit_ != nullptr) {
     RemoteException remote_except;
     unit_->Read(remote_except);
     throw remote_except;
   }
 
-  <DESERIALIZE>
-  received_map_.Read("[RESULT]", result_);
-  return result_;
-}
-)__cpp_cb";
-
-/**
- * <NAME> The name of the parameter.
- */
-constexpr const char CB_INTERFACE_METHOD_UNIT_MAP_WRITE[] =
-R"__cpp_cb(
-map_.Write("<NAME>", <NAME>);
-)__cpp_cb";
-
-/**
- * <NAME> The name of the parameter.
- */
-constexpr const char CB_INTERFACE_METHOD_DELEGATE_INSERT[] =
-R"__cpp_cb(
-delegate_list_.push_back(std::move(<NAME>));
-)__cpp_cb";
-
-/**
- * <NAME> The name of the parameter.
- */
-constexpr const char CB_INTERFACE_METHOD_UNIT_MAP_READ[] =
-R"__cpp_cb(
-received_map_.Read("<NAME>", <NAME>);
-)__cpp_cb";
+  <DESERIALIZE*>
+  received_map_.Read(<HASH_DNAME> /*<DNAME>*/, <DNAME>);
+  </DESERIALIZE*>
 
-constexpr const char CB_LEM_ANONYMOUS_NAMESPACE[] =
-R"__cpp_cb(
-namespace {
-
-std::atomic<unsigned int> seq_ { 0 };
-std::string appid_;
-
-const std::string& GetAppId() {
-  if (appid_.empty()) {
-    char* id = nullptr;
-    app_get_id(&id);
-    if (id == nullptr) {
-      _E("Failed to get app id");
-      return appid_;
-    }
-
-    appid_ = std::string(id);
-    free(id);
-  }
-
-  return appid_;
-}
-
-rpc_port_parcel_h Clone(rpc_port_parcel_h parcel) {
-  void* raw = nullptr;
-  unsigned int size = 0;
-  if (rpc_port_parcel_get_raw(parcel, &raw, &size) != RPC_PORT_ERROR_NONE) {
-    _E("Failed to get raw");
-    return nullptr;
-  }
-
-  rpc_port_parcel_h handle = nullptr;
-  rpc_port_parcel_create_from_raw(&handle, raw, size);
-  return handle;
+  received_map_.Read(<HASH_RESULT> /*[RESULT]*/, result_);
+  return result_;
 }
-
-}  // namespace
 )__cpp_cb";
 
 /**
index ce81daca0018bc2b2235cef81d99b229be8c1fba..e24ea7fa85a88ae4020e8b37ecb9bdf539367ccb 100644 (file)
@@ -29,23 +29,19 @@ CppProxyHeaderGenerator::CppProxyHeaderGenerator(
     : CppGeneratorBase(std::move(doc)), options_(std::move(options)) {}
 
 void CppProxyHeaderGenerator::OnInitGen(std::ofstream& stream) {
-  GenVersion(stream);
-  GenIncludeDefaultHeaders(stream, false);
-  GenNamespace(stream);
-}
-
-void CppProxyHeaderGenerator::OnFiniGen(std::ofstream& stream) {}
-
-void CppProxyHeaderGenerator::GenNamespace(std::ofstream& stream) {
-  ReplaceAll(CB_NAMESPACE_PROXY)
+  ReplaceAll(CB_MAIN_PROXY_HEADER)
+      .Replace("VERSION", std::string(FULLVER))
+      .Replace("INCLUDE_DEFAULT", GenIncludeDefaultHeaders(false))
       .ChangeToLower("<FILE_NAMESPACE>", GetFileNamespace())
-      .Change("<STRUCTURES>", GenLemBaseWithStructures())
-      .Change("<BASE_IMPL>", GenBaseImpl())
-      .Change("<INTERFACES>", GenInterfaces())
+      .Replace("STRUCTURES", GenLemBaseWithStructures())
+      .Replace("BASE_IMPL", GenBaseImpl())
+      .Replace("INTERFACES", GenInterfaces())
       .Transform([&](std::string str) { return SmartIndent(str); })
       .Out(stream);
 }
 
+void CppProxyHeaderGenerator::OnFiniGen(std::ofstream& stream) {}
+
 std::string CppProxyHeaderGenerator::GenLemBaseWithStructures() {
   std::string code = CB_LEM_BASE;
   code += NLine(1);
@@ -62,8 +58,7 @@ std::string CppProxyHeaderGenerator::GenBaseImpl() {
 std::string CppProxyHeaderGenerator::GenInterfaces() {
   std::string code;
   for (auto& block : GetDocument().GetBlocks()) {
-    if (block->GetType() != Block::TYPE_INTERFACE)
-      continue;
+    if (block->GetType() != Block::TYPE_INTERFACE) continue;
 
     auto& iface = static_cast<Interface&>(*block);
     code += GenInterface(iface) + NLine(1);
@@ -75,48 +70,41 @@ std::string CppProxyHeaderGenerator::GenInterfaces() {
 std::string CppProxyHeaderGenerator::GenInterface(const Interface& iface) {
   return std::string(
       ReplaceAll(CB_INTERFACE_BASE)
-          .Change("<CLS_NAME>", iface.GetID())
-          .Change("<ENUMS>", GenEnumerations(iface.GetEnums()))
-          .Change("<CALLBACKS>", GenInterfaceCallbacks(iface))
-          .Change("<METHODS>", GenInterfaceMethods(iface))
-          .Change("<METHOD_IDS>", GenMethodIds(iface))
-          .Change("<DELEGATE_IDS>", GenDelegateIds(iface)));
+          .Replace("CLS_NAME", iface.GetID())
+          .Replace("ENUMS", GenEnumerations(iface.GetEnums()))
+          .Replace("CALLBACKS", GenInterfaceCallbacks(iface))
+          .Repeat("METHODS", iface.GetDeclarations(),
+                  [&](auto& r, const auto& i) {
+                    if (i->GetMethodType() == Declaration::MethodType::DELEGATE)
+                      return false;
+                    r.Replace("METHOD_RETURN_TYPE",
+                              ConvertTypeToString(i->GetType()))
+                        .Replace("METHOD_NAME", i->GetID())
+                        .Replace("METHOD_PARAMS",
+                                 GetParameters(i->GetParameters()));
+                    return true;
+                  })
+          .Replace("METHOD_IDS", GenMethodIds(iface))
+          .Replace("DELEGATE_IDS", GenDelegateIds(iface)));
 }
 
 std::string CppProxyHeaderGenerator::GenInterfaceCallbacks(
     const Interface& iface) {
   std::string code;
   code += ReplaceAll(CB_INTERFACE_CALLBACK_BASE)
-              .Change("<IFACE_NAME>", iface.GetID());
+              .Replace("IFACE_NAME", iface.GetID());
   code += NLine(1);
   for (const auto& decl : iface.GetDeclarations()) {
-    if (decl->GetMethodType() != Declaration::MethodType::DELEGATE)
-      continue;
+    if (decl->GetMethodType() != Declaration::MethodType::DELEGATE) continue;
 
     code += ReplaceAll(CB_INTERFACE_CALLBACK)
-        .Change("<CLS_NAME>", decl->GetID())
-        .Change("<PARAMS>", GetParameters(decl->GetParameters()));
+                .Replace("CLS_NAME", decl->GetID())
+                .Replace("PARAMS", GetParameters(decl->GetParameters()));
     code += NLine(1);
   }
 
   return RemoveLine(code);
 }
 
-std::string CppProxyHeaderGenerator::GenInterfaceMethods(
-    const Interface& iface) {
-  std::string code;
-  for (const auto& decl : iface.GetDeclarations()) {
-    if (decl->GetMethodType() == Declaration::MethodType::DELEGATE)
-      continue;
-
-    code += ReplaceAll(CB_INTERFACE_METHOD)
-                .Change("<RETURN_TYPE>", ConvertTypeToString(decl->GetType()))
-                .Change("<NAME>", decl->GetID())
-                .Change("<PARAMS>", GetParameters(decl->GetParameters()));
-  }
-
-  return RemoveLine(code);
-}
-
 }  // namespace version2
 }  // namespace tidl
index 13b147e9cc50c7599a4ee185ee41e36d514a60a5..62c7868212af7713d5fcac7e3972e79e4e2fb3b4 100644 (file)
@@ -36,13 +36,11 @@ class CppProxyHeaderGenerator : public CppGeneratorBase {
   void OnFiniGen(std::ofstream& stream) override;
 
  private:
-  void GenNamespace(std::ofstream& stream);
   std::string GenLemBaseWithStructures();
   std::string GenBaseImpl();
   std::string GenInterfaces();
   std::string GenInterface(const Interface& iface);
   std::string GenInterfaceCallbacks(const Interface& iface);
-  std::string GenInterfaceMethods(const Interface& iface);
 
  private:
   std::shared_ptr<Options> options_;
index fcd08ef8cf03759c7466bfa41d1c2f8bc7cda184..47ffe24bdc5b6a29c882e9822b6cfb794755a0bd 100644 (file)
 namespace tidl {
 namespace version2 {
 
+constexpr const char CB_MAIN_PROXY_HEADER[] =
+R"__cpp_cb(
+/**
+ * Generated by tidlc <VERSION>.
+ */
+
+<INCLUDE_DEFAULT>
+
+namespace rpc_port {
+namespace <FILE_NAMESPACE> {
+
+<STRUCTURES>
+
+namespace proxy {
+
+<BASE_IMPL>
+<INTERFACES>
+
+}  // namespace proxy
+}  // namespace <FILE_NAMESPACE>
+}  // namespace rpc_port
+
+)__cpp_cb";
+
+
 /**
  * <IFACE_NAME> The interface name.
  */
@@ -143,7 +168,10 @@ class <CLS_NAME> : public LocalExecution::IEvent {
   /// <param name="tag">The tag string from delegate object</param>
   void DisposeCallback(const std::string& tag);
 
-  <METHODS>
+  <METHODS*>
+  <METHOD_RETURN_TYPE> <METHOD_NAME>(<METHOD_PARAMS>);
+  </METHODS*>
+
  private:
   <METHOD_IDS>
   <DELEGATE_IDS>
@@ -171,16 +199,6 @@ class <CLS_NAME> : public LocalExecution::IEvent {
 };
 )__cpp_cb";
 
-/**
- * <RETURN_TYPE> The return type of the method of the interface.
- * <NAME> The method name of the interface.
- * <PARAMS> The parameters of the method.
- */
-constexpr const char CB_INTERFACE_METHOD[] =
-R"__cpp_cb(
-<RETURN_TYPE> <NAME>(<PARAMS>);
-)__cpp_cb";
-
 constexpr const char CB_LEM_BASE[] =
 R"__cpp_cb(
 class LocalExecution : public std::enable_shared_from_this<LocalExecution> {
index 7d30b798bd49a7531aabca1f12448c9972ed7291..4695a092c1267b0afe30fa41dbc377c62686d0b2 100644 (file)
@@ -28,26 +28,29 @@ namespace tidl {
 namespace version2 {
 
 CppStubBodyGenerator::CppStubBodyGenerator(std::shared_ptr<Document> doc,
-    std::shared_ptr<Options> options)
+                                           std::shared_ptr<Options> options)
     : CppGeneratorBase(std::move(doc)), options_(std::move(options)) {}
 
 void CppStubBodyGenerator::OnInitGen(std::ofstream& stream) {
-  GenVersion(stream);
-  GenIncludeStubBodyHeader(stream);
-  GenIncludeDefaultHeaders(stream);
-  GenIncludeInternalHeader(stream);
-  GenLogTag(stream, "RPC_PORT_STUB");
-  GenLogDefinition(stream);
-  GenVersionDefinition(stream);
-  GenExportAPI(stream);
-  GenLemAnonymousNamespace(stream);
-  GenNamespace(stream);
-  GenLemAPI(stream);
+  ReplaceAll(CB_MAIN_STUB_BODY)
+      .Replace("VERSION", std::string(FULLVER))
+      .Replace("FILENAME", GenIncludeStubBodyHeader())
+      .Replace("INCLUDE_DEFAULT", GenIncludeDefaultHeaders())
+      .Replace("INCLUDE_INTERNAL", GenIncludeInternalHeader())
+      .Replace("LEM_CONTEXT", GenLemContext())
+      .ChangeToLower("<FILE_NAMESPACE>", GetFileNamespace())
+      .Replace("STRUCTURES", GenLemBaseWithStructures())
+      .Replace("BASE_IMPL", GenBaseImpl())
+      .Replace("INTERFACES", GenInterfaces())
+      .Replace("LEM_APIS", GenLemAPI())
+      .Replace("RPC_PORT_INTERNALS", GenRpcPortInternals())
+      .Transform([&](std::string code) { return SmartIndent(code); })
+      .Out(stream);
 }
 
 void CppStubBodyGenerator::OnFiniGen(std::ofstream& stream) {}
 
-void CppStubBodyGenerator::GenIncludeStubBodyHeader(std::ofstream& stream) {
+std::string CppStubBodyGenerator::GenIncludeStubBodyHeader() {
   std::string key(".cc");
   std::string header_file = FileName;
 
@@ -55,65 +58,43 @@ void CppStubBodyGenerator::GenIncludeStubBodyHeader(std::ofstream& stream) {
   if (found != std::string::npos)
     header_file.replace(found, key.length(), ".h");
 
-  ReplaceAll(CB_STUB_BODY_HEADER)
-      .Change("<FILENAME>", header_file)
-      .Out(stream);
-}
-
-void CppStubBodyGenerator::GenIncludeInternalHeader(std::ofstream& stream) {
-  if (options_->UseExtension()) stream << CB_INTERNAL_HEADER_INCLUSION;
-}
-
-void CppStubBodyGenerator::GenNamespace(std::ofstream& stream) {
-  ReplaceAll(CB_NAMESPACE_STUB)
-      .ChangeToLower("<FILE_NAMESPACE>", GetFileNamespace())
-      .Change("<STRUCTURES>", GenLemBaseWithStructures())
-      .Change("<BASE_IMPL>", GenBaseImpl())
-      .Change("<INTERFACES>", GenInterfaces())
-      .Transform([&](std::string str) { return SmartIndent(str); })
-      .Out(stream);
-  stream << NLine(1);
+  return header_file;
 }
 
-void CppStubBodyGenerator::GenLemAnonymousNamespace(std::ofstream& stream) {
-  ReplaceAll(CB_LEM_ANONYMOUS_NAMESPACE)
-      .Change("<LEM_CONTEXT>", GenLemContext())
-      .Transform([&](std::string code) { return SmartIndent(code); })
-      .Out(stream);
-  stream << NLine(1);
+std::string CppStubBodyGenerator::GenIncludeInternalHeader() {
+  if (options_->UseExtension()) return CB_INTERNAL_HEADER_INCLUSION;
+  return "";
 }
 
 std::string CppStubBodyGenerator::GenLemContext() {
   std::string code;
   for (const auto& block : GetDocument().GetBlocks()) {
-    if (block->GetType() != Block::TYPE_INTERFACE)
-      continue;
+    if (block->GetType() != Block::TYPE_INTERFACE) continue;
 
     auto& iface = static_cast<Interface&>(*block);
     code += ReplaceAll(CB_LEM_CONTEXT)
-        .Change("<IFACE_NAME>", iface.GetID())
-        .ChangeToLower("<FILE_NAMESPACE>", GetFileNamespace());
+                .Replace("IFACE_NAME", iface.GetID())
+                .ChangeToLower("<FILE_NAMESPACE>", GetFileNamespace());
   }
 
   return RemoveLine(code);
 }
 
-void CppStubBodyGenerator::GenLemAPI(std::ofstream& stream) {
+std::string CppStubBodyGenerator::GenLemAPI() {
   std::string input = basename(const_cast<char*>(options_->GetInput().c_str()));
   input = input.substr(0, input.find_last_of("."));
   std::string code = NLine(1);
   for (const auto& block : GetDocument().GetBlocks()) {
-    if (block->GetType() != Block::TYPE_INTERFACE)
-      continue;
+    if (block->GetType() != Block::TYPE_INTERFACE) continue;
 
     auto& iface = static_cast<Interface&>(*block);
     code += ReplaceAll(CB_LEM_API)
-        .Change("<CLS_NAME>", iface.GetID())
-        .ChangeToLower("<INPUT_FILE>", input);
+                .Replace("CLS_NAME", iface.GetID())
+                .ChangeToLower("<INPUT_FILE>", input);
     code += NLine(1);
   }
 
-  stream << SmartIndent(code);
+  return code;
 }
 
 std::string CppStubBodyGenerator::GenLemBaseWithStructures() {
@@ -135,8 +116,7 @@ std::string CppStubBodyGenerator::GenBaseImpl() {
 std::string CppStubBodyGenerator::GenInterfaces() {
   std::string code;
   for (const auto& block : GetDocument().GetBlocks()) {
-    if (block->GetType() != Block::TYPE_INTERFACE)
-      continue;
+    if (block->GetType() != Block::TYPE_INTERFACE) continue;
 
     auto& iface = static_cast<Interface&>(*block);
     code += GenInterface(iface) + NLine(1);
@@ -149,18 +129,16 @@ std::string CppStubBodyGenerator::GenInterfaces() {
 std::string CppStubBodyGenerator::GenInterface(const Interface& iface) {
   return std::string(
       ReplaceAll(CB_INTERFACE_BASE)
-          .Change("<CLS_NAME>", iface.GetID())
-          .Change("<CALLBACKS>", GenInterfaceCallbacks(iface))
-          .Change("<IMPL_SERVICE_BASE_THREAD_MEMBER_INIT>",
-                  GenInterfaceImplServiceBaseThreadMemberInit())
-          .Change("<IMPL_SERVICE_BASE_DISPATCH_FUNC_INIT>",
-                  GenInterfaceImplServiceBaseDispatchFuncInit(iface))
-          .Change("<IMPL_SERVICE_BASE_DISPATCH>",
-                  GenInterfaceImplServiceBaseDispatch())
-          .Change("<IMPL_SERVICE_BASE_DISPATCH_FUNCS>",
-                  GenInterfaceImplServiceBaseDispatchFuncs(iface))
-          .Change("<IMPL_SERVICE_BASE_SET_PRIVILEGE_MAP>",
-                  GenInterfaceImplServiceBaseSetPrivilegeMap(iface))
+          .Repeat("IMPL_SERVICE_BASE_DISPATCH_FUNC_INIT",
+                  iface.GetDeclarations(),
+                  [&](auto& r, const auto& i) {
+                    if (i->GetMethodType() == Declaration::MethodType::DELEGATE)
+                      return false;
+
+                    r.Replace("NAME", i->GetID())
+                        .Replace("IFACE_NAME", iface.GetID());
+                    return true;
+                  })
           .Repeat("IMPL_ADD_PRIVILEGE", iface.GetAttributes(),
                   [&](ReplaceAll& ra,
                       const std::unique_ptr<tidl::Attribute>& attr) {
@@ -176,7 +154,18 @@ std::string CppStubBodyGenerator::GenInterface(const Interface& iface) {
                                  return attr->GetKey() == "trusted" &&
                                         attr->GetValue() == "true";
                                }) == iface.GetAttributes().end())
-          .Change("<IMPL_SERVICE_BASE_EXTENSION>", [&]() {
+          .Replace("HASH_METHOD", std::to_string(GetHashCode("[METHOD]")))
+          .Replace("CLS_NAME", iface.GetID())
+          .Replace("CALLBACKS", GenInterfaceCallbacks(iface))
+          .Replace("IMPL_SERVICE_BASE_THREAD_MEMBER_INIT",
+                   GenInterfaceImplServiceBaseThreadMemberInit())
+          .Replace("IMPL_SERVICE_BASE_DISPATCH",
+                   GenInterfaceImplServiceBaseDispatch())
+          .Replace("IMPL_SERVICE_BASE_DISPATCH_FUNCS",
+                   GenInterfaceImplServiceBaseDispatchFuncs(iface))
+          .Replace("IMPL_SERVICE_BASE_SET_PRIVILEGE_MAP",
+                   GenInterfaceImplServiceBaseSetPrivilegeMap(iface))
+          .Replace("IMPL_SERVICE_BASE_EXTENSION", [&]() {
             if (options_->UseExtension())
               return "rpc_port_get_peer_info(port_, &pid_, &uid_);";
 
@@ -188,36 +177,37 @@ std::string CppStubBodyGenerator::GenInterfaceCallbacks(
     const Interface& iface) {
   std::string code;
   code += ReplaceAll(CB_INTERFACE_CALKBACBASE_BASE)
-              .Change("<IFACE_NAME>", iface.GetID());
+              .Replace("IFACE_NAME", iface.GetID());
   code += NLine(1);
   for (const auto& decl : iface.GetDeclarations()) {
-    if (decl->GetMethodType() != Declaration::MethodType::DELEGATE)
-      continue;
+    if (decl->GetMethodType() != Declaration::MethodType::DELEGATE) continue;
+
+    code +=
+        ReplaceAll(CB_INTERFACE_CALLBACK)
+            .Repeat("SERIALIZE", decl->GetParameters(),
+                    [&](auto& r, const auto& i) {
+                      r.Replace("HASH_NAME",
+                                std::to_string(GetHashCode(i->GetID())))
+                          .Replace("NAME", i->GetID());
+                      return true;
+                    })
+            .Repeat("PRIVATE_SHARINGS", decl->GetParameters(),
+                    [&](auto& r, const auto& i) {
+                      r.Replace("PRIVATE_SHARING", GenPrivateSharing(*i));
+                      return true;
+                    })
+            .Replace("HASH_METHOD", std::to_string(GetHashCode("[METHOD]")))
+            .Replace("HASH_DELEGATE", std::to_string(GetHashCode("delegate")))
+            .Replace("IFACE_NAME", iface.GetID())
+            .Replace("CLS_NAME", decl->GetID())
+            .Replace("PARAMS", GetParameters(decl->GetParameters()));
 
-    code += ReplaceAll(CB_INTERFACE_CALLBACK)
-        .Change("<IFACE_NAME>", iface.GetID())
-        .Change("<CLS_NAME>", decl->GetID())
-        .Change("<PARAMS>", GetParameters(decl->GetParameters()))
-        .Change("<SERIALIZE>",
-            GenInterfaceCallbackSerialize(decl->GetParameters()));
     code += NLine(1);
   }
 
   if (options_->IsThreadEnabled()) {
     code += ReplaceAll(CB_INTERFACE_PENDING_JOB)
-        .Change("<IFACE_NAME>", iface.GetID());
-  }
-
-  return RemoveLine(code);
-}
-
-std::string CppStubBodyGenerator::GenInterfaceCallbackSerialize(
-    const Parameters& params) {
-  std::string code;
-  for (auto& param : params) {
-    code += ReplaceAll(CB_INTERFACE_CALLBACK_UNIT_MAP_WRITE)
-        .Change("<NAME>", param->GetID());
-    code += GenPrivateSharing(*param);
+                .Replace("IFACE_NAME", iface.GetID());
   }
 
   return RemoveLine(code);
@@ -233,21 +223,6 @@ CppStubBodyGenerator::GenInterfaceImplServiceBaseThreadMemberInit() {
   return "";
 }
 
-std::string CppStubBodyGenerator::GenInterfaceImplServiceBaseDispatchFuncInit(
-    const Interface& iface) {
-  std::string code;
-  for (auto& decl : iface.GetDeclarations()) {
-    if (decl->GetMethodType() == Declaration::MethodType::DELEGATE)
-      continue;
-
-    code += ReplaceAll(CB_INTERFACE_IMPL_SERVICE_BASE_DISPATCH_FUNC_INIT)
-        .Change("<NAME>", decl->GetID())
-        .Change("<IFACE_NAME>", iface.GetID());
-  }
-
-  return RemoveLine(code);
-}
-
 std::string CppStubBodyGenerator::GenInterfaceImplServiceBaseDispatch() {
   std::string code;
   if (options_->IsThreadEnabled())
@@ -262,8 +237,7 @@ std::string CppStubBodyGenerator::GenInterfaceImplServiceBaseDispatchFuncs(
     const Interface& iface) {
   std::string code;
   for (const auto& decl : iface.GetDeclarations()) {
-    if (decl->GetMethodType() == Declaration::MethodType::DELEGATE)
-      continue;
+    if (decl->GetMethodType() == Declaration::MethodType::DELEGATE) continue;
 
     code += GenInterfaceImplServiceBaseDispatchFunc(iface, *decl);
   }
@@ -275,8 +249,7 @@ std::string CppStubBodyGenerator::GenInterfaceImplServiceBaseDispatchFunc(
     const Interface& iface, const Declaration& decl) {
   std::string params;
   for (auto& param : decl.GetParameters()) {
-    if (!params.empty())
-      params += ", ";
+    if (!params.empty()) params += ", ";
 
     auto& type = param->GetParameterType().GetBaseType();
     if (IsDelegateType(type))
@@ -288,19 +261,38 @@ std::string CppStubBodyGenerator::GenInterfaceImplServiceBaseDispatchFunc(
   if (decl.GetMethodType() == Declaration::MethodType::ASYNC) {
     return std::string(
         ReplaceAll(CB_INTERFACE_SERVICE_BASE_DISPATCH_FUNC_ASYNC)
-            .Change("<IFACE_NAME>", iface.GetID())
-            .Change("<NAME>", decl.GetID())
-            .Change("<PARAMS>", params)
-            .Change("<DESERIALIZE>", GenInterfaceServiceBaseDeserialize(decl)));
+            .Replace("IFACE_NAME", iface.GetID())
+            .Replace("NAME", decl.GetID())
+            .Replace("PARAMS", params)
+            .Replace("DESERIALIZE", GenInterfaceServiceBaseDeserialize(decl)));
   }
 
   return std::string(
       ReplaceAll(CB_INTERFACE_SERVICE_BASE_DISPATCH_FUNC)
-          .Change("<IFACE_NAME>", iface.GetID())
-          .Change("<NAME>", decl.GetID())
-          .Change("<PARAMS>", params)
-          .Change("<SERIALIZE>", GenInterfaceServiceBaseSerialize(decl))
-          .Change("<DESERIALIZE>", GenInterfaceServiceBaseDeserialize(decl)));
+          .Repeat("SERIALIZE", decl.GetParameters(),
+                  [&](auto& r, const auto& i) {
+                    if (i->GetParameterType().GetDirection() ==
+                        ParameterType::Direction::IN)
+                      return false;
+
+                    r.Replace("HASH_NAME",
+                              std::to_string(GetHashCode(i->GetID())))
+                        .Replace("NAME", i->GetID());
+                    return true;
+                  })
+          .Repeat("PRIVATE_SHARINGS", decl.GetParameters(),
+                  [&](auto& r, const auto& i) {
+                    r.Replace("PRIVATE_SHARING", GenPrivateSharing(*i));
+                    return true;
+                  })
+          .Replace("HASH_REMOTE_EXCEPTION",
+                   std::to_string(GetHashCode("[REMOTE_EXCEPTION]")))
+          .Replace("HASH_METHOD", std::to_string(GetHashCode("[METHOD]")))
+          .Replace("HASH_RESULT", std::to_string(GetHashCode("[RESULT]")))
+          .Replace("IFACE_NAME", iface.GetID())
+          .Replace("NAME", decl.GetID())
+          .Replace("PARAMS", params)
+          .Replace("DESERIALIZE", GenInterfaceServiceBaseDeserialize(decl)));
 }
 
 std::string CppStubBodyGenerator::GenInterfaceServiceBaseDeserialize(
@@ -310,41 +302,25 @@ std::string CppStubBodyGenerator::GenInterfaceServiceBaseDeserialize(
     auto& type = param->GetParameterType().GetBaseType();
     if (IsDelegateType(type)) {
       code += ReplaceAll(CB_INTERFACE_SERVICE_BASE_PARAM_DELEGATE)
-          .Change("<TYPE>", ConvertTypeToString(type))
-          .Change("<TYPE_NAME>", type.ToString())
-          .Change("<NAME>", param->GetID());
+                  .Replace("TYPE", ConvertTypeToString(type))
+                  .Replace("TYPE_NAME", type.ToString())
+                  .Replace("NAME", param->GetID());
     } else {
       code += ReplaceAll(CB_INTERFACE_SERVICE_BASE_PARAM_BASE)
-          .Change("<TYPE>", ConvertTypeToString(type))
-          .Change("<NAME>", param->GetID())
-          .Change("<SET_INIT_VALUE>", GetSettingInitValue(type));
+                  .Replace("TYPE", ConvertTypeToString(type))
+                  .Replace("NAME", param->GetID())
+                  .Replace("SET_INIT_VALUE", GetSettingInitValue(type));
     }
 
     if (param->GetParameterType().GetDirection() ==
         ParameterType::Direction::OUT)
       continue;
 
-    code += RemoveLine(
-        std::string(
-            ReplaceAll(CB_INTERFACE_SERVICE_BASE_UNIT_MAP_READ)
-                .Change("<TYPE>", ConvertTypeToString(type))
-                .Change("<NAME>", param->GetID())));
-  }
-
-  return RemoveLine(code);
-}
-
-std::string CppStubBodyGenerator::GenInterfaceServiceBaseSerialize(
-    const Declaration& decl) {
-  std::string code;
-  for (auto& param : decl.GetParameters()) {
-    if (param->GetParameterType().GetDirection() ==
-        ParameterType::Direction::IN)
-      continue;
-
-    code += ReplaceAll(CB_INTERFACE_SERVICE_BASE_UNIT_MAP_WRITE)
-        .Change("<NAME>", param->GetID());
-    code += GenPrivateSharing(*param);
+    code += RemoveLine(std::string(
+        ReplaceAll(CB_INTERFACE_SERVICE_BASE_UNIT_MAP_READ)
+            .Replace("HASH_NAME", std::to_string(GetHashCode(param->GetID())))
+            .Replace("TYPE", ConvertTypeToString(type))
+            .Replace("NAME", param->GetID())));
   }
 
   return RemoveLine(code);
@@ -356,18 +332,16 @@ std::string CppStubBodyGenerator::GenInterfaceImplServiceBaseSetPrivilegeMap(
   for (auto& decl : iface.GetDeclarations()) {
     std::string privileges;
     for (auto& attr : decl->GetAttributes()) {
-      if (attr->GetKey() != "privilege")
-        continue;
+      if (attr->GetKey() != "privilege") continue;
 
       privileges += "\"" + attr->GetValue() + "\"," + NLine(1);
     }
 
-    if (privileges.empty())
-      continue;
+    if (privileges.empty()) continue;
 
     code += ReplaceAll(CB_INTERFACE_SERVICE_BASE_SET_PRIVILEGE_MAP)
-        .Change("<PRIVILEGES>", privileges)
-        .Change("<METHOD>", decl->GetID());
+                .Replace("PRIVILEGES", privileges)
+                .Replace("METHOD", decl->GetID());
   }
 
   return RemoveLine(code);
@@ -377,8 +351,8 @@ std::string CppStubBodyGenerator::GenInterfaceExtensionBase(
     const Interface& iface) {
   std::string code;
   if (options_->UseExtension()) {
-    code +=
-        ReplaceAll(CB_INTERFACE_EXTENSION_BASE, "<CLS_NAME>", iface.GetID());
+    code += ReplaceAll(CB_INTERFACE_EXTENSION_BASE)
+                .Replace("CLS_NAME", iface.GetID());
   }
   return code;
 }
index 1e32865a418339e8de00db114ea3f4846dbdb25c..d12b908f4ba88167435a5a49774044fb3c972abd 100644 (file)
@@ -36,27 +36,21 @@ class CppStubBodyGenerator : public CppGeneratorBase {
   void OnFiniGen(std::ofstream& stream) override;
 
  private:
-  void GenIncludeInternalHeader(std::ofstream& stream);
-  void GenIncludeStubBodyHeader(std::ofstream& stream);
-  void GenLemAnonymousNamespace(std::ofstream& stream);
+  std::string GenIncludeInternalHeader();
+  std::string GenIncludeStubBodyHeader();
   std::string GenLemContext();
-  void GenLemAPI(std::ofstream& stream);
-  void GenNamespace(std::ofstream& stream);
+  std::string GenLemAPI();
   std::string GenLemBaseWithStructures();
   std::string GenBaseImpl();
   std::string GenInterfaces();
   std::string GenInterface(const Interface& iface);
   std::string GenInterfaceCallbacks(const Interface& iface);
-  std::string GenInterfaceCallbackSerialize(const Parameters& params);
   std::string GenInterfaceImplServiceBaseThreadMemberInit();
-  std::string GenInterfaceImplServiceBaseDispatchFuncInit(
-      const Interface& iface);
   std::string GenInterfaceImplServiceBaseDispatch();
   std::string GenInterfaceImplServiceBaseDispatchFuncs(const Interface& iface);
   std::string GenInterfaceImplServiceBaseDispatchFunc(const Interface& iface,
                                                       const Declaration& decl);
   std::string GenInterfaceServiceBaseDeserialize(const Declaration& decl);
-  std::string GenInterfaceServiceBaseSerialize(const Declaration& decl);
   std::string GenInterfaceImplServiceBaseSetPrivilegeMap(
       const Interface& iface);
   std::string GenInterfaceExtensionBase(const Interface& iface);
index 88eea6ee23253779ca7e613b364364ac39f990ff..0e6172137ac97c20c91580390f88cefa3cf78820 100644 (file)
@@ -23,8 +23,12 @@ namespace version2 {
 /**
  * <FILENAME> The filename of the stub.
  */
-constexpr const char CB_STUB_BODY_HEADER[] =
+constexpr const char CB_MAIN_STUB_BODY[] =
 R"__cpp_cb(
+/**
+ * Generated by tidlc <VERSION>.
+ */
+
 #include "<FILENAME>"
 
 #include <app_manager.h>
@@ -32,6 +36,84 @@ R"__cpp_cb(
 #include <dlog.h>
 #include <package_manager.h>
 #include <stdlib.h>
+
+<INCLUDE_DEFAULT>
+<INCLUDE_INTERNAL>
+
+#undef LOG_TAG
+#define LOG_TAG "RPC_PORT_STUB"
+
+#undef _E
+#define _E(fmt, ...) dlog_print(DLOG_ERROR, LOG_TAG, "%s: %s(%d) > " fmt, basename(const_cast<char*>(__FILE__)), __FUNCTION__, __LINE__, ##__VA_ARGS__)
+
+#undef _W
+#define _W(fmt, ...) dlog_print(DLOG_WARN, LOG_TAG, "%s: %s(%d) > " fmt, basename(const_cast<char*>(__FILE__)), __FUNCTION__, __LINE__, ##__VA_ARGS__)
+
+#undef _I
+#define _I(fmt, ...) dlog_print(DLOG_INFO, LOG_TAG, "%s: %s(%d) > " fmt, basename(const_cast<char*>(__FILE__)), __FUNCTION__, __LINE__, ##__VA_ARGS__)
+
+#undef _D
+#define _D(fmt, ...) dlog_print(DLOG_DEBUG, LOG_TAG, "%s: %s(%d) > " fmt, basename(const_cast<char*>(__FILE__)), __FUNCTION__, __LINE__, ##__VA_ARGS__)
+
+#undef TIDL_VERSION
+#define TIDL_VERSION "<VERSION>"
+
+#undef EXPORT_API
+#define EXPORT_API extern "C" __attribute__ ((visibility("default")))
+
+namespace {
+
+rpc_port_parcel_h Clone(rpc_port_parcel_h parcel) {
+  void* raw = nullptr;
+  unsigned int size = 0;
+  rpc_port_parcel_get_raw(parcel, &raw, &size);
+
+  rpc_port_parcel_h handle = nullptr;
+  rpc_port_parcel_create_from_raw(&handle, raw, size);
+  return handle;
+}
+
+bool IdleAddOnce(GMainContext* context, std::function<void()>* func) {
+  auto* source = g_idle_source_new();
+  if (source == nullptr) {
+    _E("Failed to create idle source");
+    return false;
+  }
+
+  g_source_set_callback(source, static_cast<GSourceFunc>(
+      [](gpointer user_data) {
+        auto* cb = static_cast<std::function<void()>*>(user_data);
+        (*cb)();
+        delete cb;
+        return G_SOURCE_REMOVE;
+      }), func, nullptr);
+  g_source_attach(source, context);
+  g_source_unref(source);
+  return true;
+}
+
+<LEM_CONTEXT>
+
+<RPC_PORT_INTERNALS>
+
+}  // namespace
+
+namespace rpc_port {
+namespace <FILE_NAMESPACE> {
+
+<STRUCTURES>
+
+namespace stub {
+
+<BASE_IMPL>
+<INTERFACES>
+
+}  // namespace stub
+}  // namespace <FILE_NAMESPACE>
+}  // namespace rpc_port
+
+<LEM_APIS>
+
 )__cpp_cb";
 
 /**
@@ -99,14 +181,18 @@ void <IFACE_NAME>::<CLS_NAME>::Invoke(<PARAMS>) {
   if (IsOnce() && !valid_)
       throw InvalidArgumentException();
 
-  UnitMap unit_map_;
-  unit_map_.Write("[METHOD]", static_cast<int>(MethodId::__Callback));
-  unit_map_.Write("delegate", *this);
-  <SERIALIZE>
-
   rpc_port_parcel_h parcel_;
   rpc_port_parcel_create(&parcel_);
-  unit_map_.Serialize(parcel_);
+  UnitMap()
+      .Write(<HASH_METHOD> /*[METHOD]*/, static_cast<int>(MethodId::__Callback))
+      .Write(<HASH_DELEGATE> /*delegate*/, *this)
+      <SERIALIZE*>
+      .Write(<HASH_NAME> /*<NAME>*/, <NAME>)
+      </SERIALIZE*>
+      .Serialize(parcel_);
+  <PRIVATE_SHARINGS*>
+  <PRIVATE_SHARING>
+  </PRIVATE_SHARINGS*>
 
   if (GetContext() != nullptr) {
     <IFACE_NAME>_context_->InvokeCallback(GetContext(), parcel_);
@@ -120,14 +206,6 @@ void <IFACE_NAME>::<CLS_NAME>::Invoke(<PARAMS>) {
 }
 )__cpp_cb";
 
-/**
- * <NAME> The name of the parameter of the callback.
- */
-constexpr const char CB_INTERFACE_CALLBACK_UNIT_MAP_WRITE[] =
-R"__cpp_cb(
-unit_map_.Write("<NAME>", <NAME>);
-)__cpp_cb";
-
 /**
  * <IFACE_NAME> The interface name.
  */
@@ -165,7 +243,9 @@ R"__cpp_cb(
   SetPrivilegeMap();
   <IMPL_SERVICE_BASE_THREAD_MEMBER_INIT>
   dispatch_funcs_ = {
-    <IMPL_SERVICE_BASE_DISPATCH_FUNC_INIT>
+    <IMPL_SERVICE_BASE_DISPATCH_FUNC_INIT*>
+    { static_cast<int>(MethodId::<NAME>), std::bind(&<IFACE_NAME>::ServiceBase::Dispatch<NAME>, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4) },
+    </IMPL_SERVICE_BASE_DISPATCH_FUNC_INIT*>
   };
 }
 
@@ -197,19 +277,20 @@ void <CLS_NAME>::ServiceBase::Dispatch(rpc_port_h port, rpc_port_h callback_port
 
   UnitMap unit_map_;
   unit_map_.Deserialize(parcel);
-  rpc_port_parcel_destroy(parcel);
 
   int cmd_ = -1;
-  unit_map_.Read("[METHOD]", cmd_);
+  unit_map_.Read(<HASH_METHOD> /*[METHOD]*/, cmd_);
 
   auto found = dispatch_funcs_.find(cmd_);
   if (found == dispatch_funcs_.end()) {
     _E("Unknown command(%d)", cmd_);
+    rpc_port_parcel_destroy(parcel);
     return;
   }
 
   auto& func = found->second;
   func(port, callback_port, seq_num, unit_map_);
+  rpc_port_parcel_destroy(parcel);
 }
 
 bool <CLS_NAME>::ServiceBase::PrivilegeInfoCb(const char* privilege_name, void *user_data) {
@@ -428,15 +509,6 @@ void <CLS_NAME>::OnLocalReceived(void* context, rpc_port_parcel_h parcel) {
 }
 )__cpp_cb";
 
-/**
- * <NAME> The method name of the interface.
- * <IFACE_NAME> The interface name.
- */
-constexpr const char CB_INTERFACE_IMPL_SERVICE_BASE_DISPATCH_FUNC_INIT[] =
-R"__cpp_cb(
-{ static_cast<int>(MethodId::<NAME>), std::bind(&<IFACE_NAME>::ServiceBase::Dispatch<NAME>, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4) },
-)__cpp_cb";
-
 constexpr const char CB_INTERFACE_IMPL_SERVICE_BASE_THREAD_MEMBER_INIT[] =
 R"__cpp_cb(
 active_object_ = std::unique_ptr<ActiveObject>(new ActiveObject());
@@ -482,33 +554,43 @@ void <IFACE_NAME>::ServiceBase::Dispatch<NAME>(rpc_port_h port, rpc_port_h callb
 constexpr const char CB_INTERFACE_SERVICE_BASE_DISPATCH_FUNC[] =
 R"__cpp_cb(
 void <IFACE_NAME>::ServiceBase::Dispatch<NAME>(rpc_port_h port, rpc_port_h callback_port, int seq_num, const UnitMap& unit_map) {
-  UnitMap map_;
+  rpc_port_parcel_h parcel_;
+  rpc_port_parcel_create(&parcel_);
+
+  rpc_port_parcel_header_h header_;
+  rpc_port_parcel_get_header(parcel_, &header_);
+  rpc_port_parcel_header_set_seq_num(header_, seq_num);
+
   if (!CheckPrivileges(static_cast<int>(MethodId::<NAME>))) {
     _E("Permission denied");
     RemoteException remote_except(RPC_PORT_ERROR_PERMISSION_DENIED, "Permission denied");
-    map_.Write("[REMOTE_EXCEPTION]", remote_except);
+    UnitMap()
+        .Write(<HASH_REMOTE_EXCEPTION> /*[REMOTE_EXCEPTION]*/, remote_except)
+        .Write(<HASH_METHOD> /*[METHOD]*/, static_cast<int>(MethodId::__Result))
+        .Serialize(parcel_);
   } else {
     <DESERIALIZE>
     try {
       auto ret_ = <NAME>(<PARAMS>);
-      map_.Write("[RESULT]", ret_);
-      <SERIALIZE>
+      UnitMap()
+          .Write(<HASH_RESULT> /*[RESULT]*/, ret_)
+          <SERIALIZE*>
+          .Write(<HASH_NAME> /*<NAME>*/, <NAME>)
+          </SERIALIZE*>
+          .Write(<HASH_METHOD> /*[METHOD]*/, static_cast<int>(MethodId::__Result))
+          .Serialize(parcel_);
+      <PRIVATE_SHARINGS*>
+      <PRIVATE_SHARING>
+      </PRIVATE_SHARINGS*>
     } catch (const RemoteException& e) {
       _E("Exception occurs. cause(%d), message(%s)", e.GetCause(), e.GetMessage().c_str());
-      map_.Write("[REMOTE_EXCEPTION]", e);
+      UnitMap()
+          .Write(<HASH_REMOTE_EXCEPTION> /*[REMOTE_EXCEPTION]*/, e)
+          .Write(<HASH_METHOD> /*[METHOD]*/, static_cast<int>(MethodId::__Result))
+          .Serialize(parcel_);
     }
   }
 
-  map_.Write("[METHOD]", static_cast<int>(MethodId::__Result));
-
-  rpc_port_parcel_h parcel_;
-  rpc_port_parcel_create(&parcel_);
-
-  rpc_port_parcel_header_h header_;
-  rpc_port_parcel_get_header(parcel_, &header_);
-  rpc_port_parcel_header_set_seq_num(header_, seq_num);
-
-  map_.Serialize(parcel_);
   if (GetContext() != nullptr)
     <IFACE_NAME>_context_->SendResult(GetContext(), parcel_);
   else
@@ -517,14 +599,6 @@ void <IFACE_NAME>::ServiceBase::Dispatch<NAME>(rpc_port_h port, rpc_port_h callb
 }
 )__cpp_cb";
 
-/**
- * <NAME> The name of the parameter.
- */
-constexpr const char CB_INTERFACE_SERVICE_BASE_UNIT_MAP_WRITE[] =
-R"__cpp_cb(
-map_.Write("<NAME>", <NAME>);
-)__cpp_cb";
-
 /**
  * <TYPE> The type of the parameter.
  * <NAME> The name of the parameter.
@@ -550,7 +624,7 @@ R"__cpp_cb(
  */
 constexpr const char CB_INTERFACE_SERVICE_BASE_UNIT_MAP_READ[] =
 R"__cpp_cb(
-unit_map.Read("<NAME>", <NAME>);
+unit_map.Read(<HASH_NAME> /*<NAME>*/, <NAME>);
 )__cpp_cb";
 
 /**
index 1c0620b462a092c2725d8f9d2aa3f5138be0c923..2c6107e172bf885b75cdfec9eb67759ab41f1d40 100644 (file)
@@ -25,27 +25,23 @@ namespace tidl {
 namespace version2 {
 
 CppStubHeaderGenerator::CppStubHeaderGenerator(std::shared_ptr<Document> doc,
-    std::shared_ptr<Options> options)
+                                               std::shared_ptr<Options> options)
     : CppGeneratorBase(std::move(doc)), options_(std::move(options)) {}
 
 void CppStubHeaderGenerator::OnInitGen(std::ofstream& stream) {
-  GenVersion(stream);
-  GenIncludeDefaultHeaders(stream, false);
-  GenNamespace(stream);
-}
-
-void CppStubHeaderGenerator::OnFiniGen(std::ofstream& stream) {}
-
-void CppStubHeaderGenerator::GenNamespace(std::ofstream& stream) {
-  ReplaceAll(CB_NAMESPACE_STUB)
+  ReplaceAll(CB_MAIN_STUB_HEADER)
+      .Replace("VERSION", std::string(FULLVER))
+      .Replace("INCLUDE_DEFAULT", GenIncludeDefaultHeaders(false))
       .ChangeToLower("<FILE_NAMESPACE>", GetFileNamespace())
-      .Change("<STRUCTURES>", GenLemBaseWithStructures())
-      .Change("<BASE_IMPL>", GenBaseImpl())
-      .Change("<INTERFACES>", GenInterfaces())
+      .Replace("STRUCTURES", GenLemBaseWithStructures())
+      .Replace("BASE_IMPL", GenBaseImpl())
+      .Replace("INTERFACES", GenInterfaces())
       .Transform([&](std::string str) { return SmartIndent(str); })
       .Out(stream);
 }
 
+void CppStubHeaderGenerator::OnFiniGen(std::ofstream& stream) {}
+
 std::string CppStubHeaderGenerator::GenLemBaseWithStructures() {
   std::string code = CB_LEM_BASE;
   code += NLine(1);
@@ -56,8 +52,7 @@ std::string CppStubHeaderGenerator::GenLemBaseWithStructures() {
 std::string CppStubHeaderGenerator::GenBaseImpl() {
   std::string code = GenExceptions();
   code += GenRemoteExceptionForHeader();
-  if (options_->IsThreadEnabled())
-    code += CB_THREAD_BASE;
+  if (options_->IsThreadEnabled()) code += CB_THREAD_BASE;
 
   return code;
 }
@@ -65,8 +60,7 @@ std::string CppStubHeaderGenerator::GenBaseImpl() {
 std::string CppStubHeaderGenerator::GenInterfaces() {
   std::string code;
   for (auto& block : GetDocument().GetBlocks()) {
-    if (block->GetType() != Block::TYPE_INTERFACE)
-      continue;
+    if (block->GetType() != Block::TYPE_INTERFACE) continue;
 
     auto& iface = static_cast<Interface&>(*block);
     code += GenInterface(iface) + NLine(1);
@@ -78,19 +72,33 @@ std::string CppStubHeaderGenerator::GenInterfaces() {
 std::string CppStubHeaderGenerator::GenInterface(const Interface& iface) {
   return std::string(
       ReplaceAll(CB_INTERFACE_BASE)
-          .Change("<CLS_NAME>", iface.GetID())
-          .Change("<CALLBACKS>", GenInterfaceCallbacks(iface))
-          .Change("<ENUMS>", GenEnumerations(iface.GetEnums()))
-          .Change("<SERVICE_BASE_METHODS>",
-                  GenInterfaceServiceBaseMethods(iface))
-          .Change("<SERVICE_BASE_DISPATCH_FUNCS>",
-                  GenInterfaceServiceBaseDispatchFuncs(iface))
-          .Change("<SERVICE_BASE_IMPL_THREAD_MEMBER>",
+          .Repeat("SERVICE_BASE_METHODS", iface.GetDeclarations(),
+                  [&](auto& r, const auto& i) {
+                    if (i->GetMethodType() == Declaration::MethodType::DELEGATE)
+                      return false;
+
+                    r.Replace("RETURN_TYPE", ConvertTypeToString(i->GetType()))
+                        .Replace("NAME", i->GetID())
+                        .Replace("PARAMS", GetParameters(i->GetParameters()));
+                    return true;
+                  })
+          .Repeat("SERVICE_BASE_DISPATCH_FUNCS", iface.GetDeclarations(),
+                  [&](auto& r, const auto& i) {
+                    if (i->GetMethodType() == Declaration::MethodType::DELEGATE)
+                      return false;
+
+                    r.Replace("NAME", i->GetID());
+                    return true;
+                  })
+          .Replace("CLS_NAME", iface.GetID())
+          .Replace("CALLBACKS", GenInterfaceCallbacks(iface))
+          .Replace("ENUMS", GenEnumerations(iface.GetEnums()))
+          .Replace("SERVICE_BASE_IMPL_THREAD_MEMBER",
                   GenInterfaceServiceBaseImplThreadMember())
-          .Change("<EXTENSION_BASE>", GenInterfaceExtensionBase())
-          .Change("<METHOD_IDS>", GenMethodIds(iface))
-          .Change("<DELEGATE_IDS>", GenDelegateIds(iface))
-          .Change("<SERVICE_BASE_EXTENSION>",
+          .Replace("EXTENSION_BASE", GenInterfaceExtensionBase())
+          .Replace("METHOD_IDS", GenMethodIds(iface))
+          .Replace("DELEGATE_IDS", GenDelegateIds(iface))
+          .Replace("SERVICE_BASE_EXTENSION",
                   GenInterfaceServiceBaseExtension()));
 }
 
@@ -98,50 +106,18 @@ std::string CppStubHeaderGenerator::GenInterfaceCallbacks(
     const Interface& iface) {
   std::string code;
   code += ReplaceAll(CB_INTERFACE_CALLBACK_BASE)
-              .Change("<IFACE_NAME>", iface.GetID());
+              .Replace("IFACE_NAME", iface.GetID());
   code += NLine(1);
   for (const auto& decl : iface.GetDeclarations()) {
-    if (decl->GetMethodType() != Declaration::MethodType::DELEGATE)
-      continue;
+    if (decl->GetMethodType() != Declaration::MethodType::DELEGATE) continue;
 
     code += ReplaceAll(CB_INTERFACE_CALLBACK)
-        .Change("<CLS_NAME>", decl->GetID())
-        .Change("<PARAMS>", GetParameters(decl->GetParameters()));
+                .Replace("CLS_NAME", decl->GetID())
+                .Replace("PARAMS", GetParameters(decl->GetParameters()));
     code += NLine(1);
   }
 
-  if (options_->IsThreadEnabled())
-    code += CB_INTERFACE_PENDING_JOB;
-
-  return RemoveLine(code);
-}
-
-std::string CppStubHeaderGenerator::GenInterfaceServiceBaseMethods(
-    const Interface& iface) {
-  std::string code;
-  for (const auto& decl : iface.GetDeclarations()) {
-    if (decl->GetMethodType() == Declaration::MethodType::DELEGATE)
-      continue;
-
-    code += ReplaceAll(CB_INTERFACE_SERVICE_BASE_METHOD)
-                .Change("<RETURN_TYPE>", ConvertTypeToString(decl->GetType()))
-                .Change("<NAME>", decl->GetID())
-                .Change("<PARAMS>", GetParameters(decl->GetParameters()));
-  }
-
-  return RemoveLine(code);
-}
-
-std::string CppStubHeaderGenerator::GenInterfaceServiceBaseDispatchFuncs(
-    const Interface& iface) {
-  std::string code;
-  for (const auto& decl : iface.GetDeclarations()) {
-    if (decl->GetMethodType() == Declaration::MethodType::DELEGATE)
-      continue;
-
-    code += ReplaceAll(CB_INTERFACE_SERVICE_BASE_DISPATCH_FUNC)
-                .Change("<NAME>", decl->GetID());
-  }
+  if (options_->IsThreadEnabled()) code += CB_INTERFACE_PENDING_JOB;
 
   return RemoveLine(code);
 }
index d12c3c7dd7f59f33581693eb0de319485123a73b..2cabed767733821752cd5382035a8dc286867dd0 100644 (file)
@@ -36,14 +36,11 @@ class CppStubHeaderGenerator : public CppGeneratorBase {
   void OnFiniGen(std::ofstream& stream) override;
 
  private:
-  void GenNamespace(std::ofstream& stream);
   std::string GenLemBaseWithStructures();
   std::string GenBaseImpl();
   std::string GenInterfaces();
   std::string GenInterface(const Interface& iface);
   std::string GenInterfaceCallbacks(const Interface& iface);
-  std::string GenInterfaceServiceBaseMethods(const Interface& iface);
-  std::string GenInterfaceServiceBaseDispatchFuncs(const Interface& iface);
   std::string GenInterfaceServiceBaseImplThreadMember();
   std::string GenInterfaceExtensionBase();
   std::string GenInterfaceServiceBaseExtension();
index 5031d562e0506ffa7aa8867bbb00c477f3f850a4..d3f53f63aa28fcdc464e8ffb78240dac1f2469d5 100644 (file)
 namespace tidl {
 namespace version2 {
 
+
+constexpr const char CB_MAIN_STUB_HEADER[] =
+R"__cpp_cb(
+/**
+ * Generated by tidlc <VERSION>.
+ */
+
+<INCLUDE_DEFAULT>
+
+namespace rpc_port {
+namespace <FILE_NAMESPACE> {
+
+<STRUCTURES>
+
+namespace stub {
+
+<BASE_IMPL>
+<INTERFACES>
+
+}  // namespace stub
+}  // namespace <FILE_NAMESPACE>
+}  // namespace rpc_port
+
+)__cpp_cb";
+
+
 constexpr const char CB_THREAD_BASE[] =
 R"__cpp_cb(
 class Job {
@@ -308,7 +334,10 @@ class <CLS_NAME> : public LocalExecution::IEvent {
     void Dispatch(rpc_port_h port, rpc_port_h callback_port, rpc_port_parcel_h parcel, std::shared_ptr<ServiceBase> service);
     void Dispatch(rpc_port_h port, rpc_port_h callback_port, rpc_port_parcel_h parcel);
 
-    <SERVICE_BASE_METHODS>
+    <SERVICE_BASE_METHODS*>
+    virtual <RETURN_TYPE> <NAME>(<PARAMS>) = 0;
+    </SERVICE_BASE_METHODS*>
+
     <SERVICE_BASE_EXTENSION>
 
    protected:
@@ -321,7 +350,9 @@ class <CLS_NAME> : public LocalExecution::IEvent {
     void LoadPrivileges();
     void SetPrivilegeMap();
     bool CheckPrivileges(int method_id);
-    <SERVICE_BASE_DISPATCH_FUNCS>
+    <SERVICE_BASE_DISPATCH_FUNCS*>
+    void Dispatch<NAME>(rpc_port_h port, rpc_port_h callback_port, int seq_num, const UnitMap& unit_map);
+    </SERVICE_BASE_DISPATCH_FUNCS*>
 
     <SERVICE_BASE_IMPL_THREAD_MEMBER>
 
@@ -374,24 +405,6 @@ class <CLS_NAME> : public LocalExecution::IEvent {
 };
 )__cpp_cb";
 
-/**
- * <RETURN_TYPE> The return type of the method of the interface.
- * <NAME> The method name of the interface.
- * <PARAMS> The parameters of the method.
- */
-constexpr const char CB_INTERFACE_SERVICE_BASE_METHOD[] =
-R"__cpp_cb(
-virtual <RETURN_TYPE> <NAME>(<PARAMS>) = 0;
-)__cpp_cb";
-
-/**
- * <NAME> The method name of the interface.
- */
-constexpr const char CB_INTERFACE_SERVICE_BASE_DISPATCH_FUNC[] =
-R"__cpp_cb(
-void Dispatch<NAME>(rpc_port_h port, rpc_port_h callback_port, int seq_num, const UnitMap& unit_map);
-)__cpp_cb";
-
 constexpr const char CB_INTERFACE_SERVICE_BASE_IMPL_THREAD_MEMBER[] =
 R"__cpp_cb(
 std::unique_ptr<ActiveObject> active_object_;
index ca359aaed9df229e75ba2d95cb4dc6c7082ba5d3..bc432f527140628bef87eabafe018d21bde048f5 100644 (file)
  * limitations under the License.
  */
 
+#include "idlc/gen/version2/rs_gen_base.h"
+
 #include <sys/stat.h>
 #include <unistd.h>
 
 #include <ctime>
 #include <vector>
 
-#include "idlc/gen/version2/rs_gen_base.h"
-
 #if (defined(_WIN32) || defined(__WIN32__))
 #define mkdir(A, B) mkdir(A)
 #endif
@@ -39,63 +39,47 @@ std::string GetBaseTypeName(const std::shared_ptr<tidl::Structure>& base) {
 }
 
 void GetElementsFromStructure(Elements* elms,
-    const std::shared_ptr<Structure>& base) {
+                              const std::shared_ptr<Structure>& base) {
   if (base->GetBase() != nullptr)
     GetElementsFromStructure(elms, base->GetBase());
 
-  for (auto elm : base->GetElements())
-    elms->Add(elm);
+  for (auto elm : base->GetElements()) elms->Add(elm);
 }
 
 Elements GetElements(const Structure& st) {
   Elements elms;
-  if (st.GetBase() != nullptr)
-    GetElementsFromStructure(&elms, st.GetBase());
+  if (st.GetBase() != nullptr) GetElementsFromStructure(&elms, st.GetBase());
 
-  for (auto elm : st.GetElements())
-    elms.Add(elm);
+  for (auto elm : st.GetElements()) elms.Add(elm);
 
   return elms;
 }
 
-} //namespace
+}  // namespace
 
 RsGeneratorBase::RsGeneratorBase(std::shared_ptr<Document> doc)
     : Generator(doc) {
   type_map_ = {
-      {"char", "i8"}, {"int", "i32"}, {"short", "i16"},
-      {"long", "i64"}, {"string", "String"}, {"bool", "bool"},
-      {"list", "LinkedList"}, {"array", "Vec"}, {"float", "f32"},
-      {"double", "f64"}, {"bundle", "Bundle"}, {"void", "()"},
-      {"file", "String"}, {"map", "HashMap"}, {"set", "HashSet"}
-  };
+      {"char", "i8"},         {"int", "i32"},       {"short", "i16"},
+      {"long", "i64"},        {"string", "String"}, {"bool", "bool"},
+      {"list", "LinkedList"}, {"array", "Vec"},     {"float", "f32"},
+      {"double", "f64"},      {"bundle", "Bundle"}, {"void", "()"},
+      {"file", "String"},     {"map", "HashMap"},   {"set", "HashSet"}};
 
   parcel_type_map_ = {
-    {"char", "byte"},
-    {"int", "int32"},
-    {"short", "int16"},
-    {"long", "int64"},
-    {"string", "string"},
-    {"bool", "bool"},
-    {"float", "float"},
-    {"double", "double"},
-    {"bundle", "bundle"},
-    {"file", "string"},
+      {"char", "byte"},   {"int", "int32"},     {"short", "int16"},
+      {"long", "int64"},  {"string", "string"}, {"bool", "bool"},
+      {"float", "float"}, {"double", "double"}, {"bundle", "bundle"},
+      {"file", "string"},
   };
 
   type_init_map_ = {
-    {"char", "0"},
-    {"int", "0"},
-    {"short", "0"},
-    {"long", "0"},
-    {"bool", "false"},
-    {"float", "0.0f"},
-    {"double", "0.0"},
+      {"char", "0"},     {"int", "0"},      {"short", "0"},    {"long", "0"},
+      {"bool", "false"}, {"float", "0.0f"}, {"double", "0.0"},
   };
 
   for (auto& block : GetDocument().GetBlocks()) {
-    if (block->GetType() != Block::TYPE_STRUCTURE)
-      continue;
+    if (block->GetType() != Block::TYPE_STRUCTURE) continue;
 
     auto& st = static_cast<const Structure&>(*block);
     AddTypeName(st);
@@ -118,34 +102,43 @@ void RsGeneratorBase::OnInitGen(std::ofstream& stream) {
   stream.open(FileName + "/impl_internal.rs");
   ReplaceAll(CB_COMMON_MAIN)
       .Repeat("WRITE_PARCELS", GetDocument().GetBlocks(),
-          [&](ReplaceAll& ra, const std::shared_ptr<Block>& i) {
-        return SetParcels(ra, i);
-      })
+              [&](ReplaceAll& ra, const std::shared_ptr<Block>& i) {
+                return SetParcels(ra, i);
+              })
       .Repeat("READ_PARCELS", GetDocument().GetBlocks(),
-          [&](ReplaceAll& ra, const std::shared_ptr<Block>& i) {
-        return SetParcels(ra, i);
-      })
+              [&](ReplaceAll& ra, const std::shared_ptr<Block>& i) {
+                return SetParcels(ra, i);
+              })
       .Remove("READ_EXCEPTION", GetChannelType() == ChannelType::TYPE_GROUP)
       .Remove("WRITE_EXCEPTION", GetChannelType() == ChannelType::TYPE_GROUP)
       .Remove("BUNDLE_HEADER_BLOCK", HasBundle() != true)
       .Remove("BUNDLE_BLOCK", HasBundle() != true)
       .Repeat("WRITE_ENUMS", GetDocument().GetBlocks(),
-          [&](ReplaceAll& ra, const std::shared_ptr<Block>& i) {
-        return SetEnumParcels(ra, i);
-      })
+              [&](ReplaceAll& ra, const std::shared_ptr<Block>& i) {
+                return SetEnumParcels(ra, i);
+              })
       .Repeat("READ_ENUMS", GetDocument().GetBlocks(),
-          [&](ReplaceAll& ra, const std::shared_ptr<Block>& i) {
-        return SetEnumParcels(ra, i);
-      })
-      .ReplaceBlock("META_PARCELS", [&](ReplaceAll& ra) {
-        return SetMetaParcelBlock(ra);
-      })
+              [&](ReplaceAll& ra, const std::shared_ptr<Block>& i) {
+                return SetEnumParcels(ra, i);
+              })
+      .ReplaceBlock("META_PARCELS",
+                    [&](ReplaceAll& ra) { return SetMetaParcelBlock(ra); })
+      .Replace("HASH_CHAR", std::to_string(GetHashCode("char")))
+      .Replace("HASH_SHORT", std::to_string(GetHashCode("short")))
+      .Replace("HASH_INT", std::to_string(GetHashCode("int")))
+      .Replace("HASH_LONG", std::to_string(GetHashCode("long")))
+      .Replace("HASH_FLOAT", std::to_string(GetHashCode("float")))
+      .Replace("HASH_DOUBLE", std::to_string(GetHashCode("double")))
+      .Replace("HASH_BOOL", std::to_string(GetHashCode("bool")))
+      .Replace("HASH_STRING", std::to_string(GetHashCode("string")))
+      .Replace("HASH_REMOTE_EXCEPTION",
+               std::to_string(GetHashCode("remote_exception")))
+      .Replace("HASH_BUNDLE", std::to_string(GetHashCode("bundle")))
       .Out(stream);
   stream.close();
 }
 
-void RsGeneratorBase::OnFiniGen(std::ofstream& stream) {
-}
+void RsGeneratorBase::OnFiniGen(std::ofstream& stream) {}
 
 bool RsGeneratorBase::HasBundle() {
   for (auto& i : GetDocument().GetBlocks()) {
@@ -153,17 +146,20 @@ bool RsGeneratorBase::HasBundle() {
       Structure& st = static_cast<Structure&>(*i);
       auto elms = GetElements(st);
       for (auto& e : elms) {
-        if (ConvertTypeToString(e->GetType(), i).find("Bundle") != std::string::npos) {
+        if (ConvertTypeToString(e->GetType(), i).find("Bundle") !=
+            std::string::npos) {
           return true;
         }
       }
     } else if (i->GetType() == Block::TYPE_INTERFACE) {
       Interface& iface = static_cast<Interface&>(*i);
       for (auto& d : iface.GetDeclarations()) {
-        if (GetParameters(d->GetParameters()).find("Bundle") != std::string::npos) {
+        if (GetParameters(d->GetParameters()).find("Bundle") !=
+            std::string::npos) {
           return true;
         }
-        if (ConvertTypeToString((*d).GetType()).find("Bundle") != std::string::npos) {
+        if (ConvertTypeToString((*d).GetType()).find("Bundle") !=
+            std::string::npos) {
           return true;
         }
       }
@@ -174,39 +170,38 @@ bool RsGeneratorBase::HasBundle() {
 }
 
 bool RsGeneratorBase::SetEnum(ReplaceAll& ra, const std::unique_ptr<Enum>& e) {
-  ra.Repeat("PROPERTIES",  e->GetFields(),
-        [&](ReplaceAll& ra, const std::unique_ptr<Field>& f) {
-      if (f->GetValue().empty()) {
-        ra.Replace("ID", f->GetID());
-      } else {
-        ra.Replace("ID", f->GetID() + " = " + f->GetValue());
-      }
-      return true;
-      })
-    .Replace("ENUM_NAME", e->GetID());
+  ra.Repeat("PROPERTIES", e->GetFields(),
+            [&](ReplaceAll& ra, const std::unique_ptr<Field>& f) {
+              if (f->GetValue().empty()) {
+                ra.Replace("ID", f->GetID());
+              } else {
+                ra.Replace("ID", f->GetID() + " = " + f->GetValue());
+              }
+              return true;
+            })
+      .Replace("ENUM_NAME", e->GetID());
   return true;
 }
 
 bool RsGeneratorBase::SetStructs(ReplaceAll& ra,
-    const std::shared_ptr<Block>& i) {
-  if (i->GetType() != Block::TYPE_STRUCTURE)
-    return false;
+                                 const std::shared_ptr<Block>& i) {
+  if (i->GetType() != Block::TYPE_STRUCTURE) return false;
 
-  ra.Repeat("ENUM",  i->GetEnums(),
-      [&](ReplaceAll& ra, const std::unique_ptr<Enum>& e) {
-    return SetEnum(ra, e);
-  });
+  ra.Repeat("ENUM", i->GetEnums(),
+            [&](ReplaceAll& ra, const std::unique_ptr<Enum>& e) {
+              return SetEnum(ra, e);
+            });
 
   Structure& st = static_cast<Structure&>(*i);
   auto elms = GetElements(st);
   ra.Replace("STRUCT_MOD_NAME", PascalToSnake(st.GetID()))
-    .Replace("STRUCT_NAME", st.GetID())
-    .Repeat("PROPERTIES", elms,
-        [&](ReplaceAll& ra, const std::shared_ptr<Element>& e) {
-      ra.Replace("ID", PascalToSnake(e->GetID()))
-        .Replace("TYPE", ConvertTypeToString(e->GetType(), i));
-      return true;
-    });
+      .Replace("STRUCT_NAME", st.GetID())
+      .Repeat("PROPERTIES", elms,
+              [&](ReplaceAll& ra, const std::shared_ptr<Element>& e) {
+                ra.Replace("ID", PascalToSnake(e->GetID()))
+                    .Replace("TYPE", ConvertTypeToString(e->GetType(), i));
+                return true;
+              });
   return true;
 }
 
@@ -222,43 +217,45 @@ std::string RsGeneratorBase::GetStructTypeString(const Structure& st) {
 }
 
 bool RsGeneratorBase::SetEnumParcels(ReplaceAll& ra,
-    const std::shared_ptr<Block>& i) {
-  ra.Repeat("ENUMS",  i->GetEnums(), [&](ReplaceAll& ra,
-      const std::unique_ptr<Enum>& e) {
-    ra.Repeat("MATCH_PROPERTIES", e->GetFields(),
-          [&](ReplaceAll& ra, const std::unique_ptr<Field>& f) {
-        ra.Replace("FIELD", f->GetID());
-        return true;
-      })
-      .Replace("ENUM_NAME", e->GetID());
-      return true;
-    })
-    .Replace("BLOCK_NAME", PascalToSnake(i->GetID()));
+                                     const std::shared_ptr<Block>& i) {
+  ra.Repeat("ENUMS", i->GetEnums(),
+            [&](ReplaceAll& ra, const std::unique_ptr<Enum>& e) {
+              ra.Repeat("MATCH_PROPERTIES", e->GetFields(),
+                        [&](ReplaceAll& ra, const std::unique_ptr<Field>& f) {
+                          ra.Replace("FIELD", f->GetID());
+                          return true;
+                        })
+                  .Replace("ENUM_NAME", e->GetID());
+              return true;
+            })
+      .Replace("BLOCK_NAME", PascalToSnake(i->GetID()));
 
   return true;
 }
 
 bool RsGeneratorBase::SetParcels(ReplaceAll& ra,
-    const std::shared_ptr<Block>& i) {
-  if (i->GetType() != Block::TYPE_STRUCTURE)
-    return false;
+                                 const std::shared_ptr<Block>& i) {
+  if (i->GetType() != Block::TYPE_STRUCTURE) return false;
   const Structure& st = static_cast<const Structure&>(*i);
   auto elms = GetElements(st);
   ra.Replace("MOD_NAME", PascalToSnake(st.GetID()))
-    .Replace("TYPE", st.GetID())
-    .Repeat("PARCEL_BODY", elms, [&](ReplaceAll& ra,
-        const std::shared_ptr<Element>& e) {
-      ra.Replace("ID", PascalToSnake(e->GetID()));
-      return true;
-    })
-    .Repeat("UNIT_BODY", elms, [&](ReplaceAll& ra,
-        const std::shared_ptr<Element>& e) {
-      ra.Replace("ID", PascalToSnake(e->GetID()))
-        .Replace("REAL_ID", e->GetID())
-        .Replace("INSIDE_TYPE", ConvertTypeToString(e->GetType(), i, false));
-      return true;
-    })
-    .Replace("UNIT_TYPE", GetStructTypeString(st));
+      .Replace("TYPE", st.GetID())
+      .Repeat("PARCEL_BODY", elms,
+              [&](ReplaceAll& ra, const std::shared_ptr<Element>& e) {
+                ra.Replace("ID", PascalToSnake(e->GetID()));
+                return true;
+              })
+      .Repeat("UNIT_BODY", elms,
+              [&](ReplaceAll& ra, const std::shared_ptr<Element>& e) {
+                ra.Replace("ID", PascalToSnake(e->GetID()))
+                    .Replace("REAL_ID", e->GetID())
+                    .Replace("INSIDE_TYPE",
+                             ConvertTypeToString(e->GetType(), i, false));
+                return true;
+              })
+      .Replace("HASH_UNIT_TYPE",
+               std::to_string(GetHashCode(GetStructTypeString(st))))
+      .Replace("UNIT_TYPE", GetStructTypeString(st));
   return true;
 }
 
@@ -302,21 +299,23 @@ void RsGeneratorBase::SetMetaParcelBlock(ReplaceAll& ra) {
 
       if (type.GetValueType()) {
         value_str = type.GetValueType()->ToString();
-        inside_value_str = ConvertTypeToString(
-            *type.GetValueType(), nullptr, false);
+        inside_value_str =
+            ConvertTypeToString(*type.GetValueType(), nullptr, false);
       }
     }
 
     target.Replace("TYPE", ConvertTypeToString(type, nullptr, false))
-          .Replace("TYPE_ID", GetFullNameFromType(type))
-          .RemoveAll("LIST", type.ToString() != "list")
-          .RemoveAll("ARRAY", type.ToString() != "array")
-          .RemoveAll("SET", type.ToString() != "set")
-          .RemoveAll("MAP", type.ToString() != "map")
-          .Replace("UNIT_TYPE", unit_str)
-          .Replace("UNIT_VALUE_TYPE", value_str)
-          .Replace("INSIDE_TYPE", inside_str)
-          .Replace("INSIDE_VALUE_TYPE", inside_value_str);
+        .Replace("TYPE_ID", GetFullNameFromType(type))
+        .Replace("HASH_TYPE_ID",
+                 std::to_string(GetHashCode(GetFullNameFromType(type))))
+        .RemoveAll("LIST", type.ToString() != "list")
+        .RemoveAll("ARRAY", type.ToString() != "array")
+        .RemoveAll("SET", type.ToString() != "set")
+        .RemoveAll("MAP", type.ToString() != "map")
+        .Replace("UNIT_TYPE", unit_str)
+        .Replace("UNIT_VALUE_TYPE", value_str)
+        .Replace("INSIDE_TYPE", inside_str)
+        .Replace("INSIDE_VALUE_TYPE", inside_value_str);
     ret += target;
   }
 
@@ -332,19 +331,15 @@ void RsGeneratorBase::AddMetaTypeList(const BaseType& type) {
   if (type.GetValueType() != nullptr) {
     auto value_type = type.GetValueType();
     meta_type_list_[ConvertTypeToString(type)] = &type;
-    if (value_type->GetMetaType() != nullptr)
-      AddMetaTypeList(*value_type);
+    if (value_type->GetMetaType() != nullptr) AddMetaTypeList(*value_type);
   }
-
 }
 
 std::string RsGeneratorBase::GetFullNameFromType(const BaseType& type) {
   auto found = struct_types_.find(type.GetFullName(true));
-  if (found != struct_types_.end())
-    return found->second;
+  if (found != struct_types_.end()) return found->second;
 
-  if (type.IsEnumType())
-    return "int";
+  if (type.IsEnumType()) return "int";
 
   if (IsDelegateType(type) ||
       type.ToString().find("::CallbackBase") != std::string::npos)
@@ -355,7 +350,7 @@ std::string RsGeneratorBase::GetFullNameFromType(const BaseType& type) {
 }
 
 std::string RsGeneratorBase::GetEnumTypeString(const std::string& type,
-    bool use_underbar) {
+                                               bool use_underbar) {
   std::string concatenated_char = use_underbar ? "_" : "::";
   auto pos = type.find('.');
   if (pos == std::string::npos) {
@@ -374,16 +369,15 @@ std::string RsGeneratorBase::GetEnumTypeString(const std::string& type,
 std::string RsGeneratorBase::GetClassNameFromEnumType(const std::string& type) {
   for (auto& block : GetDocument().GetBlocks()) {
     for (const auto& e : block->GetEnums()) {
-      if (e->GetID() == type)
-        return block->GetID();
+      if (e->GetID() == type) return block->GetID();
     }
   }
 
   return {};
 }
 
-std::string RsGeneratorBase::ConvertTypeToString(const BaseType& type,
-    const std::shared_ptr<Block>& i, bool definition) {
+std::string RsGeneratorBase::ConvertTypeToString(
+    const BaseType& type, const std::shared_ptr<Block>& i, bool definition) {
   if (type.IsEnumType()) {
     std::string str = type.ToString();
     size_t pos = str.find(".");
@@ -401,14 +395,13 @@ std::string RsGeneratorBase::ConvertTypeToString(const BaseType& type,
         if (!base_id.empty())
           return base_id + "::" + str;
         else if (!definition)
-          return PascalToSnake(st.GetID()) + "::" +str;
+          return PascalToSnake(st.GetID()) + "::" + str;
         else
           return str;
       } else {
         if (!definition) {
           for (auto& block : GetDocument().GetBlocks()) {
-            if (block->GetType() == Block::TYPE_STRUCTURE)
-              continue;
+            if (block->GetType() == Block::TYPE_STRUCTURE) continue;
             for (const auto& e : block->GetEnums()) {
               if (e->GetID() == type.ToString())
                 return PascalToSnake(block->GetID()) + "::" + type.ToString();
@@ -422,17 +415,16 @@ std::string RsGeneratorBase::ConvertTypeToString(const BaseType& type,
   if (type.IsStructureType())
     return PascalToSnake(type.ToString()) + "::" + type.ToString();
 
-  if (type.IsUserDefinedType())
-    return type.ToString();
+  if (type.IsUserDefinedType()) return type.ToString();
 
   if (type.GetMetaType() != nullptr)
     return type_map_[type.ToString()] + "<" +
-        ConvertTypeToString(*(type.GetMetaType()), i, definition) + ">";
+           ConvertTypeToString(*(type.GetMetaType()), i, definition) + ">";
 
   if (type.GetKeyType() != nullptr && type.GetValueType() != nullptr) {
     return type_map_[type.ToString()] + "<" +
-        ConvertTypeToString(*(type.GetKeyType()), i, definition) + ", " +
-        ConvertTypeToString(*(type.GetValueType()), i, definition) + ">";
+           ConvertTypeToString(*(type.GetKeyType()), i, definition) + ", " +
+           ConvertTypeToString(*(type.GetValueType()), i, definition) + ">";
   }
   return type_map_[type.ToString()];
 }
@@ -452,17 +444,14 @@ std::string RsGeneratorBase::GetParameters(const Parameters& ps, bool with_id) {
     }
 
     std::string life_time;
-    if (IsDelegateType(i->GetParameterType().GetBaseType())) {
-      if (IsProxy())
-        life_time = "<'b>";
-    }
-    if (with_id)
+    if (with_id) {
       ret += i->GetID() + ": " + mut +
              ConvertTypeToString(i->GetParameterType().GetBaseType()) +
              life_time;
-    else
+    } else {
       ret += mut + ConvertTypeToString(i->GetParameterType().GetBaseType()) +
              life_time;
+    }
   }
 
   return ret;
@@ -488,8 +477,8 @@ std::string RsGeneratorBase::GetParameterIDsWithDir(const Parameters& ps) {
       ret += ", ";
     }
 
-    if (i->GetParameterType().GetDirection() == ParameterType::Direction::OUT
-        || i->GetParameterType().GetDirection() == ParameterType::Direction::REF)
+    if (i->GetParameterType().GetDirection() == ParameterType::Direction::OUT ||
+        i->GetParameterType().GetDirection() == ParameterType::Direction::REF)
       ret += "&mut ";
     ret += i->GetID();
   }
@@ -498,8 +487,7 @@ std::string RsGeneratorBase::GetParameterIDsWithDir(const Parameters& ps) {
 }
 
 void RsGeneratorBase::MakeDir(const std::string& path) {
-  if (access(path.c_str(), F_OK) == 0)
-    return;
+  if (access(path.c_str(), F_OK) == 0) return;
 
   mode_t mod = (S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH | 02000);
   mkdir(path.c_str(), mod);
@@ -507,4 +495,3 @@ void RsGeneratorBase::MakeDir(const std::string& path) {
 
 }  // namespace version2
 }  // namespace tidl
-
index d5327d1c349bc99e198e08b71e096f34b0f0fe23..23cabeff538024563602a3b7fa55bf3770094847 100644 (file)
@@ -68,100 +68,135 @@ macro_rules! warn { ($($arg:tt)*) => {{ DLOG!(DLOG_WARN!(), $($arg)*); }} }
 
 macro_rules! error { ($($arg:tt)*) => {{ DLOG!(DLOG_ERROR!(), $($arg)*); }} }
 
-#[derive(Debug)]
-pub struct Unit {
-    parcel: Parcel,
-    name: String,
-    ty: String,
+pub struct Unit<'a> {
+    parcel: Option<Parcel>,
+    name: i32,
+    ty: i32,
+    val: Box<&'a (dyn Writeable)>,
+    pub cmds: Vec<Box<dyn Fn(&mut Parcel, &Unit<'a>)>>,
 }
 
 #[derive(Debug)]
-pub struct UnitMap {
-    map: HashMap<String, Unit>,
+pub struct UnitMap<'a> {
+    map: HashMap<i32, Unit<'a>>,
 }
 
 pub trait Writeable {
     fn write_parcel(&self, parcel: &mut Parcel);
-    fn write_unit(&self, unit: &mut Unit);
-    fn write_unitmap(&self, name: &str, unit_map: &mut UnitMap);
+    fn get_unit_type(&self) -> i32;
 }
 
 pub trait Readable {
     fn read_parcel(&mut self, parcel: &Parcel);
-    fn read_unit(&mut self, unit: &Unit);
-    fn read_unitmap(&mut self, name: String, unit_map: &UnitMap);
+    fn read_unitmap(&mut self, name: i32, unit_map: &UnitMap);
 }
 
-impl Unit {
+impl<'b> Unit<'b> {
     pub fn empty() -> Self {
         Unit {
-            parcel: Parcel::new_without_header(),
-            name: String::new(),
-            ty: String::new(),
+            parcel: None,
+            name: 0,
+            ty: 0,
+            val: Box::new(&0),
+            cmds: vec![],
         }
     }
-    pub fn new(name: String, ty: String) -> Self {
+    pub fn new(name: i32, ty: i32) -> Self {
         Unit {
-            parcel: Parcel::new_without_header(),
+            parcel: None,
             name,
             ty,
+            val: Box::new(&0),
+            cmds: vec![],
         }
     }
 
-    pub fn set_name(&mut self, name: String) {
+    pub fn new_for_write<T: Writeable + 'static>(name: i32, val: &'b T) -> Self {
+        let mut u = Unit {
+            parcel: None,
+            name: name,
+            ty: val.get_unit_type(),
+            val: Box::new(val),
+            cmds: vec![],
+        };
+
+        u.write(|p, unit| {
+            unit.val.write_parcel(p);
+        });
+        u
+    }
+
+    pub fn set_name(&mut self, name: i32) {
         self.name = name;
     }
 
-    pub fn set_type(&mut self, ty: String) {
+    pub fn set_type(&mut self, ty: i32) {
         self.ty = ty;
     }
 
-    pub fn get_name(&self) -> &String {
-        &self.name
+    pub fn get_name(&self) -> i32 {
+        self.name
     }
 
-    pub fn get_type(&self) -> &String {
-        &self.ty
+    pub fn get_type(&self) -> i32 {
+        self.ty
     }
 
     pub fn get_parcel(&self) -> &Parcel {
-        &self.parcel
-    }
-
-    pub fn get_mut_parcel(&mut self) -> &mut Parcel {
-        &mut self.parcel
+        &self.parcel.as_ref().unwrap()
     }
 
     pub fn serialize(&self, parcel: &mut Parcel) {
-        parcel.write_str(self.name.as_str());
-        parcel.write_str(self.ty.as_str());
+        parcel.write_i32(self.name);
+        parcel.write_i32(self.ty);
+
+        let size_pos = parcel.get_data_size();
+        parcel.reserve(4);
+
+        for cb in self.cmds.iter() {
+            cb(parcel, self);
+        }
 
-        let raw = self.parcel.get_raw();
-        parcel.write_array_count(raw.len());
-        parcel.write(raw);
+        let cur_pos = parcel.get_data_size();
+        let size = cur_pos - size_pos - 4;
+        parcel.set_data_size(size_pos);
+        parcel.write_i32(size as i32);
+        parcel.set_data_size(cur_pos);
     }
 
     pub fn deserialize(&mut self, parcel: &Parcel) {
-        self.set_name(parcel.read_string());
-        self.set_type(parcel.read_string());
+        self.set_name(parcel.read_i32());
+        self.set_type(parcel.read_i32());
         let size = parcel.read_array_count();
-        let mut raw = Vec::<u8>::with_capacity(size);
-        raw.resize(size, 0);
-        let mut raw_slice: &mut [u8] = raw.as_mut_slice();
-        parcel.read(raw_slice);
-        self.parcel.write(raw_slice);
+        if size == 0 {
+            return;
+        }
+
+        let start_pos = parcel.get_reader();
+        self.parcel = Some(Parcel::new_from(parcel, start_pos, size as u32));
+        self.parcel.as_ref().unwrap().reserve(size as u32);
+        parcel.set_reader(start_pos + size as u32);
     }
 
     pub fn read(&self, data: &mut dyn Readable) {
-        data.read_unit(self);
+        data.read_parcel(self.get_parcel());
+    }
+
+    pub fn write<T: Fn(&mut Parcel, &Unit<'b>) + 'static> (&mut self, cb: T) {
+        self.cmds.push(Box::new(cb));
     }
+}
 
-    pub fn write(&mut self, data: &dyn Writeable) {
-        data.write_unit(self);
+impl std::fmt::Debug for Unit<'_> {
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        f.debug_struct("Unit")
+            .field("name", &self.name)
+            .field("ty", &self.ty)
+            .finish()
     }
 }
 
-impl UnitMap {
+impl<'b> UnitMap<'b> {
     pub fn new() -> Self {
         Self {
             map: HashMap::new(),
@@ -176,32 +211,33 @@ impl UnitMap {
         self.map.len()
     }
 
-    pub fn insert(&mut self, name: String, unit: Unit) {
-        self.map.insert(name, unit);
+    pub fn insert(&mut self, unit: Unit<'b>) -> &mut Self {
+        self.map.insert(unit.get_name(), unit);
+        self
     }
 
-    pub fn lookup(&self, name: &str) -> Option<&Unit> {
-        self.map.get(name)
+    pub fn lookup(&self, name: i32) -> Option<&Unit<'b>> {
+        self.map.get(&name)
     }
 
-    pub fn serialize(&self, parcel: &mut Parcel) {
+    pub fn serialize(&mut self, parcel: &mut Parcel) {
         parcel.write_array_count(self.len() as usize);
-        for unit in self.map.values() {
+        for unit in self.map.values_mut() {
             unit.serialize(parcel);
         }
     }
 
     pub fn deserialize(&mut self, parcel: &Parcel) {
         let size = parcel.read_array_count();
+        parcel.pin();
         for _ in 0..size {
-            let mut unit = Unit::empty();
+            let mut unit = Unit::<'b>::empty();
             unit.deserialize(parcel);
-            let name = unit.get_name();
-            self.insert(String::from(name), unit);
+            self.insert(unit);
         }
     }
 
-    pub fn read(&self, name: &str, data: &mut dyn Readable) {
+    pub fn read(&self, name: i32, data: &mut dyn Readable) {
         let unit = self.lookup(name);
         if let Some(unit) = unit {
             unit.read(data);
@@ -215,13 +251,9 @@ impl Writeable for i8 {
     fn write_parcel(&self, parcel: &mut Parcel) {
         parcel.write_i8(*self);
     }
-    fn write_unit(&self, unit: &mut Unit) {
-        self.write_parcel(unit.get_mut_parcel());
-    }
-    fn write_unitmap(&self, name: &str, unit_map: &mut UnitMap) {
-        let mut unit = Unit::new(String::from(name), String::from("char"));
-        unit.write(self);
-        unit_map.insert(String::from(name), unit);
+
+    fn get_unit_type(&self) -> i32 {
+        <HASH_CHAR> /*char*/
     }
 }
 
@@ -229,13 +261,9 @@ impl Writeable for i16 {
     fn write_parcel(&self, parcel: &mut Parcel) {
         parcel.write_i16(*self);
     }
-    fn write_unit(&self, unit: &mut Unit) {
-        self.write_parcel(unit.get_mut_parcel());
-    }
-    fn write_unitmap(&self, name: &str, unit_map: &mut UnitMap) {
-        let mut unit = Unit::new(String::from(name), String::from("short"));
-        unit.write(self);
-        unit_map.insert(String::from(name), unit);
+
+    fn get_unit_type(&self) -> i32 {
+        <HASH_SHORT> /*short*/
     }
 }
 
@@ -243,13 +271,9 @@ impl Writeable for i32 {
     fn write_parcel(&self, parcel: &mut Parcel) {
         parcel.write_i32(*self);
     }
-    fn write_unit(&self, unit: &mut Unit) {
-        self.write_parcel(unit.get_mut_parcel());
-    }
-    fn write_unitmap(&self, name: &str, unit_map: &mut UnitMap) {
-        let mut unit = Unit::new(String::from(name), String::from("int"));
-        unit.write(self);
-        unit_map.insert(String::from(name), unit);
+
+    fn get_unit_type(&self) -> i32 {
+        <HASH_INT> /*int*/
     }
 }
 
@@ -257,13 +281,9 @@ impl Writeable for i64 {
     fn write_parcel(&self, parcel: &mut Parcel) {
         parcel.write_i64(*self);
     }
-    fn write_unit(&self, unit: &mut Unit) {
-        self.write_parcel(unit.get_mut_parcel());
-    }
-    fn write_unitmap(&self, name: &str, unit_map: &mut UnitMap) {
-        let mut unit = Unit::new(String::from(name), String::from("long"));
-        unit.write(self);
-        unit_map.insert(String::from(name), unit);
+
+    fn get_unit_type(&self) -> i32 {
+        <HASH_LONG> /*long*/
     }
 }
 
@@ -271,13 +291,9 @@ impl Writeable for f32 {
     fn write_parcel(&self, parcel: &mut Parcel) {
         parcel.write_f32(*self);
     }
-    fn write_unit(&self, unit: &mut Unit) {
-        self.write_parcel(unit.get_mut_parcel());
-    }
-    fn write_unitmap(&self, name: &str, unit_map: &mut UnitMap) {
-        let mut unit = Unit::new(String::from(name), String::from("float"));
-        unit.write(self);
-        unit_map.insert(String::from(name), unit);
+
+    fn get_unit_type(&self) -> i32 {
+        <HASH_FLOAT> /*float*/
     }
 }
 
@@ -285,13 +301,9 @@ impl Writeable for f64 {
     fn write_parcel(&self, parcel: &mut Parcel) {
         parcel.write_f64(*self);
     }
-    fn write_unit(&self, unit: &mut Unit) {
-        self.write_parcel(unit.get_mut_parcel());
-    }
-    fn write_unitmap(&self, name: &str, unit_map: &mut UnitMap) {
-        let mut unit = Unit::new(String::from(name), String::from("double"));
-        unit.write(self);
-        unit_map.insert(String::from(name), unit);
+
+    fn get_unit_type(&self) -> i32 {
+        <HASH_DOUBLE> /*double*/
     }
 }
 
@@ -299,13 +311,9 @@ impl Writeable for bool {
     fn write_parcel(&self, parcel: &mut Parcel) {
         parcel.write_bool(*self);
     }
-    fn write_unit(&self, unit: &mut Unit) {
-        self.write_parcel(unit.get_mut_parcel());
-    }
-    fn write_unitmap(&self, name: &str, unit_map: &mut UnitMap) {
-        let mut unit = Unit::new(String::from(name), String::from("bool"));
-        unit.write(self);
-        unit_map.insert(String::from(name), unit);
+
+    fn get_unit_type(&self) -> i32 {
+        <HASH_BOOL> /*bool*/
     }
 }
 
@@ -313,13 +321,9 @@ impl Writeable for String {
     fn write_parcel(&self, parcel: &mut Parcel) {
         parcel.write_str(&*self);
     }
-    fn write_unit(&self, unit: &mut Unit) {
-        self.write_parcel(unit.get_mut_parcel());
-    }
-    fn write_unitmap(&self, name: &str, unit_map: &mut UnitMap) {
-        let mut unit = Unit::new(String::from(name), String::from("string"));
-        unit.write(self);
-        unit_map.insert(String::from(name), unit);
+
+    fn get_unit_type(&self) -> i32 {
+        <HASH_STRING> /*string*/
     }
 }
 
@@ -329,13 +333,9 @@ impl Writeable for <BLOCK_NAME>::<ENUM_NAME> {
     fn write_parcel(&self, parcel: &mut Parcel) {
        parcel.write_i32((*self) as i32);
     }
-    fn write_unit(&self, unit: &mut Unit) {
-        self.write_parcel(unit.get_mut_parcel());
-    }
-    fn write_unitmap(&self, name: &str, unit_map: &mut UnitMap) {
-        let mut unit = Unit::new(String::from(name), String::from("int"));
-        unit.write(self);
-        unit_map.insert(String::from(name), unit);
+
+    fn get_unit_type(&self) -> i32 {
+        <HASH_INT> /*int*/
     }
 }
 
@@ -348,17 +348,8 @@ impl Writeable for RemoteException {
         parcel.write_str(self.message.as_str());
     }
 
-    fn write_unit(&self, unit: &mut Unit) {
-        let mut unit_map = UnitMap::new();
-        self.cause.write_unitmap("cause", &mut unit_map);
-        self.message.write_unitmap("message", &mut unit_map);
-        unit_map.serialize(unit.get_mut_parcel());
-    }
-
-    fn write_unitmap(&self, name: &str, unit_map: &mut UnitMap) {
-        let mut unit = Unit::new(String::from(name), "remote_exception".to_owned());
-        unit.write(self);
-        unit_map.insert(String::from(name), unit);
+    fn get_unit_type(&self) -> i32 {
+        <HASH_REMOTE_EXCEPTION> /*remote_exception*/
     }
 }
 
@@ -368,13 +359,11 @@ impl Readable for i8 {
     fn read_parcel(&mut self, parcel: &Parcel) {
         *self = parcel.read_i8();
     }
-    fn read_unit(&mut self, unit: &Unit) {
-        self.read_parcel(unit.get_parcel());
-    }
-    fn read_unitmap(&mut self, name: String, unit_map: &UnitMap) {
-        match unit_map.lookup(name.as_str()) {
+
+    fn read_unitmap(&mut self, name: i32, unit_map: &UnitMap) {
+        match unit_map.lookup(name) {
             Some(unit) => {
-                if unit.get_type().ne(&"char") {
+                if unit.get_type() != <HASH_CHAR> /*char*/ {
                     error!("type({}) is not char", unit.get_type());
                     return;
                 }
@@ -393,13 +382,11 @@ impl Readable for i16 {
     fn read_parcel(&mut self, parcel: &Parcel) {
         *self = parcel.read_i16();
     }
-    fn read_unit(&mut self, unit: &Unit) {
-        self.read_parcel(unit.get_parcel());
-    }
-    fn read_unitmap(&mut self, name: String, unit_map: &UnitMap) {
-        match unit_map.lookup(name.as_str()) {
+
+    fn read_unitmap(&mut self, name: i32, unit_map: &UnitMap) {
+        match unit_map.lookup(name) {
             Some(unit) => {
-                if unit.get_type().ne(&"short") {
+                if unit.get_type() != <HASH_SHORT> /*short*/ {
                     error!("type({}) is not short", unit.get_type());
                     return;
                 }
@@ -418,13 +405,11 @@ impl Readable for i32 {
     fn read_parcel(&mut self, parcel: &Parcel) {
         *self = parcel.read_i32();
     }
-    fn read_unit(&mut self, unit: &Unit) {
-        self.read_parcel(unit.get_parcel());
-    }
-    fn read_unitmap(&mut self, name: String, unit_map: &UnitMap) {
-        match unit_map.lookup(name.as_str()) {
+
+    fn read_unitmap(&mut self, name: i32, unit_map: &UnitMap) {
+        match unit_map.lookup(name) {
             Some(unit) => {
-                if unit.get_type().ne(&"int") {
+                if unit.get_type() != <HASH_INT> /*int*/ {
                     error!("type({}) is not int", unit.get_type());
                     return;
                 }
@@ -443,13 +428,11 @@ impl Readable for i64 {
     fn read_parcel(&mut self, parcel: &Parcel) {
         *self = parcel.read_i64();
     }
-    fn read_unit(&mut self, unit: &Unit) {
-        self.read_parcel(unit.get_parcel());
-    }
-    fn read_unitmap(&mut self, name: String, unit_map: &UnitMap) {
-        match unit_map.lookup(name.as_str()) {
+
+    fn read_unitmap(&mut self, name: i32, unit_map: &UnitMap) {
+        match unit_map.lookup(name) {
             Some(unit) => {
-                if unit.get_type().ne(&"long") {
+                if unit.get_type() != <HASH_LONG> /*long*/ {
                     error!("type({}) is not long", unit.get_type());
                     return;
                 }
@@ -468,13 +451,11 @@ impl Readable for f32 {
     fn read_parcel(&mut self, parcel: &Parcel) {
         *self = parcel.read_f32();
     }
-    fn read_unit(&mut self, unit: &Unit) {
-        self.read_parcel(unit.get_parcel());
-    }
-    fn read_unitmap(&mut self, name: String, unit_map: &UnitMap) {
-        match unit_map.lookup(name.as_str()) {
+
+    fn read_unitmap(&mut self, name: i32, unit_map: &UnitMap) {
+        match unit_map.lookup(name) {
             Some(unit) => {
-                if unit.get_type().ne(&"float") {
+                if unit.get_type() != <HASH_FLOAT> /*float*/ {
                     error!("type({}) is not float", unit.get_type());
                     return;
                 }
@@ -493,13 +474,11 @@ impl Readable for f64 {
     fn read_parcel(&mut self, parcel: &Parcel) {
         *self = parcel.read_f64();
     }
-    fn read_unit(&mut self, unit: &Unit) {
-        self.read_parcel(unit.get_parcel());
-    }
-    fn read_unitmap(&mut self, name: String, unit_map: &UnitMap) {
-        match unit_map.lookup(name.as_str()) {
+
+    fn read_unitmap(&mut self, name: i32, unit_map: &UnitMap) {
+        match unit_map.lookup(name) {
             Some(unit) => {
-                if unit.get_type().ne(&"double") {
+                if unit.get_type() != <HASH_DOUBLE> /*double*/ {
                     error!("type({}) is not double", unit.get_type());
                     return;
                 }
@@ -518,13 +497,11 @@ impl Readable for bool {
     fn read_parcel(&mut self, parcel: &Parcel) {
         *self = parcel.read_bool();
     }
-    fn read_unit(&mut self, unit: &Unit) {
-        self.read_parcel(unit.get_parcel());
-    }
-    fn read_unitmap(&mut self, name: String, unit_map: &UnitMap) {
-        match unit_map.lookup(name.as_str()) {
+
+    fn read_unitmap(&mut self, name: i32, unit_map: &UnitMap) {
+        match unit_map.lookup(name) {
             Some(unit) => {
-                if unit.get_type().ne(&"bool") {
+                if unit.get_type() != <HASH_BOOL> /*bool*/ {
                     error!("type({}) is not bool", unit.get_type());
                     return;
                 }
@@ -543,13 +520,11 @@ impl Readable for String {
     fn read_parcel(&mut self, parcel: &Parcel) {
         *self = parcel.read_string();
     }
-    fn read_unit(&mut self, unit: &Unit) {
-        self.read_parcel(unit.get_parcel());
-    }
-    fn read_unitmap(&mut self, name: String, unit_map: &UnitMap) {
-        match unit_map.lookup(name.as_str()) {
+
+    fn read_unitmap(&mut self, name: i32, unit_map: &UnitMap) {
+        match unit_map.lookup(name) {
             Some(unit) => {
-                if unit.get_type().ne(&"string") {
+                if unit.get_type() != <HASH_STRING> /*string*/ {
                     error!("type({}) is not string", unit.get_type());
                     return;
                 }
@@ -569,13 +544,9 @@ impl Writeable for Bundle {
     fn write_parcel(&self, parcel: &mut Parcel) {
         parcel.write_bundle(&*self);
     }
-    fn write_unit(&self, unit: &mut Unit) {
-        self.write_parcel(unit.get_mut_parcel());
-    }
-    fn write_unitmap(&self, name: &str, unit_map: &mut UnitMap) {
-        let mut unit = Unit::new(String::from(name), String::from("bundle"));
-        unit.write(self);
-        unit_map.insert(String::from(name), unit);
+
+    fn get_unit_type(&self) -> i32 {
+        <HASH_BUNDLE> /*bundle*/
     }
 }
 
@@ -583,13 +554,11 @@ impl Readable for Bundle {
     fn read_parcel(&mut self, parcel: &Parcel) {
         *self = parcel.read_bundle() as Bundle;
     }
-    fn read_unit(&mut self, unit: &Unit) {
-        self.read_parcel(unit.get_parcel());
-    }
-    fn read_unitmap(&mut self, name: String, unit_map: &UnitMap) {
-        match unit_map.lookup(name.as_str()) {
+
+    fn read_unitmap(&mut self, name: i32, unit_map: &UnitMap) {
+        match unit_map.lookup(name) {
             Some(unit) => {
-                if unit.get_type().ne(&"bundle") {
+                if unit.get_type() != <HASH_BUNDLE> /*bundle*/ {
                     error!("type({}) is not bundle", unit.get_type());
                     return;
                 }
@@ -622,13 +591,11 @@ impl Readable for <BLOCK_NAME>::<ENUM_NAME> {
     fn read_parcel(&mut self, parcel: &Parcel) {
         *self = parcel.read_i32().into();
     }
-    fn read_unit(&mut self, unit: &Unit) {
-        self.read_parcel(unit.get_parcel());
-    }
-    fn read_unitmap(&mut self, name: String, unit_map: &UnitMap) {
-        match unit_map.lookup(name.as_str()) {
+
+    fn read_unitmap(&mut self, name: i32, unit_map: &UnitMap) {
+        match unit_map.lookup(name) {
             Some(unit) => {
-                if unit.get_type().ne(&"int") {
+                if unit.get_type() != <HASH_INT> /*int*/ {
                     error!("type({}) is not int", unit.get_type());
                     return;
                 }
@@ -651,16 +618,11 @@ impl Readable for RemoteException {
         self.cause = parcel.read_i32();
         self.message = parcel.read_string();
     }
-    fn read_unit(&mut self, unit: &Unit) {
-        let mut unit_map = UnitMap::new();
-        unit_map.deserialize(unit.get_parcel());
-        unit_map.read("cause", &mut self.cause);
-        unit_map.read("message", &mut self.message);
-    }
-    fn read_unitmap(&mut self, name: String, unit_map: &UnitMap) {
-        match unit_map.lookup(name.as_str()) {
+
+    fn read_unitmap(&mut self, name: i32, unit_map: &UnitMap) {
+        match unit_map.lookup(name) {
             Some(unit) => {
-                if unit.get_type().ne(&"remote_exception") {
+                if unit.get_type() != <HASH_REMOTE_EXCEPTION> /*remote_exception*/ {
                     error!("type({}) is not remote_exception", unit.get_type());
                     return;
                 }
@@ -683,18 +645,9 @@ impl Writeable for <MOD_NAME>::<TYPE> {
         self.<ID>.write_parcel(parcel);
         </PARCEL_BODY*>
     }
-    fn write_unit(&self, unit: &mut Unit) {
-        let mut __unit_map = UnitMap::new();
-        <UNIT_BODY*>
-        self.<ID>.write_unitmap("<REAL_ID>", &mut __unit_map);
-        </UNIT_BODY*>
 
-        __unit_map.serialize(unit.get_mut_parcel());
-    }
-    fn write_unitmap(&self, name: &str, unit_map: &mut UnitMap) {
-        let mut unit = Unit::new(String::from(name), String::from("<UNIT_TYPE>"));
-        unit.write(self);
-        unit_map.insert(String::from(name), unit);
+    fn get_unit_type(&self) -> i32 {
+        <HASH_UNIT_TYPE> /*<UNIT_TYPE>*/
     }
 }
 </WRITE_PARCELS*>
@@ -706,19 +659,11 @@ impl Readable for <MOD_NAME>::<TYPE> {
         self.<ID>.read_parcel(parcel);
         </PARCEL_BODY*>
     }
-    fn read_unit(&mut self, unit: &Unit) {
-        let mut __unit_map = UnitMap::new();
-        __unit_map.deserialize(unit.get_parcel());
-        <UNIT_BODY*>
-        let mut tmp_<ID>: <INSIDE_TYPE> = Default::default();
-        __unit_map.read("<REAL_ID>", &mut tmp_<ID>);
-        self.<ID> = tmp_<ID>;
-        </UNIT_BODY*>
-    }
-    fn read_unitmap(&mut self, name: String, unit_map: &UnitMap) {
-        match unit_map.lookup(name.as_str()) {
+
+    fn read_unitmap(&mut self, name: i32, unit_map: &UnitMap) {
+        match unit_map.lookup(name) {
             Some(unit) => {
-                if unit.get_type().ne(&"<UNIT_TYPE>") {
+                if unit.get_type() != <HASH_UNIT_TYPE> /*<UNIT_TYPE>*/ {
                     error!("type({}) is not <UNIT_TYPE>", unit.get_type());
                     return;
                 }
@@ -737,113 +682,79 @@ impl Readable for <MOD_NAME>::<TYPE> {
 <META_PARCELS!>
 impl Writeable for <TYPE> {
     fn write_parcel(&self, parcel: &mut Parcel) {
-    }
-    fn write_unit(&self, unit: &mut Unit) {
-        let mut __unit_map = UnitMap::new();
         <LIST?>
-        let mut __unit = Unit::new("length".to_owned(), "int".to_owned());
-        __unit.write(&(self.len() as i32));
-        __unit_map.insert("length".to_owned(), __unit);
-        for (index, e) in self.iter().enumerate() {
-            let mut __unit = Unit::new(index.to_string(), "<UNIT_TYPE>".to_owned());
-            __unit.write(e);
-            __unit_map.insert(index.to_string(), __unit);
+        parcel.write_i32(self.len() as i32);
+        for i in self.iter() {
+            i.write_parcel(parcel);
         }
         </LIST?>
         <ARRAY?>
-        let mut __unit = Unit::new("size".to_owned(), "int".to_owned());
-        __unit.write(&(self.len() as i32));
-        __unit_map.insert("size".to_owned(), __unit);
-        for (index, e) in self.iter().enumerate() {
-            let mut __unit = Unit::new(index.to_string(), "<UNIT_TYPE>".to_owned());
-            __unit.write(e);
-            __unit_map.insert(index.to_string(), __unit);
+        //TODO opt
+        parcel.write_i32(self.len() as i32);
+        for i in self.iter() {
+            i.write_parcel(parcel);
         }
         </ARRAY?>
         <SET?>
-        let mut __unit = Unit::new("size".to_owned(), "int".to_owned());
-        __unit.write(&(self.len() as i32));
-        __unit_map.insert("size".to_owned(), __unit);
-        for (index, e) in self.iter().enumerate() {
-            let key_str = format!("{}{}", String::from("key-"), index);
-            let mut __unit = Unit::new(key_str.clone(), "<UNIT_TYPE>".to_owned());
-            __unit.write(e);
-            __unit_map.insert(key_str, __unit);
+        parcel.write_i32(self.len() as i32);
+        for i in self.iter() {
+            i.write_parcel(parcel);
         }
         </SET?>
         <MAP?>
-        let mut __unit = Unit::new("size".to_owned(), "int".to_owned());
-        __unit.write(&(self.len() as i32));
-        __unit_map.insert("size".to_owned(), __unit);
-        for (index, (key, value)) in self.iter().enumerate() {
-            let key_str = format!("{}{}", String::from("key-"), index);
-            let mut __unit = Unit::new(key_str.clone(), "<UNIT_TYPE>".to_owned());
-            __unit.write(key);
-            __unit_map.insert(key_str, __unit);
-            let value_str = format!("{}{}", String::from("value-"), index);
-            let mut __unit = Unit::new(value_str.clone(), "<UNIT_VALUE_TYPE>".to_owned());
-            __unit.write(value);
-            __unit_map.insert(value_str, __unit);
+        parcel.write_i32(self.len() as i32);
+        for (key, value) in self.iter() {
+            key.write_parcel(parcel);
+            value.write_parcel(parcel);
         }
         </MAP?>
-        __unit_map.serialize(unit.get_mut_parcel());
     }
-    fn write_unitmap(&self, name: &str, unit_map: &mut UnitMap) {
-        let mut unit = Unit::new(String::from(name), String::from("<TYPE_ID>"));
-        unit.write(self);
-        unit_map.insert(String::from(name), unit);
+
+    fn get_unit_type(&self) -> i32 {
+        <HASH_TYPE_ID> /*<TYPE_ID>*/
     }
 }
 
 impl Readable for <TYPE> {
     fn read_parcel(&mut self, parcel: &Parcel) {
-    }
-    fn read_unit(&mut self, unit: &Unit) {
-        let mut __unit_map = UnitMap::new();
-        __unit_map.deserialize(unit.get_parcel());
-        let mut __size: i32 = Default::default();
+        let __size = parcel.read_i32();
         <LIST?>
-        __unit_map.read("length", &mut __size);
-        for index in 0..__size {
+        for _ in 0..__size {
             let mut __tmp_value: <INSIDE_TYPE> = Default::default();
-            __unit_map.read(&index.to_string(), &mut __tmp_value);
+            __tmp_value.read_parcel(parcel);
             self.push_back(__tmp_value);
         }
         </LIST?>
         <ARRAY?>
-        __unit_map.read("size", &mut __size);
-        for index in 0..__size {
+        //TODO opt
+        for _ in 0..__size {
             let mut __tmp_value: <INSIDE_TYPE> = Default::default();
-            __unit_map.read(&index.to_string(), &mut __tmp_value);
+            __tmp_value.read_parcel(parcel);
             self.push(__tmp_value);
         }
         </ARRAY?>
         <SET?>
-        __unit_map.read("size", &mut __size);
-        for index in 0..__size {
-            let key_str = format!("{}{}", String::from("key-"), index);
+        for _ in 0..__size {
             let mut __tmp_value: <INSIDE_TYPE> = Default::default();
-            __unit_map.read(&key_str, &mut __tmp_value);
+            __tmp_value.read_parcel(parcel);
             self.insert(__tmp_value);
         }
         </SET?>
         <MAP?>
-        __unit_map.read("size", &mut __size);
-        for index in 0..__size {
-            let key_str = format!("{}{}", String::from("key-"), index);
-            let value_str = format!("{}{}", String::from("value-"), index);
+        for _ in 0..__size {
             let mut __tmp_key: <INSIDE_TYPE> = Default::default();
             let mut __tmp_value: <INSIDE_VALUE_TYPE> = Default::default();
-            __unit_map.read(&key_str, &mut __tmp_key);
-            __unit_map.read(&value_str, &mut __tmp_value);
+            __tmp_key.read_parcel(parcel);
+            __tmp_value.read_parcel(parcel);
             self.insert(__tmp_key, __tmp_value);
         }
         </MAP?>
     }
-    fn read_unitmap(&mut self, name: String, unit_map: &UnitMap) {
-        match unit_map.lookup(name.as_str()) {
+
+    fn read_unitmap(&mut self, name: i32, unit_map: &UnitMap) {
+        match unit_map.lookup(name) {
             Some(unit) => {
-                if unit.get_type().ne(&"<TYPE_ID>") {
+                if unit.get_type() != <HASH_TYPE_ID> /*<TYPE_ID>*/ {
                     error!("type({}) is not <TYPE>", unit.get_type());
                     return;
                 }
index e29d2c069793652a66287d73f6dd3b557a8e208c..300a6d51f9e6f508b8fdd38ef300673c7bff85db 100644 (file)
@@ -37,6 +37,7 @@ void RsGroupGen::OnInitGen(std::ofstream& stream) {
           return SetStructs(ra, i);
         })
       .ReplaceBlock("MODULE_BLOCK", [&](ReplaceAll& ra) { SetModules(ra); })
+      .Replace("HASH_METHOD", std::to_string(GetHashCode("[METHOD]")))
       .Out(stream);
   stream.close();
 }
@@ -195,6 +196,7 @@ bool RsGroupGen::SetMethod(ReplaceAll& ra, const std::unique_ptr<Declaration>& d
                 if (p->GetParameterType().GetBaseType().IsDelegateType())
                   return false;
                 ra.Replace("ID", p->GetID())
+                  .Replace("HASH_ID", std::to_string(GetHashCode(p->GetID())))
                   .Replace("TYPE", ConvertTypeToString(
                       p->GetParameterType().GetBaseType()));
                 return true;
@@ -204,6 +206,7 @@ bool RsGroupGen::SetMethod(ReplaceAll& ra, const std::unique_ptr<Declaration>& d
                 if (!p->GetParameterType().GetBaseType().IsDelegateType())
                   return false;
                 ra.Replace("ID", p->GetID())
+                  .Replace("HASH_ID", std::to_string(GetHashCode(p->GetID())))
                   .Replace("TYPE", ConvertTypeToString(
                       p->GetParameterType().GetBaseType()));
                 return true;
@@ -238,7 +241,8 @@ bool RsGroupGen::SetSenderBody(ReplaceAll& ra,
 
   SetFile(ra, i);
 
-  ra.Replace("ID", i->GetID());
+  ra.Replace("ID", i->GetID())
+    .Replace("HASH_ID", std::to_string(GetHashCode(i->GetID())));
   return true;
 }
 
index ef947bf6766b5cf72446888fb3d44ac6ec96ae2a..050b18451bd21f776fbcc2453e4fee99541f3ecf 100644 (file)
 
 constexpr const char CB_GROUP_MAIN[] =
 R"__rs_cb(
+#![allow(unused)]
+#![allow(non_snake_case)]
+#![allow(non_camel_case_types)]
+
 extern crate rust_app_event;
 extern crate rust_rpc_port;
 use rust_app_event::{AppEvent, Bundle};
@@ -57,7 +61,7 @@ fn convert_err(id: i32) -> ErrorId {
 pub mod <STRUCT_MOD_NAME> {
     use super::*;
     <ENUM*>
-    #[derive(Copy, Clone)]
+    #[derive(Copy, Clone, Debug)]
     pub enum <ENUM_NAME> {
         <PROPERTIES*>
         <ID>,
@@ -104,7 +108,7 @@ pub mod <MOD_NAME> {
 
     <INTERFACE_BLOCK!>
     <ENUM*>
-    #[derive(Copy, Clone)]
+    #[derive(Copy, Clone, Debug)]
     pub enum <ENUM_NAME> {
         <PROPERTIES*>
         <ID>,
@@ -161,7 +165,7 @@ pub mod <MOD_NAME> {
         /// <param name="sender_id">The sender application ID</param>
         /// <param name="is_system">The flag indicating whether the event is a system event.</param>
         pub fn new<T: ServiceHandler>(sender_id: String, is_system: bool) -> Arc<Mutex<<IFACE_NAME>>> {
-            let mut event_name: String;
+            let event_name: String;
             match is_system {
                 true => event_name = "tizen.system.event.tidl_iface_<IFACE_NAME>".to_string(),
                 false => event_name = ("event.".to_owned() + &sender_id + ".tidl_iface_<IFACE_NAME>").to_string(),
@@ -171,22 +175,22 @@ pub mod <MOD_NAME> {
                 event_name,
                 group: None,
             }));
-            let mut obj = Arc::new(Mutex::new(Self {
+            let obj = Arc::new(Mutex::new(Self {
                 sender_id,
                 is_system,
                 connection: connection.clone(),
                 handler: T::new(connection),
-                on_received: Arc::new(Mutex::new(Box::new(|event_name: &str, event_data: &Bundle| {
-                }))),
+                on_received: Arc::new(Mutex::new(Box::new(|_, _| {}))),
             }));
 
-            let mut copy_obj = obj.clone();
-            obj.lock().unwrap().on_received = Arc::new(Mutex::new(Box::new(move |event_name: &str, event_data: &Bundle| {
+            let copy_obj = obj.clone();
+            obj.lock().unwrap().on_received =
+                Arc::new(Mutex::new(Box::new(move |_, event_data| {
                 let mut __parcel = copy_obj.lock().unwrap().get_parcel_from_bundle(event_data);
                 let mut __unit_map = UnitMap::new();
                 __unit_map.deserialize(&__parcel);
                 let mut __cmd: i32 = -1;
-                __cmd.read_unitmap("[METHOD]".to_string(), &mut __unit_map);
+                __cmd.read_unitmap(<HASH_METHOD> /*[METHOD]*/, &mut __unit_map);
                 match __cmd {
                     <DISPATCHES*>
                     x if x == MethodId::<ID> as i32 => {
@@ -204,15 +208,15 @@ pub mod <MOD_NAME> {
         }
 
         fn get_bundle_from_parcel(&self, parcel: &Parcel) -> Bundle {
-            let mut raw = parcel.get_raw();
+            let raw = parcel.get_raw();
             let mut b = Bundle::new();
 
-            b.add_bytes("TIDL_RAW", &raw.to_vec());
+            let _ = b.add_bytes("TIDL_RAW", &raw.to_vec());
             b
         }
 
         fn get_parcel_from_bundle(&self, bundle: &Bundle) -> Parcel {
-            let mut raw = bundle.get_bytes("TIDL_RAW").unwrap();
+            let raw = bundle.get_bytes("TIDL_RAW").unwrap();
 
             Parcel::from_raw(raw.as_slice())
         }
@@ -244,16 +248,16 @@ pub mod <MOD_NAME> {
 
         <METHODS*>
         pub fn <FN_NAME>(&mut self, <PARAMS>) -> Result<(), ErrorId> {
+            let mut __parcel = Parcel::new();
+            let __method_id = MethodId::<METHOD_ID> as i32;
             let mut __unit_map = UnitMap::new();
-            (MethodId::<METHOD_ID> as i32).write_unitmap("[METHOD]", &mut __unit_map);
+            __unit_map.insert(Unit::new_for_write(<HASH_METHOD> /*[METHOD]*/, &__method_id))
             <SENDER_BODY*>
-            <ID>.write_unitmap("<ID>", &mut __unit_map);
+                .insert(Unit::new_for_write(<HASH_ID> /*<ID>*/, &<ID>))
             </SENDER_BODY*>
+                .serialize(&mut __parcel);
 
-            let mut __parcel = Parcel::new();
-            __unit_map.serialize(&mut __parcel);
             let mut __bundle = self.get_bundle_from_parcel(&__parcel);
-
             let connection = self.connection.lock().unwrap();
             match AppEvent::publish(connection.event_name.as_str(), &mut __bundle) {
                 Ok(_) => Ok(()),
@@ -267,7 +271,7 @@ pub mod <MOD_NAME> {
         fn dispatch_<FN_NAME>(&mut self, unit_map: &UnitMap) {
             <RECEIVER_BODY*>
             let mut <ID>: <TYPE> = Default::default();
-            unit_map.read("<ID>", &mut <ID>);
+            unit_map.read(<HASH_ID> /*<ID>*/, &mut <ID>);
             </RECEIVER_BODY*>
             self.handler.on_<FN_NAME>(<IDS>);
         }
index 291996f84e6a93f704042b99513104fd5c3809b1..cc9c407f54c6327ef5709d964c275a06c4c64b2a 100644 (file)
@@ -23,8 +23,7 @@ namespace {
 namespace tidl {
 namespace version2 {
 
-RsProxyGen::RsProxyGen(std::shared_ptr<Document> doc)
-    : RsGeneratorBase(doc) {}
+RsProxyGen::RsProxyGen(std::shared_ptr<Document> doc) : RsGeneratorBase(doc) {}
 
 void RsProxyGen::OnInitGen(std::ofstream& stream) {
   RsGeneratorBase::OnInitGen(stream);
@@ -32,11 +31,16 @@ void RsProxyGen::OnInitGen(std::ofstream& stream) {
   ReplaceAll(::CB_PROXY_MAIN)
       .Replace("VERSION", std::string(FULLVER))
       .Repeat("STRUCTS", GetDocument().GetBlocks(),
-            [&](ReplaceAll& ra, const std::shared_ptr<Block>& i) {
-          return SetStructs(ra, i);
-        })
+              [&](ReplaceAll& ra, const std::shared_ptr<Block>& i) {
+                return SetStructs(ra, i);
+              })
       .ReplaceBlock("MODULE_BLOCK", [&](ReplaceAll& ra) { SetModules(ra); })
       .Remove("BUNDLE_HEADER_BLOCK", RsGeneratorBase::HasBundle() != true)
+      .Replace("HASH_METHOD", std::to_string(GetHashCode("[METHOD]")))
+      .Replace("HASH_REMOTE_EXCEPTION",
+               std::to_string(GetHashCode("[REMOTE_EXCEPTION]")))
+      .Replace("HASH_RESULT", std::to_string(GetHashCode("[RESULT]")))
+      .Replace("HASH_DELEGATE", std::to_string(GetHashCode("delegate")))
       .Out(stream);
   stream.close();
 }
@@ -50,92 +54,94 @@ void RsProxyGen::SetModules(ReplaceAll& ra) {
   int m_cnt = 2;
   int d_cnt = 1;
 
-  ra.Repeat("MODULES", GetDocument().GetBlocks(),
+  ra.Repeat(
+      "MODULES", GetDocument().GetBlocks(),
       [&](ReplaceAll& ra, const std::shared_ptr<Block>& i) {
-    if (i->GetType() != Block::TYPE_INTERFACE)
-      return false;
-    Interface& iface = static_cast<Interface&>(*i);
-    ra.Replace("MOD_NAME", PascalToSnake(iface.GetID()))
-        .Repeat("METHOD_ID", iface.GetDeclarations(),
-            [&](ReplaceAll& ra, const std::unique_ptr<Declaration>& d){
-          return SetMethodIDs(ra, d, m_cnt);
-        })
-        .Repeat("DELEGATE_ID", iface.GetDeclarations(),
-            [&](ReplaceAll& ra, const std::unique_ptr<Declaration>& d){
-          return SetDelegateIDs(ra, d, d_cnt);
-        })
-        .ReplaceBlock("DELEGATE_BLOCK", [&](ReplaceAll& ra) {
-          SetDelegateBlock(ra, iface);
-        })
-        .Repeat("ENUM", iface.GetEnums(),
-            [&](ReplaceAll& ra, const std::unique_ptr<Enum>& e) {
-          return SetEnum(ra, e);
-        })
-        .ReplaceBlock("INTERFACE_BLOCK", [&](ReplaceAll& ra) {
-          SetInterfaceBlock(ra, iface);
-        });
-    return true;
-  });
+        if (i->GetType() != Block::TYPE_INTERFACE) return false;
+        Interface& iface = static_cast<Interface&>(*i);
+        ra.Replace("MOD_NAME", PascalToSnake(iface.GetID()))
+            .Repeat("METHOD_ID", iface.GetDeclarations(),
+                    [&](ReplaceAll& ra, const std::unique_ptr<Declaration>& d) {
+                      return SetMethodIDs(ra, d, m_cnt);
+                    })
+            .Repeat("DELEGATE_ID", iface.GetDeclarations(),
+                    [&](ReplaceAll& ra, const std::unique_ptr<Declaration>& d) {
+                      return SetDelegateIDs(ra, d, d_cnt);
+                    })
+            .ReplaceBlock("DELEGATE_BLOCK",
+                          [&](ReplaceAll& ra) { SetDelegateBlock(ra, iface); })
+            .Repeat("ENUM", iface.GetEnums(),
+                    [&](ReplaceAll& ra, const std::unique_ptr<Enum>& e) {
+                      return SetEnum(ra, e);
+                    })
+            .ReplaceBlock("INTERFACE_BLOCK", [&](ReplaceAll& ra) {
+              SetInterfaceBlock(ra, iface);
+            });
+        return true;
+      });
 }
 
 bool RsProxyGen::SetMethodIDs(ReplaceAll& ra,
-    const std::unique_ptr<Declaration>& d, int& cnt) {
-  if (d->GetMethodType() == Declaration::MethodType::DELEGATE)
-    return false;
+                              const std::unique_ptr<Declaration>& d, int& cnt) {
+  if (d->GetMethodType() == Declaration::MethodType::DELEGATE) return false;
 
   ra.Replace("ID", SnakeToPascal(d->GetID()))
-    .Replace("COUNT", std::to_string(cnt++));
+      .Replace("COUNT", std::to_string(cnt++));
   return true;
 }
 
 bool RsProxyGen::SetDelegateIDs(ReplaceAll& ra,
-    const std::unique_ptr<Declaration>& d, int& cnt) {
-  if (d->GetMethodType() != Declaration::MethodType::DELEGATE)
-    return false;
+                                const std::unique_ptr<Declaration>& d,
+                                int& cnt) {
+  if (d->GetMethodType() != Declaration::MethodType::DELEGATE) return false;
 
   ra.Replace("ID", SnakeToPascal(d->GetID()))
-    .Replace("COUNT", std::to_string(cnt++));
+      .Replace("COUNT", std::to_string(cnt++));
   return true;
 }
 
-
 void RsProxyGen::SetDelegateBlock(ReplaceAll& ra, const Interface& iface) {
   auto& decls = iface.GetDeclarations();
 
-  ra.Repeat("DELEGATES", decls,
+  ra.Repeat(
+      "DELEGATES", decls,
       [&](ReplaceAll& ra, const std::unique_ptr<Declaration>& i) {
-    if (i->GetMethodType() != Declaration::MethodType::DELEGATE)
-      return false;
-    ra.Replace("TYPES", GetParameters(i->GetParameters(), false))
-      .Repeat("RECEIVER_BODY", i->GetParameters(),
-        [&](ReplaceAll& ra, const std::unique_ptr<tidl::Parameter>& p){
-        ra.Replace("ID", p->GetID())
-          .Replace("TYPE", ConvertTypeToString(
-              p->GetParameterType().GetBaseType()));
+        if (i->GetMethodType() != Declaration::MethodType::DELEGATE)
+          return false;
+        ra.Replace("TYPES", GetParameters(i->GetParameters(), false))
+            .Repeat(
+                "RECEIVER_BODY", i->GetParameters(),
+                [&](ReplaceAll& ra, const std::unique_ptr<tidl::Parameter>& p) {
+                  ra.Replace("ID", p->GetID())
+                      .Replace("HASH_ID",
+                               std::to_string(GetHashCode(p->GetID())))
+                      .Replace("TYPE",
+                               ConvertTypeToString(
+                                   p->GetParameterType().GetBaseType()));
+                  return true;
+                })
+            .Replace("IDS", GetParameterIDs(i->GetParameters()))
+            .Replace("METHOD_NAME", SnakeToPascal(i->GetID()));
         return true;
-      })
-      .Replace("IDS", GetParameterIDs(i->GetParameters()))
-      .Replace("METHOD_NAME", SnakeToPascal(i->GetID()));
-    return true;
-  });
+      });
 }
 
 void RsProxyGen::SetInterfaceBlock(ReplaceAll& ra, const Interface& iface) {
   ra.Repeat("ENUM", iface.GetEnums(),
-      [&](ReplaceAll& ra, const std::unique_ptr<Enum>& e) {
-    return SetEnum(ra, e);
-  });
+            [&](ReplaceAll& ra, const std::unique_ptr<Enum>& e) {
+              return SetEnum(ra, e);
+            });
 
   ra.Replace("IFACE_NAME", iface.GetID())
-    .Repeat("METHODS", iface.GetDeclarations(),
-        [&](ReplaceAll& ra, const std::unique_ptr<Declaration>& d){
-      return SetMethod(ra, d);
-    });
+      .Repeat("METHODS", iface.GetDeclarations(),
+              [&](ReplaceAll& ra, const std::unique_ptr<Declaration>& d) {
+                return SetMethod(ra, d);
+              });
 }
 
-bool RsProxyGen::SetMethod(ReplaceAll& ra, const std::unique_ptr<Declaration>& d) {
-  if (d->GetMethodType() == Declaration::MethodType::DELEGATE)
-    return false;
+bool RsProxyGen::SetMethod(ReplaceAll& ra,
+                           const std::unique_ptr<Declaration>& d) {
+  if (d->GetMethodType() == Declaration::MethodType::DELEGATE) return false;
 
   if (!d->GetComments().empty())
     ra.Replace("COMMENTS", AddIndent(2 * TAB_SIZE, d->GetComments()));
@@ -143,69 +149,76 @@ bool RsProxyGen::SetMethod(ReplaceAll& ra, const std::unique_ptr<Declaration>& d
     ra.Replace("COMMENTS", {});
 
   ra.Replace("FN_NAME", PascalToSnake(d->GetID()))
-    .Replace("PARAMS", GetParameters(d->GetParameters()))
-//    .Replace("RET", GetRetExpr(*d))
-    .Replace("METHOD_ID", SnakeToPascal((*d).GetID()))
-    .Repeat("SENDER_BODY", (*d).GetParameters(),
-        [&](ReplaceAll& ra, const std::unique_ptr<tidl::Parameter>& i) {
-      return SetSenderBody(ra, i);
-    })
-    .Remove("ASYNC", (*d).GetMethodType() == Declaration::MethodType::SYNC)
-    .Remove("SYNC", (*d).GetMethodType() == Declaration::MethodType::ASYNC)
-    .Repeat("RECEIVER_BODY", (*d).GetParameters(),
-        [&](ReplaceAll& ra, const std::unique_ptr<tidl::Parameter>& i) {
-      return SetReceiverBody(ra, i);
-    })
-    .Repeat("REG_DELEGATERS", (*d).GetParameters(),
-        [&](ReplaceAll& ra, const std::unique_ptr<tidl::Parameter>& i) {
-      return SetRegDelegaters(ra, i);
-    })
-    .Remove("HAS_RETURN", (*d).GetType().ToString() == "void" )
-    .Replace("TYPE", [&]() {
-      return ConvertTypeToString((*d).GetType());
-    });
+      .Replace("PARAMS", GetParameters(d->GetParameters()))
+      //    .Replace("RET", GetRetExpr(*d))
+      .Replace("METHOD_ID", SnakeToPascal((*d).GetID()))
+      .Repeat("SENDER_BODY", (*d).GetParameters(),
+              [&](ReplaceAll& ra, const std::unique_ptr<tidl::Parameter>& i) {
+                return SetSenderBody(ra, i);
+              })
+      .Remove("ASYNC", (*d).GetMethodType() == Declaration::MethodType::SYNC)
+      .Remove("SYNC", (*d).GetMethodType() == Declaration::MethodType::ASYNC)
+      .Repeat("RECEIVER_BODY", (*d).GetParameters(),
+              [&](ReplaceAll& ra, const std::unique_ptr<tidl::Parameter>& i) {
+                return SetReceiverBody(ra, i);
+              })
+      .Repeat("REG_DELEGATERS", (*d).GetParameters(),
+              [&](ReplaceAll& ra, const std::unique_ptr<tidl::Parameter>& i) {
+                return SetRegDelegaters(ra, i);
+              })
+      .Remove("HAS_RETURN", (*d).GetType().ToString() == "void")
+      .Replace("HASH_RESULT", std::to_string(GetHashCode("[RESULT]")))
+      .Replace("TYPE", [&]() { return ConvertTypeToString((*d).GetType()); });
   return true;
 }
 
 void RsProxyGen::SetFile(ReplaceAll& ra,
-    const std::unique_ptr<tidl::Parameter>& i) {
+                         const std::unique_ptr<tidl::Parameter>& i) {
   std::string type = GetFullNameFromType(i->GetParameterType().GetBaseType());
 
   ra.Remove("FILE", type != "file")
-    .Remove("FILESLIST", type != "list_file")
-    .Remove("FILESARRAY", type != "array_file");
+      .Remove("FILESLIST", type != "list_file")
+      .Remove("FILESARRAY", type != "array_file");
 }
 
 bool RsProxyGen::SetSenderBody(ReplaceAll& ra,
-    const std::unique_ptr<tidl::Parameter>& i) {
+                               const std::unique_ptr<tidl::Parameter>& i) {
   if (i->GetParameterType().GetDirection() == ParameterType::Direction::OUT)
     return false;
 
   SetFile(ra, i);
 
-  ra.Replace("ID", i->GetID());
+  ra.Replace("ID", i->GetID())
+      .Replace("REF_TAG",
+               [&]() {
+                 if (i->GetParameterType().GetDirection() ==
+                     ParameterType::Direction::REF)
+                   return "";
+                 return "&";
+               })
+      .Replace("HASH_ID", std::to_string(GetHashCode(i->GetID())));
   return true;
 }
 
 bool RsProxyGen::SetReceiverBody(ReplaceAll& ra,
-    const std::unique_ptr<tidl::Parameter>& i) {
+                                 const std::unique_ptr<tidl::Parameter>& i) {
   if (i->GetParameterType().GetDirection() == ParameterType::Direction::IN)
-        return false;
-  ra.Replace("ID", i->GetID());
+    return false;
+  ra.Replace("ID", i->GetID())
+      .Replace("HASH_ID", std::to_string(GetHashCode(i->GetID())));
+
   return true;
 }
 
 bool RsProxyGen::SetRegDelegaters(ReplaceAll& ra,
-    const std::unique_ptr<tidl::Parameter>& i) {
-  if (!IsDelegateType(i->GetParameterType().GetBaseType()))
-        return false;
+                                  const std::unique_ptr<tidl::Parameter>& i) {
+  if (!IsDelegateType(i->GetParameterType().GetBaseType())) return false;
   ra.Replace("ID", i->GetID());
   return true;
 }
 
 std::string RsProxyGen::GetRetExpr(const Declaration& decl) {
-  if (decl.GetType().ToString() == "void")
-    return "";
+  if (decl.GetType().ToString() == "void") return "";
   return "-> " + ConvertTypeToString(decl.GetType());
 }
 
index 3330ea39e54415d7986692e0ff92b051c04269d5..a70143329765b1de4398cc27431c3960482abd3d 100644 (file)
 
 constexpr const char CB_PROXY_MAIN[] =
 R"__rs_cb(
+#![allow(unused)]
+#![allow(non_snake_case)]
+#![allow(non_camel_case_types)]
+
 extern crate rust_rpc_port;
 <BUNDLE_HEADER_BLOCK?>
 extern crate tizen_bundle;
@@ -28,6 +32,7 @@ use tizen_bundle::tizen_bundle::Bundle;
 use rust_rpc_port::parcel::Parcel;
 use rust_rpc_port::proxy::{Proxy, Receive};
 use rust_rpc_port::{Port, PortType};
+use std::any::Any;
 use std::sync::{Arc, Mutex};
 use std::collections::{LinkedList, HashMap, HashSet};
 use std::sync::atomic::{AtomicI32, Ordering};
@@ -108,7 +113,7 @@ pub enum Exception {
 pub mod <STRUCT_MOD_NAME> {
     use super::*;
     <ENUM*>
-    #[derive(Copy, Clone)]
+    #[derive(Copy, Clone, Debug)]
     pub enum <ENUM_NAME> {
         <PROPERTIES*>
         <ID>,
@@ -175,21 +180,13 @@ pub mod <MOD_NAME> {
 
     impl Writeable for DelegateBase {
         fn write_parcel(&self, parcel: &mut Parcel) {
-            self.id.write_parcel(parcel);
-            self.seq_id.write_parcel(parcel);
-            self.once.write_parcel(parcel);
-        }
-        fn write_unit(&self, unit: &mut Unit) {
-            let mut __unit_map = UnitMap::new();
-            self.id.write_unitmap("id", &mut __unit_map);
-            self.seq_id.write_unitmap("seq_id", &mut __unit_map);
-            self.once.write_unitmap("once", &mut __unit_map);
-            __unit_map.serialize(unit.get_mut_parcel());
+            parcel.write_i32(self.id);
+            parcel.write_i32(self.seq_id);
+            parcel.write_bool(self.once);
         }
-        fn write_unitmap(&self, name: &str, unit_map: &mut UnitMap) {
-            let mut unit = Unit::new(String::from(name), String::from("delegate"));
-            unit.write(self);
-            unit_map.insert(String::from(name), unit);
+
+        fn get_unit_type(&self) -> i32 {
+            <HASH_DELEGATE> /*delegate*/
         }
     }
 
@@ -199,24 +196,11 @@ pub mod <MOD_NAME> {
             self.seq_id.read_parcel(parcel);
             self.once.read_parcel(parcel);
         }
-        fn read_unit(&mut self, unit: &Unit) {
-            let mut __unit_map = UnitMap::new();
-            __unit_map.deserialize(unit.get_parcel());
-
-            let mut __tmp_id: i32 = Default::default();
-            __unit_map.read("id", &mut __tmp_id);
-            self.id = __tmp_id;
-            let mut __tmp_seq_id: i32 = Default::default();
-            __unit_map.read("seq_id", &mut __tmp_seq_id);
-            self.seq_id = __tmp_seq_id;
-            let mut __tmp_once: bool = Default::default();
-            __unit_map.read("once", &mut __tmp_once);
-            self.once = __tmp_once;
-        }
-        fn read_unitmap(&mut self, name: String, unit_map: &UnitMap) {
-            match unit_map.lookup(name.as_str()) {
+
+        fn read_unitmap(&mut self, name: i32, unit_map: &UnitMap) {
+            match unit_map.lookup(name) {
                 Some(unit) => {
-                    if unit.get_type().ne(&"delegate") {
+                    if unit.get_type() !=  <HASH_DELEGATE> /*delegate*/ {
                         error!("type({}) is not delegate", unit.get_type());
                         return;
                     }
@@ -232,36 +216,42 @@ pub mod <MOD_NAME> {
     }
 
     <DELEGATES*>
-    pub struct <METHOD_NAME><'a> {
+    pub struct <METHOD_NAME> {
         base: DelegateBase,
-        callback: Box<dyn Fn(<TYPES>) + Send + 'a>
+        callback: Box<dyn Fn(<TYPES>, &Option<Box<dyn Any + Send>>) + Send>,
+        data: Option<Box<dyn Any + Send>>,
     }
 
-    impl<'b> <METHOD_NAME><'b> {
-        pub fn new(once: bool) -> <METHOD_NAME><'b> {
+    impl <METHOD_NAME> {
+        pub fn new(once: bool) -> Self {
             Self {
                 base: DelegateBase {
                     id: DelegateId::<METHOD_NAME> as i32,
                     seq_id: SEQ_NUM.fetch_add(1, Ordering::SeqCst),
                     once,
                 },
-                callback: Box::new(|<IDS>|{})
+                callback: Box::new(|<IDS>, _|{}),
+                data: None,
             }
         }
 
-        fn write_unitmap(&self, name: &str, unit_map: &mut UnitMap) {
-            self.base.write_unitmap(name, unit_map);
-        }
-
         pub fn on_received<F>(&mut self, handler: F)
         where
-            F: Fn(<TYPES>) + Send + 'b,
+            F: Fn(<TYPES>, &Option<Box<dyn Any + Send>>) + Send + 'static,
         {
             self.callback = Box::new(handler);
         }
+
+        pub fn get_data(&self) -> &Option<Box<dyn Any + Send>> {
+            &self.data
+        }
+
+        pub fn set_data(&mut self, d: Option<Box<dyn Any + Send>>) {
+            self.data = d;
+        }
     }
 
-    impl Delegate for <METHOD_NAME><'_> {
+    impl Delegate for <METHOD_NAME> {
         fn invoke(&self, unit_map: &UnitMap, id: i32, seq_id: i32) -> bool {
             if id != self.base.id || seq_id != self.base.seq_id {
               return false;
@@ -269,19 +259,30 @@ pub mod <MOD_NAME> {
 
             <RECEIVER_BODY*>
             let mut <ID>: <TYPE> = Default::default();
-            <ID>.read_unitmap("<ID>".to_string(), &unit_map);
+            <ID>.read_unitmap(<HASH_ID> /*<ID>*/, &unit_map);
             </RECEIVER_BODY*>
             let cb = &self.callback;
-            cb(<IDS>);
+            cb(<IDS>, self.get_data());
             true
         }
     }
+
+    impl Writeable for <METHOD_NAME> {
+        fn write_parcel(&self, parcel: &mut Parcel) {
+           self.base.write_parcel(parcel);
+        }
+
+        fn get_unit_type(&self) -> i32 {
+            self.base.get_unit_type()
+        }
+    }
+
     </DELEGATES*>
     </DELEGATE_BLOCK!>
 
     <INTERFACE_BLOCK!>
     <ENUM*>
-    #[derive(Copy, Clone)]
+    #[derive(Copy, Clone, Debug)]
     pub enum <ENUM_NAME> {
         <PROPERTIES*>
         <ID>,
@@ -297,7 +298,7 @@ pub mod <MOD_NAME> {
 
     pub struct <IFACE_NAME><'a> {
         proxy: Arc<Mutex<Proxy<'a>>>,
-        delegate_list: Vec<Box<dyn Delegate + Send + 'a>>,
+        delegate_list: Vec<Box<dyn Delegate + Send>>,
     }
 
     impl Receive for <IFACE_NAME><'_> {
@@ -416,7 +417,7 @@ pub mod <MOD_NAME> {
             let mut __unit_map = UnitMap::new();
             __unit_map.deserialize(&__parcel_received);
             let mut __cmd: i32 = -1;
-            let unit = __unit_map.lookup("[METHOD]");
+            let unit = __unit_map.lookup(<HASH_METHOD> /*[METHOD]*/);
             match unit {
                 Some(u) => {
                     u.read(&mut __cmd);
@@ -433,7 +434,7 @@ pub mod <MOD_NAME> {
             }
 
             let mut __delegate_base: DelegateBase = DelegateBase::default();
-            __delegate_base.read_unitmap("delegate".to_string(), &mut __unit_map);
+            __delegate_base.read_unitmap(<HASH_DELEGATE> /*delegate*/, &mut __unit_map);
             for (pos, delegate) in self.delegate_list.iter().enumerate() {
                 if delegate.invoke(&__unit_map, __delegate_base.id, __delegate_base.seq_id) {
                     if __delegate_base.once {
@@ -452,8 +453,9 @@ pub mod <MOD_NAME> {
             info!("get seq_num {seq_num}");
             let __port = self.proxy.lock().unwrap().get_port(&PortType::Main);
 
+            let __method_id = (MethodId::<METHOD_ID> as i32);
             let mut __map = UnitMap::new();
-            (MethodId::<METHOD_ID> as i32).write_unitmap("[METHOD]", &mut __map);
+            __map.insert(Unit::new_for_write(<HASH_METHOD> /*[METHOD]*/, &__method_id));
             <SENDER_BODY*>
             <FILE?>
             __port.set_private_sharing(&<ID>);
@@ -465,13 +467,14 @@ pub mod <MOD_NAME> {
             <FILESARRAY?>
             __port.set_private_sharing_array(&<ID>);
             </FILESARRAY?>
-            <ID>.write_unitmap("<ID>", &mut __map);
+            __map.insert(Unit::new_for_write(<HASH_ID> /*<ID>*/, <REF_TAG><ID>));
             </SENDER_BODY*>
+            __map.serialize(&mut __p);
+            drop(__map);
             <REG_DELEGATERS*>
             self.delegate_list.push(Box::new(<ID>));
             </REG_DELEGATERS*>
 
-            __map.serialize(&mut __p);
             let __r = __p.try_send(&__port);
             if let Err(id) = __r {
                 error!("fail to send");
@@ -491,7 +494,7 @@ pub mod <MOD_NAME> {
 
                 __map_received.deserialize(&__parcel_received);
                 let mut cmd: i32 = -1;
-                __map_received.read("[METHOD]", &mut cmd);
+                __map_received.read(<HASH_METHOD> /*[METHOD]*/, &mut cmd);
                 let cmd_exp = MethodId::__Result as i32;
                 if cmd == cmd_exp {
                     break;
@@ -502,19 +505,19 @@ pub mod <MOD_NAME> {
                 error!("received map size is zero");
             }
 
-            if let Some(unit) = __map_received.lookup("[REMOTE_EXCEPTION]") {
+            if let Some(unit) = __map_received.lookup(<HASH_REMOTE_EXCEPTION> /*[REMOTE_EXCEPTION]*/) {
                 let mut __remote_exception = RemoteException::new();
-                __remote_exception.read_unit(unit);
+                unit.read(&mut __remote_exception);
                 error!("seq_num {seq_num} exception {:?}", Exception::RemoteException(__remote_exception.clone()));
                 return Err(Exception::RemoteException(__remote_exception));
             }
 
             <RECEIVER_BODY*>
-            __map_received.read("<ID>", <ID>);
+            __map_received.read(<HASH_ID> /*<ID>*/, <ID>);
             </RECEIVER_BODY*>
             <HAS_RETURN?>
             let mut __ret: <TYPE> = Default::default();
-            __map_received.read("[RESULT]", &mut __ret);
+            __map_received.read(<HASH_RESULT> /*[RESULT]*/, &mut __ret);
             Ok(__ret)
             </HAS_RETURN?>
             </SYNC?>
index 5e6d2c18e34179188a4d40be82dab44e199af9cd..07b69e919b552111024d9e5ed1b07e3c335a2ca3 100644 (file)
@@ -27,7 +27,7 @@ namespace version2 {
 
 RsStubGen::RsStubGen(std::shared_ptr<Document> doc,
                      std::shared_ptr<Options> options)
-      : RsGeneratorBase(doc), options_(std::move(options)) {}
+    : RsGeneratorBase(doc), options_(std::move(options)) {}
 
 void RsStubGen::OnInitGen(std::ofstream& stream) {
   RsGeneratorBase::OnInitGen(stream);
@@ -35,11 +35,16 @@ void RsStubGen::OnInitGen(std::ofstream& stream) {
   ReplaceAll(::CB_STUB_MAIN)
       .Replace("VERSION", std::string(FULLVER))
       .Repeat("STRUCTS", GetDocument().GetBlocks(),
-            [&](ReplaceAll& ra, const std::shared_ptr<Block>& i) {
-          return SetStructs(ra, i);
-        })
+              [&](ReplaceAll& ra, const std::shared_ptr<Block>& i) {
+                return SetStructs(ra, i);
+              })
       .ReplaceBlock("MODULE_BLOCK", [&](ReplaceAll& ra) { SetModules(ra); })
       .Remove("BUNDLE_HEADER_BLOCK", RsGeneratorBase::HasBundle() != true)
+      .Replace("HASH_METHOD", std::to_string(GetHashCode("[METHOD]")))
+      .Replace("HASH_REMOTE_EXCEPTION",
+               std::to_string(GetHashCode("[REMOTE_EXCEPTION]")))
+      .Replace("HASH_RESULT", std::to_string(GetHashCode("[RESULT]")))
+      .Replace("HASH_DELEGATE", std::to_string(GetHashCode("delegate")))
       .Out(stream);
   stream.close();
 }
@@ -53,142 +58,139 @@ void RsStubGen::SetModules(ReplaceAll& ra) {
   int m_cnt = 2;
   int d_cnt = 1;
 
-  ra.Repeat("MODULES", GetDocument().GetBlocks(),
+  ra.Repeat(
+      "MODULES", GetDocument().GetBlocks(),
       [&](ReplaceAll& ra, const std::shared_ptr<Block>& i) {
-    if (i->GetType() != Block::TYPE_INTERFACE)
-      return false;
-    Interface& iface = static_cast<Interface&>(*i);
-    ra.Replace("MOD_NAME", PascalToSnake(iface.GetID()))
-        .Repeat("METHOD_ID", iface.GetDeclarations(),
-            [&](ReplaceAll& ra, const std::unique_ptr<Declaration>& d){
-          return SetMethodIDs(ra, d, m_cnt);
-        })
-        .Repeat("DELEGATE_ID", iface.GetDeclarations(),
-            [&](ReplaceAll& ra, const std::unique_ptr<Declaration>& d){
-          return SetDelegateIDs(ra, d, d_cnt);
-        })
-        .ReplaceBlock("DELEGATE_BLOCK", [&](ReplaceAll& ra) {
-          SetDelegateBlock(ra, iface);
-        })
-        .Repeat("ENUM",  iface.GetEnums(),
-            [&](ReplaceAll& ra, const std::unique_ptr<Enum>& e) {
-          return SetEnum(ra, e);
-        })
-        .ReplaceBlock("INTERFACE_BLOCK", [&](ReplaceAll& ra) {
-          SetInterfaceBlock(ra, iface);
-        })
-        .RemoveAll("EXTENSION_BLOCK", options_->UseExtension() != true);
-    return true;
-  });
+        if (i->GetType() != Block::TYPE_INTERFACE) return false;
+        Interface& iface = static_cast<Interface&>(*i);
+        ra.Replace("MOD_NAME", PascalToSnake(iface.GetID()))
+            .Repeat("METHOD_ID", iface.GetDeclarations(),
+                    [&](ReplaceAll& ra, const std::unique_ptr<Declaration>& d) {
+                      return SetMethodIDs(ra, d, m_cnt);
+                    })
+            .Repeat("DELEGATE_ID", iface.GetDeclarations(),
+                    [&](ReplaceAll& ra, const std::unique_ptr<Declaration>& d) {
+                      return SetDelegateIDs(ra, d, d_cnt);
+                    })
+            .ReplaceBlock("DELEGATE_BLOCK",
+                          [&](ReplaceAll& ra) { SetDelegateBlock(ra, iface); })
+            .Repeat("ENUM", iface.GetEnums(),
+                    [&](ReplaceAll& ra, const std::unique_ptr<Enum>& e) {
+                      return SetEnum(ra, e);
+                    })
+            .ReplaceBlock("INTERFACE_BLOCK",
+                          [&](ReplaceAll& ra) { SetInterfaceBlock(ra, iface); })
+            .RemoveAll("EXTENSION_BLOCK", options_->UseExtension() != true);
+        return true;
+      });
 }
 
 bool RsStubGen::SetMethodIDs(ReplaceAll& ra,
-    const std::unique_ptr<Declaration>& d, int& cnt) {
-  if (d->GetMethodType() == Declaration::MethodType::DELEGATE)
-    return false;
+                             const std::unique_ptr<Declaration>& d, int& cnt) {
+  if (d->GetMethodType() == Declaration::MethodType::DELEGATE) return false;
 
   ra.Replace("ID", SnakeToPascal(d->GetID()))
-    .Replace("COUNT", std::to_string(cnt++));
+      .Replace("COUNT", std::to_string(cnt++));
   return true;
 }
 
 bool RsStubGen::SetDelegateIDs(ReplaceAll& ra,
-    const std::unique_ptr<Declaration>& d, int& cnt) {
-  if (d->GetMethodType() != Declaration::MethodType::DELEGATE)
-    return false;
+                               const std::unique_ptr<Declaration>& d,
+                               int& cnt) {
+  if (d->GetMethodType() != Declaration::MethodType::DELEGATE) return false;
 
   ra.Replace("ID", SnakeToPascal(d->GetID()))
-    .Replace("COUNT", std::to_string(cnt++));
+      .Replace("COUNT", std::to_string(cnt++));
   return true;
 }
 
-
 void RsStubGen::SetDelegateBlock(ReplaceAll& ra, const Interface& iface) {
   auto& decls = iface.GetDeclarations();
 
-  ra.Repeat("DELEGATES", decls,
+  ra.Repeat(
+      "DELEGATES", decls,
       [&](ReplaceAll& ra, const std::unique_ptr<Declaration>& i) {
-    if (i->GetMethodType() != Declaration::MethodType::DELEGATE)
-      return false;
-    ra.Replace("TYPES", GetParameters(i->GetParameters(), true))
-      .Repeat("REPLY_BODY", i->GetParameters(),
-          [&](ReplaceAll& ra, const std::unique_ptr<tidl::Parameter>& p) {
-        ra.Replace("ID", p->GetID());
+        if (i->GetMethodType() != Declaration::MethodType::DELEGATE)
+          return false;
+        ra.Replace("TYPES", GetParameters(i->GetParameters(), true))
+            .Repeat(
+                "REPLY_BODY", i->GetParameters(),
+                [&](ReplaceAll& ra, const std::unique_ptr<tidl::Parameter>& p) {
+                  ra.Replace("ID", p->GetID())
+                      .Replace("HASH_ID",
+                               std::to_string(GetHashCode(p->GetID())));
+                  return true;
+                })
+            .Replace("METHOD_NAME", SnakeToPascal(i->GetID()))
+            .Replace("METHOD_ORG_NAME", i->GetID());
         return true;
-      })
-      .Replace("METHOD_NAME", SnakeToPascal(i->GetID()))
-      .Replace("METHOD_ORG_NAME", i->GetID());
-    return true;
-  });
+      });
 }
 
 void RsStubGen::SetInterfaceBlock(ReplaceAll& ra, const Interface& iface) {
   ra.Repeat("ENUM", iface.GetEnums(),
-      [&](ReplaceAll& ra, const std::unique_ptr<Enum>& e) {
-    return SetEnum(ra, e);
-  });
+            [&](ReplaceAll& ra, const std::unique_ptr<Enum>& e) {
+              return SetEnum(ra, e);
+            });
 
   ra.Replace("IFACE_NAME", iface.GetID())
-    .Repeat("METHODS_PROTO", iface.GetDeclarations(),
-        [&](ReplaceAll& ra, const std::unique_ptr<Declaration>& d){
-      return SetMethod(ra, d);
-    })
-    .Repeat("METHODS", iface.GetDeclarations(),
-        [&](ReplaceAll& ra, const std::unique_ptr<Declaration>& d){
-      return SetMethod(ra, d);
-    })
-    .Repeat("DISPATCHES", iface.GetDeclarations(),
-        [&](ReplaceAll& ra, const std::unique_ptr<Declaration>& d) {
-      if (d->GetMethodType() == Declaration::MethodType::DELEGATE)
-        return false;
-
-      ra.Replace("ID", d->GetID())
-        .Replace("SNAKE_ID", PascalToSnake(d->GetID()));
-      return true;
-    })
-    .Repeat("PRIVILEGES", iface.GetDeclarations(),
-        [&](ReplaceAll& ra, const std::unique_ptr<Declaration>& d) {
-          if (d->GetMethodType() == Declaration::MethodType::DELEGATE)
-            return false;
-
-          std::vector<std::string> privileges;
-          for (auto& attr : d->GetAttributes()) {
-            if (attr->GetKey() != "privilege")
-              continue;
-
-            privileges.push_back(attr->GetValue());
-          }
-          if (privileges.empty())
-            return false;
-
-          ra.Repeat("PRIVILEGE", privileges,
-              [&](ReplaceAll& ra, const std::string& priv) {
-            ra.Replace("ID", priv);
-            return true;
-          })
-          .Replace("METHOD", SnakeToPascal(d->GetID()));
-          return true;
-        })
-        .Repeat("INTERFACE_PRIVILEGES", iface.GetAttributes(),
+      .Repeat("METHODS_PROTO", iface.GetDeclarations(),
+              [&](ReplaceAll& ra, const std::unique_ptr<Declaration>& d) {
+                return SetMethod(ra, d);
+              })
+      .Repeat("METHODS", iface.GetDeclarations(),
+              [&](ReplaceAll& ra, const std::unique_ptr<Declaration>& d) {
+                return SetMethod(ra, d);
+              })
+      .Repeat("DISPATCHES", iface.GetDeclarations(),
+              [&](ReplaceAll& ra, const std::unique_ptr<Declaration>& d) {
+                if (d->GetMethodType() == Declaration::MethodType::DELEGATE)
+                  return false;
+
+                ra.Replace("ID", d->GetID())
+                    .Replace("SNAKE_ID", PascalToSnake(d->GetID()));
+                return true;
+              })
+      .Repeat("PRIVILEGES", iface.GetDeclarations(),
+              [&](ReplaceAll& ra, const std::unique_ptr<Declaration>& d) {
+                if (d->GetMethodType() == Declaration::MethodType::DELEGATE)
+                  return false;
+
+                std::vector<std::string> privileges;
+                for (auto& attr : d->GetAttributes()) {
+                  if (attr->GetKey() != "privilege") continue;
+
+                  privileges.push_back(attr->GetValue());
+                }
+                if (privileges.empty()) return false;
+
+                ra.Repeat("PRIVILEGE", privileges,
+                          [&](ReplaceAll& ra, const std::string& priv) {
+                            ra.Replace("ID", priv);
+                            return true;
+                          })
+                    .Replace("METHOD", SnakeToPascal(d->GetID()));
+                return true;
+              })
+      .Repeat(
+          "INTERFACE_PRIVILEGES", iface.GetAttributes(),
           [&](ReplaceAll& ra, const std::unique_ptr<tidl::Attribute>& attr) {
-            if (attr->GetKey() != "privilege")
-              return false;
+            if (attr->GetKey() != "privilege") return false;
 
             ra.Replace("INTERFACE_PRIVILEGE", attr->GetValue());
             return true;
-          }
-        )
-        .Remove("SET_TRUSTED", std::find_if(
-                iface.GetAttributes().begin(),
-                iface.GetAttributes().end(),
-                [](const auto& attr) {
-                  return attr->GetKey() == "trusted" && attr->GetValue() == "true";
-                }) == iface.GetAttributes().end());
+          })
+      .Remove("SET_TRUSTED",
+              std::find_if(iface.GetAttributes().begin(),
+                           iface.GetAttributes().end(), [](const auto& attr) {
+                             return attr->GetKey() == "trusted" &&
+                                    attr->GetValue() == "true";
+                           }) == iface.GetAttributes().end());
 }
 
-bool RsStubGen::SetMethod(ReplaceAll& ra, const std::unique_ptr<Declaration>& d) {
-  if (d->GetMethodType() == Declaration::MethodType::DELEGATE)
-    return false;
+bool RsStubGen::SetMethod(ReplaceAll& ra,
+                          const std::unique_ptr<Declaration>& d) {
+  if (d->GetMethodType() == Declaration::MethodType::DELEGATE) return false;
 
   if (!d->GetComments().empty())
     ra.Replace("COMMENTS", AddIndent(2 * TAB_SIZE, d->GetComments()));
@@ -209,10 +211,12 @@ bool RsStubGen::SetMethod(ReplaceAll& ra, const std::unique_ptr<Declaration>& d)
               [&](ReplaceAll& ra, const std::unique_ptr<tidl::Parameter>& p) {
                 if (p->GetParameterType().GetBaseType().IsDelegateType())
                   return false;
-                ra.Remove("IS_OUT_DIR", p->GetParameterType().GetDirection() == ParameterType::Direction::OUT)
-                  .Replace("ID", p->GetID())
-                  .Replace("TYPE", ConvertTypeToString(
-                      p->GetParameterType().GetBaseType()));
+                ra.Remove("IS_OUT_DIR", p->GetParameterType().GetDirection() ==
+                                            ParameterType::Direction::OUT)
+                    .Replace("ID", p->GetID())
+                    .Replace("HASH_ID", std::to_string(GetHashCode(p->GetID())))
+                    .Replace("TYPE", ConvertTypeToString(
+                                         p->GetParameterType().GetBaseType()));
                 return true;
               })
       .Repeat("DELEGATER_RECEIVER_BODY", (*d).GetParameters(),
@@ -220,17 +224,21 @@ bool RsStubGen::SetMethod(ReplaceAll& ra, const std::unique_ptr<Declaration>& d)
                 if (!p->GetParameterType().GetBaseType().IsDelegateType())
                   return false;
                 ra.Replace("ID", p->GetID())
-                  .Replace("TYPE", ConvertTypeToString(
-                      p->GetParameterType().GetBaseType()));
+                    .Replace("HASH_ID", std::to_string(GetHashCode(p->GetID())))
+                    .Replace("TYPE", ConvertTypeToString(
+                                         p->GetParameterType().GetBaseType()));
                 return true;
               })
       .Repeat("RETURNS", (*d).GetParameters(),
               [&](ReplaceAll& ra, const std::unique_ptr<tidl::Parameter>& p) {
-                if (p->GetParameterType().GetDirection() == ParameterType::Direction::IN ||
+                if (p->GetParameterType().GetDirection() ==
+                        ParameterType::Direction::IN ||
                     p->GetParameterType().GetBaseType().IsDelegateType())
                   return false;
 
-                ra.Replace("ID", p->GetID());
+                ra.Replace("ID", p->GetID())
+                    .Replace("HASH_ID",
+                             std::to_string(GetHashCode(p->GetID())));
                 return true;
               })
       .Replace("IDS", GetParameterIDsWithDir((*d).GetParameters()))
@@ -239,16 +247,16 @@ bool RsStubGen::SetMethod(ReplaceAll& ra, const std::unique_ptr<Declaration>& d)
 }
 
 void RsStubGen::SetFile(ReplaceAll& ra,
-    const std::unique_ptr<tidl::Parameter>& i) {
+                        const std::unique_ptr<tidl::Parameter>& i) {
   std::string type = GetFullNameFromType(i->GetParameterType().GetBaseType());
 
   ra.Remove("FILE", type != "file")
-    .Remove("FILESLIST", type != "list_file")
-    .Remove("FILESARRAY", type != "array_file");
+      .Remove("FILESLIST", type != "list_file")
+      .Remove("FILESARRAY", type != "array_file");
 }
 
 bool RsStubGen::SetSenderBody(ReplaceAll& ra,
-    const std::unique_ptr<tidl::Parameter>& i) {
+                              const std::unique_ptr<tidl::Parameter>& i) {
   if (i->GetParameterType().GetDirection() == ParameterType::Direction::OUT)
     return false;
 
@@ -259,16 +267,15 @@ bool RsStubGen::SetSenderBody(ReplaceAll& ra,
 }
 
 bool RsStubGen::SetReceiverBody(ReplaceAll& ra,
-    const std::unique_ptr<tidl::Parameter>& i) {
+                                const std::unique_ptr<tidl::Parameter>& i) {
   if (i->GetParameterType().GetDirection() == ParameterType::Direction::IN)
-        return false;
+    return false;
   ra.Replace("ID", i->GetID());
   return true;
 }
 
 std::string RsStubGen::GetRetExpr(const Declaration& decl) {
-  if (decl.GetType().ToString() == "void")
-    return "";
+  if (decl.GetType().ToString() == "void") return "";
   return "-> " + ConvertTypeToString(decl.GetType());
 }
 
index 0245a7155d08cab9abee80b377a74232e4c941ea..4e91f63debc23e582aa6d29e1ccf675b64de78da 100644 (file)
 
 constexpr const char CB_STUB_MAIN[] =
 R"__rs_cb(
+#![allow(unused)]
+#![allow(non_snake_case)]
+#![allow(non_camel_case_types)]
+
 extern crate rust_rpc_port;
 <BUNDLE_HEADER_BLOCK?>
 extern crate tizen_bundle;
@@ -126,7 +130,7 @@ pub enum Exception {
 pub mod <STRUCT_MOD_NAME> {
     use super::*;
     <ENUM*>
-    #[derive(Copy, Clone)]
+    #[derive(Copy, Clone, Debug)]
     pub enum <ENUM_NAME> {
         <PROPERTIES*>
         <ID>,
@@ -260,15 +264,17 @@ pub mod <MOD_NAME> {
                 return Err(ErrorId::IoError);
             }
 
+            let mut __parcel = Parcel::new();
+            let __method_id = (MethodId::__Callback as i32);
             let mut __unit_map = UnitMap::new();
-            (MethodId::__Callback as i32).write_unitmap("[METHOD]", &mut __unit_map);
-            self.write_unitmap("delegate", &mut __unit_map);
+            __unit_map.insert(Unit::new_for_write(<HASH_METHOD> /*[METHOD]*/, &__method_id))
+                .insert(Unit::new_for_write(<HASH_DELEGATE> /*delegate*/, self))
             <REPLY_BODY*>
-            <ID>.write_unitmap("<ID>", &mut __unit_map);
+                .insert(Unit::new_for_write(<HASH_ID> /*<ID>*/, &<ID>))
             </REPLY_BODY*>
+                .serialize(&mut __parcel);
+            drop(__unit_map);
 
-            let mut __parcel = Parcel::new();
-            __unit_map.serialize(&mut __parcel);
             if let Err(err) = __parcel.try_send(&self.callback_port) {
                 error!("send failed: {:?}", err);
                 return Err(convert_err(err));
@@ -285,17 +291,9 @@ pub mod <MOD_NAME> {
             self.seq_id.write_parcel(parcel);
             self.once.write_parcel(parcel);
         }
-        fn write_unit(&self, unit: &mut Unit) {
-            let mut __unit_map = UnitMap::new();
-            self.id.write_unitmap("id", &mut __unit_map);
-            self.seq_id.write_unitmap("seq_id", &mut __unit_map);
-            self.once.write_unitmap("once", &mut __unit_map);
-            __unit_map.serialize(unit.get_mut_parcel());
-        }
-        fn write_unitmap(&self, name: &str, unit_map: &mut UnitMap) {
-            let mut unit = Unit::new(String::from(name), String::from("delegate"));
-            unit.write(self);
-            unit_map.insert(String::from(name), unit);
+
+        fn get_unit_type(&self) -> i32 {
+            <HASH_DELEGATE> /*delegate*/
         }
     }
 
@@ -305,24 +303,11 @@ pub mod <MOD_NAME> {
             self.seq_id.read_parcel(parcel);
             self.once.read_parcel(parcel);
         }
-        fn read_unit(&mut self, unit: &Unit) {
-            let mut __unit_map = UnitMap::new();
-            __unit_map.deserialize(unit.get_parcel());
-
-            let mut __tmp_id: i32 = Default::default();
-            __unit_map.read("id", &mut __tmp_id);
-            self.id = __tmp_id;
-            let mut __tmp_seq_id: i32 = Default::default();
-            __unit_map.read("seq_id", &mut __tmp_seq_id);
-            self.seq_id = __tmp_seq_id;
-            let mut __tmp_once: bool = Default::default();
-            __unit_map.read("once", &mut __tmp_once);
-            self.once = __tmp_once;
-        }
-        fn read_unitmap(&mut self, name: String, unit_map: &UnitMap) {
-            match unit_map.lookup(name.as_str()) {
+
+        fn read_unitmap(&mut self, name: i32, unit_map: &UnitMap) {
+            match unit_map.lookup(name) {
                 Some(unit) => {
-                    if unit.get_type().ne(&"delegate") {
+                    if unit.get_type() != <HASH_DELEGATE> /*delegate*/ {
                         error!("type({}) is not delegate", unit.get_type());
                         return;
                     }
@@ -341,7 +326,7 @@ pub mod <MOD_NAME> {
 
     <INTERFACE_BLOCK!>
     <ENUM*>
-    #[derive(Copy, Clone)]
+    #[derive(Copy, Clone, Debug)]
     pub enum <ENUM_NAME> {
         <PROPERTIES*>
         <ID>,
@@ -435,7 +420,7 @@ pub mod <MOD_NAME> {
             unit_map.deserialize(parcel);
 
             let mut cmd: i32 = -1;
-            unit_map.read("[METHOD]", &mut cmd);
+            unit_map.read(<HASH_METHOD> /*[METHOD]*/, &mut cmd);
 
             match cmd {
                 <DISPATCHES*>
@@ -464,7 +449,8 @@ pub mod <MOD_NAME> {
         fn load_privileges(&mut self) {
             let mut app_info: *mut c_void = std::ptr::null_mut();
             let sender = self.get_sender();
-            let ret = unsafe { app_info_create(CString::new(sender).unwrap().as_ptr() as *const c_char, &mut app_info) };
+            let c_sender = CString::new(sender).unwrap();
+            let ret = unsafe { app_info_create(c_sender.as_ptr() as *const c_char, &mut app_info) };
             if ret != 0 {
                 error!("app_info_create failed. ret({})", ret);
                 return;
@@ -522,44 +508,49 @@ pub mod <MOD_NAME> {
 
         <METHODS*>
         fn dispatch_<FN_NAME>(&mut self, port: &Port, callback_port: Arc<Port>, seq_num: i32, unit_map: &UnitMap) {
-            let mut __map = UnitMap::new();
+            let mut __parcel = Parcel::new();
+            __parcel.set_seq_num(seq_num);
+            let __method_id = (MethodId::__Result as i32);
+
             <SYNC?>
-            match self.check_privileges(MethodId::<METHOD_ID> as i32) {
-                false => {
-                    error!("Permission denied");
-                    let remote_except = RemoteException::with_cause_and_message(ErrorId::PermissionDenied as i32, "Permission denied");
-                    remote_except.write_unitmap("[REMOTE_EXCEPTION]", &mut __map);
-                }
-                true => {
-                    <RECEIVER_BODY*>
-                    let mut <ID>: <TYPE> = Default::default();
-                    <IS_OUT_DIR?>
-                    unit_map.read("<ID>", &mut <ID>);
-                    </IS_OUT_DIR?>
-                    </RECEIVER_BODY*>
-                    <DELEGATER_RECEIVER_BODY*>
-                    let mut <ID> = <TYPE>::new(callback_port);
-                    unit_map.read("<ID>", &mut <ID>);
-                    </DELEGATER_RECEIVER_BODY*>
-                    match self.handler.<FN_NAME>(<IDS>) {
-                        Ok(ret) => {
-                            ret.write_unitmap("[RESULT]", &mut __map);
-                            <RETURNS*>
-                            <ID>.write_unitmap("<ID>", &mut __map);
-                            </RETURNS*>
-                        }
-                        Err(err) => {
-                            error!("Error: cause({}), message({})", err.cause, err.message);
-                            err.write_unitmap("[REMOTE_EXCEPTION]", &mut __map);
-                        }
+            if !self.check_privileges(MethodId::<METHOD_ID> as i32) {
+                error!("Permission denied");
+                let remote_except = RemoteException::with_cause_and_message(ErrorId::PermissionDenied as i32, "Permission denied");
+                let mut __map = UnitMap::new();
+                __map.insert(Unit::new_for_write(<HASH_REMOTE_EXCEPTION> /*[REMOTE_EXCEPTION]*/, &remote_except))
+                    .insert(Unit::new_for_write(<HASH_METHOD> /*[METHOD]*/, &__method_id))
+                    .serialize(&mut __parcel);
+            } else {
+                <RECEIVER_BODY*>
+                let mut <ID>: <TYPE> = Default::default();
+                <IS_OUT_DIR?>
+                unit_map.read(<HASH_ID> /*<ID>*/, &mut <ID>);
+                </IS_OUT_DIR?>
+                </RECEIVER_BODY*>
+                <DELEGATER_RECEIVER_BODY*>
+                let mut <ID> = <TYPE>::new(callback_port);
+                unit_map.read(<HASH_ID> /*<ID>*/, &mut <ID>);
+                </DELEGATER_RECEIVER_BODY*>
+                match self.handler.<FN_NAME>(<IDS>) {
+                    Ok(ret) => {
+                        let mut __map = UnitMap::new();
+                        __map.insert(Unit::new_for_write(<HASH_RESULT> /*[RESULT]*/, &ret))
+                        <RETURNS*>
+                            .insert(Unit::new_for_write(<HASH_ID> /*<ID>*/, &<ID>))
+                        </RETURNS*>
+                            .insert(Unit::new_for_write(<HASH_METHOD> /*[METHOD]*/, &__method_id))
+                            .serialize(&mut __parcel);
+                    }
+                    Err(err) => {
+                        error!("Error: cause({}), message({})", err.cause, err.message);
+                        let mut __map = UnitMap::new();
+                        __map.insert(Unit::new_for_write(<HASH_REMOTE_EXCEPTION> /*[REMOTE_EXCEPTION]*/, &err))
+                            .insert(Unit::new_for_write(<HASH_METHOD> /*[METHOD]*/, &__method_id))
+                            .serialize(&mut __parcel);
                     }
                 }
             }
 
-            (MethodId::__Result as i32).write_unitmap("[METHOD]", &mut __map);
-            let mut __parcel = Parcel::new();
-            __parcel.set_seq_num(seq_num);
-            __map.serialize(&mut __parcel);
             if let Err(ret) = __parcel.try_send(port) {
                 error!("Failed to send parcel {}", ret);
             }
@@ -572,11 +563,11 @@ pub mod <MOD_NAME> {
 
             <RECEIVER_BODY*>
             let mut <ID>: <TYPE> = Default::default();
-            unit_map.read("<ID>", &mut <ID>);
+            unit_map.read(<HASH_ID> /*<ID>*/, &mut <ID>);
             </RECEIVER_BODY*>
             <DELEGATER_RECEIVER_BODY*>
             let mut <ID> = <TYPE>::new(callback_port);
-            unit_map.read("<ID>", &mut <ID>);
+            unit_map.read(<HASH_ID> /*<ID>*/, &mut <ID>);
             </DELEGATER_RECEIVER_BODY*>
             if let Err(err) = &self.handler.<FN_NAME>(<IDS>) {
                 error!("Error: cause({}), message({}", err.cause, err.message);
@@ -604,18 +595,18 @@ pub mod <MOD_NAME> {
                 services: vec![],
             }));
 
-            let mut clone_ret = ret.clone();
+            let clone_ret = ret.clone();
             s.lock().unwrap().on_connected(move |sender, instance| {
                 let mut service = Box::new(Service::new(sender, instance, &T::new));
-                let mut port = clone_ret.lock().unwrap().get_port(&PortType::Callback, instance);
+                let port = clone_ret.lock().unwrap().get_port(&PortType::Callback, instance);
                 service.set_port(port);
                 service.on_create();
                 clone_ret.lock().unwrap().services.push(service);
             });
 
-            let mut clone_ret = ret.clone();
+            let clone_ret = ret.clone();
             s.lock().unwrap().on_disconnected(move |sender, instance| {
-                let mut services = &mut clone_ret.lock().unwrap().services;
+                let services = &mut clone_ret.lock().unwrap().services;
                 services.retain_mut(|svc| {
                     if svc.get_instance() == instance {
                         svc.on_terminate();
@@ -626,11 +617,11 @@ pub mod <MOD_NAME> {
                 });
             });
 
-            let mut clone_ret = ret.clone();
+            let clone_ret = ret.clone();
             s.lock().unwrap().on_received(move |sender, instance, port| -> i32 {
                 let callback_port = Arc::new(clone_ret.lock().unwrap().get_port(&PortType::Callback, instance));
                 let mut services = &mut clone_ret.lock().unwrap().services;
-                for mut svc in services {
+                for svc in services {
                     if svc.get_instance() == instance {
                         let mut parcel = Parcel::from(port);
                         svc.dispatch(port, callback_port, &mut parcel);