Refactor Unit in C generator for improving performance 82/315682/35
authorpjh9216 <jh9216.park@samsung.com>
Wed, 4 Dec 2024 04:50:41 +0000 (13:50 +0900)
committerJunghoon Park <jh9216.park@samsung.com>
Fri, 20 Dec 2024 00:21:44 +0000 (00:21 +0000)
Change-Id: Ia250d8f04e8e6f08fef558f2041be318746c2430
Signed-off-by: pjh9216 <jh9216.park@samsung.com>
19 files changed:
idlc/gen/c_body_gen_base.cc
idlc/gen/c_body_gen_base.h
idlc/gen/version2/c_body_generator_array_base_cb.hh
idlc/gen/version2/c_body_generator_base.cc
idlc/gen/version2/c_body_generator_base.hh
idlc/gen/version2/c_body_generator_base_cb.hh
idlc/gen/version2/c_body_generator_list_base_cb.hh
idlc/gen/version2/c_body_generator_map_base_cb.hh
idlc/gen/version2/c_body_generator_set_base_cb.hh
idlc/gen/version2/c_group_body_generator.cc
idlc/gen/version2/c_group_body_generator.hh
idlc/gen/version2/c_group_body_generator_cb.hh
idlc/gen/version2/c_header_generator_base_cb.hh
idlc/gen/version2/c_proxy_body_generator.cc
idlc/gen/version2/c_proxy_body_generator.hh
idlc/gen/version2/c_proxy_body_generator_cb.hh
idlc/gen/version2/c_stub_body_generator.cc
idlc/gen/version2/c_stub_body_generator.hh
idlc/gen/version2/c_stub_body_generator_cb.hh

index e187f37a983718c4cf9fe2821a576c3234d90b6b..f1541694e72e5760314fa4a130dfb0edc938bccd 100644 (file)
@@ -68,13 +68,18 @@ CBodyGeneratorBase::CBodyGeneratorBase(std::shared_ptr<Document> doc)
 }
 
 void CBodyGeneratorBase::GenIncludeHeader(std::ofstream& stream) {
+  stream << NLine(1);
+  stream << GetIncludeHeader();
+}
+
+std::string CBodyGeneratorBase::GetIncludeHeader() {
   std::string code;
   code += "#include \"";
   code += FileName.substr(0, FileName.length() - 2);
   code += ".h\"";
-  stream << NLine(1);
-  stream << code;
-  stream << NLine(1);
+  code += NLine(1);
+
+  return code;
 }
 
 void CBodyGeneratorBase::GenLogTag(std::ofstream& stream,
@@ -664,7 +669,10 @@ void CBodyGeneratorBase::GenStructureBase(std::ofstream& stream,
   .Out(stream);
 }
 
-const std::string& CBodyGeneratorBase::GetParcelType(const BaseType& type) {
+std::string CBodyGeneratorBase::GetParcelType(const BaseType& type) {
+  if (type.GetUserDefinedType() == BaseType::UserType::ENUM)
+    return "int32";
+
   if (type.IsUserDefinedType() ||
       type.ToString() == "list" ||
       type.ToString() == "array")
@@ -692,6 +700,10 @@ bool CBodyGeneratorBase::HasListFile(const Interface& iface) {
 
 // @see #CB_PRIVATE_SHARING_LIST_SET
 void CBodyGeneratorBase::GenPrivateSharingListSet(std::ofstream& stream) {
+  stream << GetPrivateSharingListSet();
+}
+
+std::string CBodyGeneratorBase::GetPrivateSharingListSet() {
   bool has_list_file = false;
   for (auto& i : GetDocument().GetBlocks()) {
     if (i->GetType() != Block::TYPE_INTERFACE)
@@ -704,9 +716,9 @@ void CBodyGeneratorBase::GenPrivateSharingListSet(std::ofstream& stream) {
   }
 
   if (!has_list_file)
-    return;
+    return "";
 
-  stream << SmartIndent(std::string(CB_PRIVATE_SHARING_LIST_SET));
+  return SmartIndent(std::string(CB_PRIVATE_SHARING_LIST_SET));
 }
 
 // @see #CB_LIST_FILE_SET_PRIVATE_SHARING
index 9e6f51719b8d0f5d298bb97aaaae19a7634161df..6754a0f56cce48cf65d8cfca01f4c32c7f327d05 100644 (file)
@@ -33,13 +33,15 @@ class CBodyGeneratorBase : public CGeneratorBase {
   void GenStructureDefs(std::ofstream& stream);
   void GenStructures(std::ofstream& stream);
   void GenIncludeHeader(std::ofstream& stream);
+  std::string GetIncludeHeader();
   void GenLogTag(std::ofstream& stream, const std::string& log_tag);
   void GenLogDefinition(std::ofstream& stream);
   void GenVersionDefinition(std::ofstream& stream);
   void GenBaseDefinition(std::ofstream& stream);
-  const std::string& GetParcelType(const BaseType& type);
+  std::string GetParcelType(const BaseType& type);
 
   void GenPrivateSharingListSet(std::ofstream& stream);
+  std::string GetPrivateSharingListSet();
   std::string GetPrivateSharingString(const BaseType& type,
       const Interface& iface, const std::string& port, const std::string& arg);
 
index b2cfa3d92245f6966505b104d27620ee660c2c54..b52e1a19f933c232600768a3878f5545852d3942 100644 (file)
@@ -37,8 +37,6 @@ typedef struct <PREFIX>_<NAME>_s {
 /**
  * <PREFIX> The prefix of the array structure.
  * <NAME> The name of the array structure.
- * <UNIT_MAP_WRITE> The implementation to write the value to the unit map.
- * <UNIT_MAP_READ> The implemention to read the value from the unit map.
  * <PARAM_TYPE_IN> The type of the input parameter.
  * <PARAM_TYPE_OUT> The type of the output parameter.
  * <ELEMENT_TYPE> The type of the element of the array.
@@ -50,8 +48,6 @@ R"__c_cb(
 static void __<PREFIX>_<NAME>_to(rpc_port_parcel_h parcel, void *data)
 {
   <PREFIX>_<NAME>_t *handle = data;
-  rpc_port_unit_map_h map;
-  char index[12];
   int i;
 
   if (parcel == nullptr || handle == nullptr) {
@@ -59,29 +55,23 @@ static void __<PREFIX>_<NAME>_to(rpc_port_parcel_h parcel, void *data)
     return;
   }
 
-  map = rpc_port_unit_map_create();
-  if (map == nullptr) {
-    set_last_result(RPC_PORT_ERROR_OUT_OF_MEMORY);
-    return;
-  }
-
-  rpc_port_unit_map_write_int(map, "size", handle->size);
+  rpc_port_parcel_write_array_count(parcel, handle->size);
 
   for (i = 0; i < handle->size; ++i) {
-    snprintf(index, sizeof(index), "%d", i);
-    <UNIT_MAP_WRITE>
+    <IS_DEFAULT_TYPE?>
+    rpc_port_parcel_write_<PARCEL_TYPE>(parcel, handle->value[i]);
+    </IS_DEFAULT_TYPE?>
+    <IS_PARCELABLE_TYPE?>
+    rpc_port_parcel_write(parcel, &handle->value[i]->parcelable, handle->value[i]);
+    </IS_PARCELABLE_TYPE?>
   }
 
-  rpc_port_parcel_write(parcel, &map->parcelable, map);
-  rpc_port_unit_map_destroy(map);
   set_last_result(RPC_PORT_ERROR_NONE);
 }
 
 static void __<PREFIX>_<NAME>_from(rpc_port_parcel_h parcel, void *data)
 {
   <PREFIX>_<NAME>_t *handle = data;
-  rpc_port_unit_map_h map;
-  char index[12];
   int i;
 
   if (parcel == nullptr || handle == nullptr) {
@@ -90,29 +80,23 @@ static void __<PREFIX>_<NAME>_from(rpc_port_parcel_h parcel, void *data)
     return;
   }
 
-  map = rpc_port_unit_map_create();
-  if (map == nullptr) {
-    set_last_result(RPC_PORT_ERROR_OUT_OF_MEMORY);
-    return;
-  }
-
-  rpc_port_parcel_read(parcel, &map->parcelable, map);
-  rpc_port_unit_map_read_int(map, "size", &handle->size);
-
+  rpc_port_parcel_read_array_count(parcel, &handle->size);
   handle->value = calloc(handle->size, sizeof(<ELEMENT_TYPE_SIZE>));
   if (handle->value == nullptr) {
     _E("Out of memory");
-    rpc_port_unit_map_destroy(map);
     set_last_result(RPC_PORT_ERROR_OUT_OF_MEMORY);
     return;
   }
 
   for (i = 0; i < handle->size; ++i) {
-    snprintf(index, sizeof(index), "%d", i);
-    <UNIT_MAP_READ>
+    <IS_DEFAULT_TYPE?>
+    rpc_port_parcel_read_<PARCEL_TYPE>(parcel, &handle->value[i]);
+    </IS_DEFAULT_TYPE?>
+    <IS_PARCELABLE_TYPE?>
+    rpc_port_parcel_read(parcel, &handle->value[i]->parcelable, handle->value[i]);
+    </IS_PARCELABLE_TYPE?>
   }
 
-  rpc_port_unit_map_destroy(map);
   set_last_result(RPC_PORT_ERROR_NONE);
 }
 
@@ -157,32 +141,42 @@ int <PREFIX>_<NAME>_destroy(<PREFIX>_<NAME>_h h)
 
 int <PREFIX>_<NAME>_clone(<PREFIX>_<NAME>_h h, <PREFIX>_<NAME>_h *clone)
 {
-  <PREFIX>_<NAME>_t *handle = h;
-  rpc_port_unit_map_h map;
+  <PREFIX>_<NAME>_h handle;
+  rpc_port_parcel_h parcel;
   int ret;
 
-  if (handle == nullptr || clone == nullptr) {
+  if (h == nullptr || clone == nullptr) {
     _E("Invalid parameter");
     return RPC_PORT_ERROR_INVALID_PARAMETER;
   }
 
-  map = rpc_port_unit_map_create();
-  if (map == nullptr) {
-    _E("Failed to create unit map");
-    return RPC_PORT_ERROR_OUT_OF_MEMORY;
+  ret = <PREFIX>_<NAME>_create(&handle);
+  if (ret != RPC_PORT_ERROR_NONE) {
+    _E("Failed to create handle. error(%d)", ret);
+    return ret;
   }
 
-  ret = rpc_port_unit_map_write_<NAME>(map, "clone", handle);
+  ret = rpc_port_parcel_create(&parcel);
   if (ret != RPC_PORT_ERROR_NONE) {
-    _E("Failed to write <NAME>. error(%d)", ret);
-    rpc_port_unit_map_destroy(map);
+    _E("Failed to create parcel handle. error(%d)", ret);
+    <PREFIX>_<NAME>_destroy(handle);
     return ret;
   }
 
-  rpc_port_unit_map_read_<NAME>(map, "clone", clone);
-  rpc_port_unit_map_destroy(map);
+  rpc_port_parcel_write(parcel, &h->parcelable, h);
+  rpc_port_parcel_read(parcel, &handle->parcelable, handle);
+  ret = get_last_result();
+  rpc_port_parcel_destroy(parcel);
 
-  return ret;
+  if (ret != RPC_PORT_ERROR_NONE) {
+    _E("Failed to read data. error(%d)", ret);
+    <PREFIX>_<NAME>_destroy(handle);
+    return ret;
+  }
+
+  *clone = handle;
+
+  return RPC_PORT_ERROR_NONE;
 }
 
 int <PREFIX>_<NAME>_set(<PREFIX>_<NAME>_h h, <PARAM_TYPE_IN>*value, int size)
@@ -262,22 +256,22 @@ int <PREFIX>_<NAME>_get(<PREFIX>_<NAME>_h h, <PARAM_TYPE_OUT>*value, int *size)
  */
 constexpr const char CB_STRUCTURE_ARRAY_USER_DEFINED_UNIT_MAP_WRITE[] =
 R"__c_cb(
-rpc_port_unit_map_write_<TYPE_NAME>(map, index, handle->value[i]);
+rpc_port_parcel_write(parcel, &handle->value[i]->parcelable, handle->value[i]);
 )__c_cb";
 
 constexpr const char CB_STRUCTURE_ARRAY_ENUM_UNIT_MAP_WRITE[] =
 R"__c_cb(
-rpc_port_unit_map_write_int(map, index, (int)handle->value[i]);
+rpc_port_parcel_write_i32(parcel, (int)handle->value[i]);
 )__c_cb";
 
 constexpr const char CB_STRUCTURE_ARRAY_BUNDLE_UNIT_MAP_WRITE[] =
 R"__c_cb(
-rpc_port_unit_map_write_bundle(map, index, handle->value[i]);
+rpc_port_parcel_write_bundle(parcel, handle->value[i]);
 )__c_cb";
 
 constexpr const char CB_STRUCTURE_ARRAY_STRING_UNIT_MAP_WRITE[] =
 R"__c_cb(
-rpc_port_unit_map_write_string(map, index, STRING_GET(handle->value[i]));
+rpc_port_parcel_write_string(parcel, STRING_GET(handle->value[i]));
 )__c_cb";
 
 /**
@@ -285,7 +279,7 @@ rpc_port_unit_map_write_string(map, index, STRING_GET(handle->value[i]));
  */
 constexpr const char CB_STRUCTURE_ARRAY_BASE_UNIT_MAP_WRITE[] =
 R"__c_cb(
-rpc_port_unit_map_write_<TYPE_NAME>(map, index, handle->value[i]);
+rpc_port_parcel_write_<PARCEL_TYPE>(parcel, handle->value[i]);
 )__c_cb";
 
 /**
@@ -293,22 +287,53 @@ rpc_port_unit_map_write_<TYPE_NAME>(map, index, handle->value[i]);
  */
 constexpr const char CB_STRUCTURE_ARRAY_USER_DEFINED_UNIT_MAP_READ[] =
 R"__c_cb(
-rpc_port_unit_map_read_<TYPE_NAME>(map, index, &handle->value[i]);
+ret = <PREFIX>_<NAME>_create(&value);
+if (ret != RPC_PORT_ERROR_NONE) {
+  _E("Failed to create handle. error(%d)", ret);
+  set_last_result(ret);
+  return;
+}
+
+rpc_port_parcel_read(parcel, &value->parcelable, value);
+if (get_last_result() != RPC_PORT_ERROR_NONE) {
+  _E("Failed to read data. error(%d)", get_last_result());
+  <PREFIX>_<NAME>_destroy(value);
+  return;
+}
+
+handle->value[i] = value;
 )__c_cb";
 
 constexpr const char CB_STRUCTURE_ARRAY_ENUM_UNIT_MAP_READ[] =
 R"__c_cb(
-rpc_port_unit_map_read_int(map, index, (int *)&handle->value[i]);
+rpc_port_parcel_read_i32(parcel, (int *)&handle->value[i]);
 )__c_cb";
 
 constexpr const char CB_STRUCTURE_ARRAY_BUNDLE_UNIT_MAP_READ[] =
 R"__c_cb(
-rpc_port_unit_map_read_bundle(map, index, &handle->value[i]);
+value = nullptr;
+rpc_port_parcel_read_bundle(parcel, &value);
+if (value == nullptr) {
+  _E("Failed to read data");
+  set_last_result(RPC_PORT_ERROR_OUT_OF_MEMORY);
+  return;
+}
+
+handle->value[i] = value;
+
 )__c_cb";
 
 constexpr const char CB_STRUCTURE_ARRAY_STRING_UNIT_MAP_READ[] =
 R"__c_cb(
-rpc_port_unit_map_read_string(map, index, &handle->value[i]);
+value = nullptr;
+rpc_port_parcel_read_string(parcel, &value);
+if (value == nullptr) {
+  _E("Failed to read data");
+  set_last_result(RPC_PORT_ERROR_OUT_OF_MEMORY);
+  return;
+}
+
+handle->value[i] = value;
 )__c_cb";
 
 /**
@@ -316,7 +341,8 @@ rpc_port_unit_map_read_string(map, index, &handle->value[i]);
  */
 constexpr const char CB_STRUCTURE_ARRAY_BASE_UNIT_MAP_READ[] =
 R"__c_cb(
-rpc_port_unit_map_read_<TYPE_NAME>(map, index, &handle->value[i]);
+rpc_port_parcel_read_<PARCEL_TYPE>(parcel, &value);
+handle->value[i] = value;
 )__c_cb";
 
 /**
index 2d6fe7c6266c4a12d70acde3c635555543e64c53..794b5e91b7381b00b77bef6497e2a14d93ff3f36 100644 (file)
@@ -33,13 +33,20 @@ namespace {
 constexpr const char PREFIX_RPC_PORT_PROXY[] = "rpc_port_proxy";
 constexpr const char PREFIX_RPC_PORT_STUB[] = "rpc_port_stub";
 
+bool IsDefaultType(const BaseType* type) {
+  if (!type) return true;
+
+  if (type->GetUserDefinedType() == BaseType::UserType::ENUM) return true;
+
+  return !type->IsUserDefinedType() && type->GetMetaType() == nullptr &&
+         type->GetKeyType() == nullptr;
+}
+
 bool IsPtrType(const BaseType& type) {
   if (type.GetUserDefinedType() == BaseType::UserType::STRUCTURE ||
       type.GetUserDefinedType() == BaseType::UserType::DELEGATE ||
-      type.GetMetaType() != nullptr ||
-      type.GetKeyType() != nullptr ||
-      type.ToString() == "string" ||
-      type.ToString() == "bundle" ||
+      type.GetMetaType() != nullptr || type.GetKeyType() != nullptr ||
+      type.ToString() == "string" || type.ToString() == "bundle" ||
       type.ToString() == "file")
     return true;
 
@@ -54,21 +61,18 @@ std::string GetBaseTypeName(const std::shared_ptr<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;
 }
@@ -91,8 +95,7 @@ CBodyGeneratorBase::CBodyGeneratorBase(std::shared_ptr<Document> doc)
         break;
       }
     }
-    if (has_delegate_)
-      break;
+    if (has_delegate_) break;
   }
 }
 
@@ -107,89 +110,93 @@ void CBodyGeneratorBase::AddTypeName(const Structure& st) {
   struct_types_[std::move(name)] = std::move(type_name);
 }
 
-void CBodyGeneratorBase::GenIncludeLemHeaders(std::ofstream& stream) {
-  stream << SmartIndent(CB_LEM_HEADER);
+std::string CBodyGeneratorBase::GetRpcPortInternalAPIs() {
+  return CB_RPC_PORT_INTERNAL_APIS;
 }
 
-void CBodyGeneratorBase::GenStructureDefinition(std::ofstream& stream) {
+std::string CBodyGeneratorBase::GetStructureDefinition() {
+  std::string ret;
+
   for (auto& b : GetDocument().GetBlocks()) {
     if (b->GetType() == Block::TYPE_STRUCTURE) {
       auto& st = static_cast<const Structure&>(*b);
-      GenStructureBaseDefinition(stream, st);
+      ret += GetStructureBaseDefinition(st);
     }
   }
 
   for (auto& i : GetStructures()) {
     auto& st = *i.second;
     if (st.GetID().compare(0, strlen("array"), "array") == 0)
-      GenStructureArrayBaseDefinition(stream, st);
+      ret += GetStructureArrayBaseDefinition(st);
     else if (st.GetID().compare(0, strlen("list"), "list") == 0)
-      GenStructureListBaseDefinition(stream, st);
+      ret += GetStructureListBaseDefinition(st);
     else if (st.GetID().compare(0, strlen("map"), "map") == 0)
-      GenStructureMapBaseDefinition(stream, st);
+      ret += GetStructureMapBaseDefinition(st);
     else if (st.GetID().compare(0, strlen("set"), "set") == 0)
-      GenStructureSetBaseDefinition(stream, st);
+      ret += GetStructureSetBaseDefinition(st);
     else
-      GenStructureBaseDefinition(stream, st);
+      ret += GetStructureBaseDefinition(st);
   }
-}
 
-bool CBodyGeneratorBase::HasDelegate() {
-  return has_delegate_;
+  return ret;
 }
 
+bool CBodyGeneratorBase::HasDelegate() { return has_delegate_; }
+
 std::string CBodyGeneratorBase::GetHandlePrefixReverse() {
-  std::string prefix =
-      IsProxy() ? PREFIX_RPC_PORT_STUB : PREFIX_RPC_PORT_PROXY;
-  if (!HasNamespace())
-    return prefix;
+  std::string prefix = IsProxy() ? PREFIX_RPC_PORT_STUB : PREFIX_RPC_PORT_PROXY;
+  if (!HasNamespace()) return prefix;
 
   return prefix + "_" + GetFileNamespace();
 }
 
-void CBodyGeneratorBase::GenStructureArrayBaseDefinition(std::ofstream& stream,
+std::string CBodyGeneratorBase::GetStructureArrayBaseDefinition(
     const Structure& st) {
   auto& elm = *(st.GetElements().begin());
   auto& type = elm->GetType();
-  std::string element_type  = GetDataTypeString(type, false);
+  std::string element_type = GetDataTypeString(type, false);
 
-  ReplaceAll(CB_STRUCTURE_ARRAY_DEF)
-      .Change("<PREFIX>", GetHandlePrefix())
-      .Change("<NAME>", st.GetID())
-      .Change("<ELEMENT_TYPE>", element_type)
+  return ReplaceAll(CB_STRUCTURE_ARRAY_DEF)
+      .Replace("PREFIX", GetHandlePrefix())
+      .Replace("NAME", st.GetID())
+      .Replace("ELEMENT_TYPE", element_type)
+      .Replace("HASH_CLONE", "clone"_hash)
       .Transform([&](std::string code) { return SmartIndent(code); })
-      .Out(stream);
+      .ToString();
 }
 
-void CBodyGeneratorBase::GenStructureListBaseDefinition(std::ofstream& stream,
+std::string CBodyGeneratorBase::GetStructureListBaseDefinition(
     const Structure& st) {
-  ReplaceAll(CB_STRUCTURE_LIST_DEF)
-      .Change("<PREFIX>", GetHandlePrefix())
-      .Change("<NAME>", st.GetID())
+  return ReplaceAll(CB_STRUCTURE_LIST_DEF)
+      .Replace("PREFIX", GetHandlePrefix())
+      .Replace("NAME", st.GetID())
+      .Replace("HASH_CLONE", "clone"_hash)
       .Transform([&](std::string code) { return SmartIndent(code); })
-      .Out(stream);
+      .ToString();
 }
 
-void CBodyGeneratorBase::GenStructureMapBaseDefinition(std::ofstream& stream,
+std::string CBodyGeneratorBase::GetStructureMapBaseDefinition(
     const Structure& st) {
-  ReplaceAll(CB_STRUCTURE_MAP_DEF)
-      .Change("<PREFIX>", GetHandlePrefix())
-      .Change("<NAME>", st.GetID())
+  return ReplaceAll(CB_STRUCTURE_MAP_DEF)
+      .Replace("PREFIX", GetHandlePrefix())
+      .Replace("NAME", st.GetID())
+      .Replace("HASH_CLONE", "clone"_hash)
       .Transform([&](std::string code) { return SmartIndent(code); })
-      .Out(stream);
+      .ToString();
 }
 
-void CBodyGeneratorBase::GenStructureSetBaseDefinition(std::ofstream& stream,
+std::string CBodyGeneratorBase::GetStructureSetBaseDefinition(
     const Structure& st) {
-  ReplaceAll(CB_STRUCTURE_SET_DEF)
-      .Change("<PREFIX>", GetHandlePrefix())
-      .Change("<NAME>", st.GetID())
+  return ReplaceAll(CB_STRUCTURE_SET_DEF)
+      .Replace("PREFIX", GetHandlePrefix())
+      .Replace("NAME", st.GetID())
+      .Replace("HASH_CLONE", "clone"_hash)
       .Transform([&](std::string code) { return SmartIndent(code); })
-      .Out(stream);
+      .ToString();
 }
 
 std::string CBodyGeneratorBase::GenBaseElements(const Elements& elms,
-    const std::string& id) {
+                                                const std::string& id) {
   std::string code;
   for (const auto& elm : elms) {
     auto& type = elm->GetType();
@@ -201,85 +208,42 @@ std::string CBodyGeneratorBase::GenBaseElements(const Elements& elms,
   return code;
 }
 
-void CBodyGeneratorBase::GenStructureBaseDefinition(std::ofstream& stream,
+std::string CBodyGeneratorBase::GetStructureBaseDefinition(
     const Structure& st) {
   auto elms = GetElements(st);
-  ReplaceAll(CB_STRUCTURE_BASE_DEF, {
-      { "<PREFIX>", GetHandlePrefix() },
-      { "<NAME>", st.GetID() },
-      { "<ELEMENTS>", GenBaseElements(elms, st.GetID()) }
-  })
-  .Transform([&](std::string str) {
-      return SmartIndent(str);
-  })
-  .Out(stream);
-}
-
-void CBodyGeneratorBase::GenStructure(std::ofstream& stream) {
+  return ReplaceAll(CB_STRUCTURE_BASE_DEF)
+      .Replace("PREFIX", GetHandlePrefix())
+      .Replace("NAME", st.GetID())
+      .Replace("ELEMENTS", GenBaseElements(elms, st.GetID()))
+      .Transform([&](std::string str) { return SmartIndent(str); })
+      .ToString();
+}
+
+std::string CBodyGeneratorBase::GetStructure() {
+  std::string ret;
+
   for (auto& b : GetDocument().GetBlocks()) {
     if (b->GetType() == Block::TYPE_STRUCTURE) {
       auto& st = static_cast<const Structure&>(*b);
-      GenStructureBase(stream, st);
+      ret += GetStructureBase(st);
     }
   }
 
   for (auto& i : GetStructures()) {
     auto& st = *i.second;
     if (st.GetID().compare(0, strlen("array"), "array") == 0)
-      GenStructureArrayBase(stream, st);
+      ret += GetStructureArrayBase(st);
     else if (st.GetID().compare(0, strlen("list"), "list") == 0)
-      GenStructureListBase(stream, st);
+      ret += GetStructureListBase(st);
     else if (st.GetID().compare(0, strlen("map"), "map") == 0)
-      GenStructureMapBase(stream, st);
+      ret += GetStructureMapBase(st);
     else if (st.GetID().compare(0, strlen("set"), "set") == 0)
-      GenStructureSetBase(stream, st);
+      ret += GetStructureSetBase(st);
     else
-      GenStructureBase(stream, st);
-  }
-}
-
-std::string CBodyGeneratorBase::GenArrayUnitMapWrite(
-    const std::shared_ptr<Element>& elm) {
-  std::string code;
-  auto& type = elm->GetType();
-  if (type.GetUserDefinedType() == BaseType::UserType::ENUM) {
-    code = CB_STRUCTURE_ARRAY_ENUM_UNIT_MAP_WRITE;
-  } else if (type.IsUserDefinedType() || type.GetMetaType() != nullptr ||
-      type.GetKeyType() != nullptr) {
-    code = ReplaceAll(CB_STRUCTURE_ARRAY_USER_DEFINED_UNIT_MAP_WRITE)
-        .Change("<TYPE_NAME>", GetFullNameFromType(type));
-  } else if (type.ToString() == "bundle") {
-    code = std::string(CB_STRUCTURE_ARRAY_BUNDLE_UNIT_MAP_WRITE);
-  } else if (type.ToString() == "string" || type.ToString() == "file") {
-    code = std::string(CB_STRUCTURE_ARRAY_STRING_UNIT_MAP_WRITE);
-  } else {
-    code = ReplaceAll(CB_STRUCTURE_ARRAY_BASE_UNIT_MAP_WRITE)
-        .Change("<TYPE_NAME>", GetFullNameFromType(type));
+      ret += GetStructureBase(st);
   }
 
-  return RemoveLine(code);
-}
-
-std::string CBodyGeneratorBase::GenArrayUnitMapRead(
-    const std::shared_ptr<Element>& elm) {
-  std::string code;
-  auto& type = elm->GetType();
-  if (type.GetUserDefinedType() == BaseType::UserType::ENUM) {
-    code = CB_STRUCTURE_ARRAY_ENUM_UNIT_MAP_READ;
-  } else if (type.IsUserDefinedType() || type.GetMetaType() != nullptr ||
-      type.GetKeyType() != nullptr) {
-    code = ReplaceAll(CB_STRUCTURE_ARRAY_USER_DEFINED_UNIT_MAP_READ)
-        .Change("<TYPE_NAME>", GetFullNameFromType(type));
-  } else if (type.ToString() == "bundle") {
-    code = std::string(CB_STRUCTURE_ARRAY_BUNDLE_UNIT_MAP_READ);
-  } else if (type.ToString() == "string" || type.ToString() == "file") {
-    code = std::string(CB_STRUCTURE_ARRAY_STRING_UNIT_MAP_READ);
-  } else {
-    code = ReplaceAll(CB_STRUCTURE_ARRAY_BASE_UNIT_MAP_READ)
-        .Change("<TYPE_NAME>", GetFullNameFromType(type));
-  }
-
-  return RemoveLine(code);
+  return ret;
 }
 
 std::string CBodyGeneratorBase::GenArrayElementsFree(
@@ -289,10 +253,10 @@ std::string CBodyGeneratorBase::GenArrayElementsFree(
   if (type.GetUserDefinedType() == BaseType::UserType::ENUM) {
     code = CB_STRUCTURE_ARRAY_BASE_FREE;
   } else if (type.IsUserDefinedType() || type.GetMetaType() != nullptr ||
-      type.GetKeyType() != nullptr) {
+             type.GetKeyType() != nullptr) {
     code = ReplaceAll(CB_STRUCTURE_ARRAY_USER_DEFINED_FREE)
-        .Change("<PREFIX>", GetHandlePrefix())
-        .Change("<NAME>", GetFullNameFromType(type));
+               .Change("<PREFIX>", GetHandlePrefix())
+               .Change("<NAME>", GetFullNameFromType(type));
   } else if (type.ToString() == "bundle") {
     code = std::string(CB_STRUCTURE_ARRAY_BUNDLE_FREE);
   } else if (type.ToString() == "string" || type.ToString() == "file") {
@@ -304,30 +268,31 @@ std::string CBodyGeneratorBase::GenArrayElementsFree(
   return RemoveLine(code);
 }
 
-void CBodyGeneratorBase::GenStructureArrayBase(std::ofstream& stream,
-    const Structure& st) {
+std::string CBodyGeneratorBase::GetStructureArrayBase(const Structure& st) {
   auto& elm = *(st.GetElements().begin());
   auto& type = elm->GetType();
 
   auto element_type = GetDataTypeString(type, false);
-  auto param_type_in  = GetParamTypeString(ParameterType::Direction::IN, type);
+  auto param_type_in = GetParamTypeString(ParameterType::Direction::IN, type);
   auto param_type_out = GetParamTypeString(ParameterType::Direction::OUT, type);
   auto element_type_size = element_type;
 
   element_type_size = RemoveLastSpaces(element_type_size);
-
-  ReplaceAll(CB_STRUCTURE_ARRAY_BASE)
-      .Change("<PREFIX>", GetHandlePrefix())
-      .Change("<NAME>", st.GetID())
-      .Change("<UNIT_MAP_WRITE>", GenArrayUnitMapWrite(elm))
-      .Change("<UNIT_MAP_READ>", GenArrayUnitMapRead(elm))
-      .Change("<PARAM_TYPE_IN>", param_type_in)
-      .Change("<PARAM_TYPE_OUT>", param_type_out)
-      .Change("<ELEMENT_TYPE>", element_type)
-      .Change("<ELEMENT_TYPE_SIZE>", element_type_size)
-      .Change("<ELEMENTS_FREE>", GenArrayElementsFree(elm))
+  bool is_default_type = IsDefaultType(&type);
+
+  return ReplaceAll(CB_STRUCTURE_ARRAY_BASE)
+      .RemoveAll("IS_DEFAULT_TYPE", !is_default_type)
+      .RemoveAll("IS_PARCELABLE_TYPE", is_default_type)
+      .Replace("PREFIX", GetHandlePrefix())
+      .Replace("NAME", st.GetID())
+      .Replace("PARCEL_TYPE", GetParcelType(type))
+      .Replace("PARAM_TYPE_IN", param_type_in)
+      .Replace("PARAM_TYPE_OUT", param_type_out)
+      .Replace("ELEMENT_TYPE", element_type)
+      .Replace("ELEMENT_TYPE_SIZE", element_type_size)
+      .Replace("ELEMENTS_FREE", GenArrayElementsFree(elm))
       .Transform([&](std::string code) { return SmartIndent(code); })
-      .Out(stream);
+      .ToString();
 }
 
 std::string CBodyGeneratorBase::GenListDataFree(
@@ -337,10 +302,10 @@ std::string CBodyGeneratorBase::GenListDataFree(
   if (type.GetUserDefinedType() == BaseType::UserType::ENUM) {
     code = CB_STRUCTURE_LIST_BASE_FREE;
   } else if (type.IsUserDefinedType() || type.GetMetaType() != nullptr ||
-      type.GetKeyType() != nullptr) {
+             type.GetKeyType() != nullptr) {
     code = ReplaceAll(CB_STRUCTURE_LIST_USER_DEFINED_FREE)
-        .Change("<PREFIX>", GetHandlePrefix())
-        .Change("<NAME>", GetFullNameFromType(type));
+               .Change("<PREFIX>", GetHandlePrefix())
+               .Change("<NAME>", GetFullNameFromType(type));
   } else if (type.ToString() == "bundle") {
     code = std::string(CB_STRUCTURE_LIST_BUNDLE_FREE);
   } else if (type.ToString() == "string" || type.ToString() == "file") {
@@ -359,16 +324,15 @@ std::string CBodyGeneratorBase::GenListUnitMapWrite(
   if (type.GetUserDefinedType() == BaseType::UserType::ENUM) {
     code = CB_STRUCTURE_LIST_ENUM_UNIT_MAP_WRITE;
   } else if (type.IsUserDefinedType() || type.GetMetaType() != nullptr ||
-      type.GetKeyType() != nullptr) {
-    code = ReplaceAll(CB_STRUCTURE_LIST_USER_DEFINED_UNIT_MAP_WRITE)
-        .Change("<TYPE_NAME>", GetFullNameFromType(type));
+             type.GetKeyType() != nullptr) {
+    code = CB_STRUCTURE_LIST_USER_DEFINED_UNIT_MAP_WRITE;
   } else if (type.ToString() == "bundle") {
-    code = std::string(CB_STRUCTURE_LIST_BUNDLE_UNIT_MAP_WRITE);
+    code = CB_STRUCTURE_LIST_BUNDLE_UNIT_MAP_WRITE;
   } else if (type.ToString() == "string" || type.ToString() == "file") {
-    code = std::string(CB_STRUCTURE_LIST_STRING_UNIT_MAP_WRITE);
+    code = CB_STRUCTURE_LIST_STRING_UNIT_MAP_WRITE;
   } else {
     code = ReplaceAll(CB_STRUCTURE_LIST_BASE_UNIT_MAP_WRITE)
-        .Change("<TYPE_NAME>", GetFullNameFromType(type));
+               .Replace("PARCEL_TYPE", GetParcelType(type));
   }
 
   return RemoveLine(code);
@@ -379,25 +343,21 @@ std::string CBodyGeneratorBase::GenListUnitMapRead(
   std::string code;
   auto& type = elm->GetType();
   if (type.GetUserDefinedType() == BaseType::UserType::ENUM) {
-    code = ReplaceAll(CB_STRUCTURE_LIST_ENUM_UNIT_MAP_READ)
-        .Change("<VALUE_TYPE>",
-            RemoveLastSpaces(
-              GetParamTypeString(ParameterType::Direction::IN, type,
-                  GetEnumBockString(type.ToString()))));
+    code = CB_STRUCTURE_LIST_ENUM_UNIT_MAP_READ;
   } else if (type.IsUserDefinedType() || type.GetMetaType() != nullptr ||
-      type.GetKeyType() != nullptr) {
+             type.GetKeyType() != nullptr) {
     code = ReplaceAll(CB_STRUCTURE_LIST_USER_DEFINED_UNIT_MAP_READ)
-        .Change("<TYPE_NAME>", GetFullNameFromType(type));
+               .Replace("PREFIX", GetHandlePrefix())
+               .Replace("NAME", GetFullNameFromType(type));
   } else if (type.ToString() == "bundle") {
-    code = std::string(CB_STRUCTURE_LIST_BUNDLE_UNIT_MAP_READ);
+    code = CB_STRUCTURE_LIST_BUNDLE_UNIT_MAP_READ;
   } else if (type.ToString() == "string" || type.ToString() == "file") {
-    code = std::string(CB_STRUCTURE_LIST_STRING_UNIT_MAP_READ);
+    code = CB_STRUCTURE_LIST_STRING_UNIT_MAP_READ;
   } else {
     code = ReplaceAll(CB_STRUCTURE_LIST_BASE_UNIT_MAP_READ)
-        .Change("<VALUE_TYPE>",
-            RemoveLastSpaces(
-              GetParamTypeString(ParameterType::Direction::IN, type)))
-        .Change("<TYPE_NAME>", GetFullNameFromType(type));
+               .Replace("VALUE_TYPE", RemoveLastSpaces(GetParamTypeString(
+                                          ParameterType::Direction::IN, type)))
+               .Replace("PARCEL_TYPE", GetParcelType(type));
   }
 
   return RemoveLine(code);
@@ -408,24 +368,24 @@ std::string CBodyGeneratorBase::GenListAdd(
   std::string code;
   auto& type = elm->GetType();
   if (type.GetUserDefinedType() == BaseType::UserType::ENUM) {
-    code = ReplaceAll(CB_STRUCTURE_LIST_ENUM_ADD)
-        .Change("<VALUE_TYPE>",
-            RemoveLastSpaces(
-              GetParamTypeString(ParameterType::Direction::IN, type,
-                  GetEnumBockString(type.ToString()))));
+    code =
+        ReplaceAll(CB_STRUCTURE_LIST_ENUM_ADD)
+            .Change("<VALUE_TYPE>", RemoveLastSpaces(GetParamTypeString(
+                                        ParameterType::Direction::IN, type,
+                                        GetEnumBockString(type.ToString()))));
   } else if (type.IsUserDefinedType() || type.GetMetaType() != nullptr ||
-      type.GetKeyType() != nullptr) {
+             type.GetKeyType() != nullptr) {
     code = ReplaceAll(CB_STRUCTURE_LIST_USER_DEFINED_ADD)
-        .Change("<PREFIX>", GetHandlePrefix())
-        .Change("<NAME>", GetFullNameFromType(type));
+               .Change("<PREFIX>", GetHandlePrefix())
+               .Change("<NAME>", GetFullNameFromType(type));
   } else if (type.ToString() == "bundle") {
     code = std::string(CB_STRUCTURE_LIST_BUNDLE_ADD);
   } else if (type.ToString() == "string" || type.ToString() == "file") {
     code = std::string(CB_STRUCTURE_LIST_STRING_ADD);
   } else {
     code = ReplaceAll(CB_STRUCTURE_LIST_BASE_ADD)
-        .Change("<VALUE_TYPE>",
-            GetParamTypeString(ParameterType::Direction::IN, type));
+               .Change("<VALUE_TYPE>",
+                       GetParamTypeString(ParameterType::Direction::IN, type));
   }
 
   return RemoveLine(code);
@@ -443,25 +403,44 @@ std::string CBodyGeneratorBase::GenListCallbackParamType(
   return code;
 }
 
-void CBodyGeneratorBase::GenStructureListBase(std::ofstream& stream,
-    const Structure& st) {
+std::string CBodyGeneratorBase::GetStructureListBase(const Structure& st) {
   auto& elm = *(st.GetElements().begin());
   auto& type = elm->GetType();
   auto data_type = GetDataTypeString(type, true);
   auto param_type = GetParamTypeString(ParameterType::Direction::IN, type);
-
-  ReplaceAll(CB_STRUCTURE_LIST_BASE)
-      .Change("<PREFIX>", GetHandlePrefix())
-      .Change("<NAME>", st.GetID())
-      .Change("<DATA_TYPE>", data_type)
-      .Change("<DATA_FREE>", GenListDataFree(elm))
-      .Change("<PARAM_TYPE_IN>", param_type)
-      .Change("<UNIT_MAP_WRITE>", GenListUnitMapWrite(elm))
-      .Change("<UNIT_MAP_READ>", GenListUnitMapRead(elm))
-      .Change("<LIST_ADD>", GenListAdd(elm))
-      .Change("<CALLBACK_PARAM_TYPE>", GenListCallbackParamType(elm))
+  bool is_bundle_type = false;
+  bool is_string_type = false;
+  bool is_default_type = false;
+  bool is_parcelable_type = false;
+  bool is_enum = false;
+
+  if (type.ToString() == "bundle")
+    is_bundle_type = true;
+  else if (type.ToString() == "string" || type.ToString() == "file")
+    is_string_type = true;
+  else if (IsDefaultType(&type))
+    is_default_type = true;
+  else
+    is_parcelable_type = true;
+  is_enum = type.IsEnumType();
+
+  return ReplaceAll(CB_STRUCTURE_LIST_BASE)
+      .RemoveAll("IS_BUNDLE_TYPE", !is_bundle_type)
+      .RemoveAll("IS_STRING_TYPE", !is_string_type)
+      .RemoveAll("IS_DEFAULT_TYPE", !is_default_type)
+      .RemoveAll("IS_PARCELABLE_TYPE", !is_parcelable_type)
+      .RemoveAll("IS_ENUM", !is_enum)
+      .Replace("PREFIX", GetHandlePrefix())
+      .Replace("NAME", st.GetID())
+      .Replace("PARCEL_TYPE", GetParcelType(type))
+      .Replace("DATA_TYPE", data_type)
+      .Replace("DATA_TYPE_WITHOUT_POINTER", GetDataTypeString(type, false))
+      .Replace("DATA_FREE", GenListDataFree(elm))
+      .Replace("PARAM_TYPE_IN", param_type)
+      .Replace("LIST_ADD", GenListAdd(elm))
+      .Replace("CALLBACK_PARAM_TYPE", GenListCallbackParamType(elm))
       .Transform([&](std::string code) { return SmartIndent(code); })
-      .Out(stream);
+      .ToString();
 }
 
 std::string CBodyGeneratorBase::GenMapContains(const BaseType& key_type) {
@@ -500,10 +479,10 @@ std::string CBodyGeneratorBase::GenMapForeachVarsDefinition(
     code = CB_MAP_FOREACH_VARS_DEF_KEY_BASE_VALUE_BASE_TYPE;
 
   code = ReplaceAll(code)
-      .Change("<KEY_TYPE>",
-          RemoveLastSpaces(GetDataTypeString(key_type, false)))
-      .Change("<VALUE_TYPE>",
-          RemoveLastSpaces(GetDataTypeString(value_type, false)));
+             .Change("<KEY_TYPE>",
+                     RemoveLastSpaces(GetDataTypeString(key_type, false)))
+             .Change("<VALUE_TYPE>",
+                     RemoveLastSpaces(GetDataTypeString(value_type, false)));
 
   return RemoveLine(code);
 }
@@ -518,8 +497,7 @@ std::string CBodyGeneratorBase::GenMapErase(const BaseType& key_type) {
   return RemoveLine(code);
 }
 
-std::string CBodyGeneratorBase::GenMapKeyNullCheck(
-    const BaseType& key_type) {
+std::string CBodyGeneratorBase::GenMapKeyNullCheck(const BaseType& key_type) {
   std::string code;
   if (IsPtrType(key_type))
     code = CB_MAP_HANDLE_KEY_NULL_CHECK;
@@ -537,30 +515,32 @@ std::string CBodyGeneratorBase::GenMapLookupValueSet(
       value_type.GetMetaType() != nullptr ||
       value_type.GetKeyType() != nullptr) {
     code = ReplaceAll(CB_MAP_LOOKUP_VALUE_USER_DEFINED_SET)
-        .Change("<PREFIX>", GetHandlePrefix())
-        .Change("<NAME>", value_type.GetFullName(true));
+               .Change("<PREFIX>", GetHandlePrefix())
+               .Change("<NAME>", value_type.GetFullName(true));
   } else if (value_type.ToString() == "bundle") {
     code = CB_MAP_LOOKUP_VALUE_BUNDLE_SET;
   } else if (value_type.ToString() == "string") {
     code = CB_MAP_LOOKUP_VALUE_STRING_SET;
   } else {
     code = ReplaceAll(CB_MAP_LOOKUP_VALUE_BASE_SET)
-        .Change("<VALUE_TYPE>",
-            RemoveLastSpaces(GetDataTypeString(value_type, false)));
+               .Change("<VALUE_TYPE>",
+                       RemoveLastSpaces(GetDataTypeString(value_type, false)));
   }
 
   return RemoveLine(code);
 }
 
-std::string CBodyGeneratorBase::GenMapLookup(
-    const BaseType& key_type, const BaseType& value_type) {
+std::string CBodyGeneratorBase::GenMapLookup(const BaseType& key_type,
+                                             const BaseType& value_type) {
   std::string code;
   if (IsPtrType(key_type)) {
-    code = ReplaceAll(CB_MAP_LOOKUP_KEY_PTR_TYPE)
-        .Change("<MAP_LOOKUP_VALUE_SET>", GenMapLookupValueSet(value_type));
+    code =
+        ReplaceAll(CB_MAP_LOOKUP_KEY_PTR_TYPE)
+            .Change("<MAP_LOOKUP_VALUE_SET>", GenMapLookupValueSet(value_type));
   } else {
-    code = ReplaceAll(CB_MAP_LOOKUP_KEY_BASE_TYPE)
-        .Change("<MAP_LOOKUP_VALUE_SET>", GenMapLookupValueSet(value_type));
+    code =
+        ReplaceAll(CB_MAP_LOOKUP_KEY_BASE_TYPE)
+            .Change("<MAP_LOOKUP_VALUE_SET>", GenMapLookupValueSet(value_type));
   }
 
   return RemoveLine(code);
@@ -582,11 +562,10 @@ std::string CBodyGeneratorBase::GenMapInsertNewKeyFree(
   std::string code;
   if (key_type.GetUserDefinedType() == BaseType::UserType::STRUCTURE ||
       key_type.GetUserDefinedType() == BaseType::UserType::DELEGATE ||
-      key_type.GetMetaType() != nullptr ||
-      key_type.GetKeyType() != nullptr) {
+      key_type.GetMetaType() != nullptr || key_type.GetKeyType() != nullptr) {
     code = ReplaceAll(CB_MAP_INSERT_NEW_KEY_USER_DEFINED_FREE)
-        .Change("<PREFIX>", GetHandlePrefix())
-        .Change("<NAME>", key_type.GetFullName(true));
+               .Change("<PREFIX>", GetHandlePrefix())
+               .Change("<NAME>", key_type.GetFullName(true));
   } else if (key_type.ToString() == "bundle") {
     code = CB_MAP_INSERT_NEW_KEY_BUNDLE_FREE;
   } else if (key_type.ToString() == "string" || key_type.ToString() == "file") {
@@ -606,21 +585,21 @@ std::string CBodyGeneratorBase::GenMapInsertNewValueImpl(
       value_type.GetMetaType() != nullptr ||
       value_type.GetKeyType() != nullptr) {
     code = ReplaceAll(CB_MAP_INSERT_NEW_VALUE_USER_DEFINED_IMPL)
-        .Change("<PREFIX>", GetHandlePrefix())
-        .Change("<NAME>", value_type.GetFullName(true));
+               .Change("<PREFIX>", GetHandlePrefix())
+               .Change("<NAME>", value_type.GetFullName(true));
   } else if (value_type.ToString() == "bundle") {
     code = CB_MAP_INSERT_NEW_VALUE_BUNDLE_IMPL;
   } else if (value_type.ToString() == "string" ||
-      value_type.ToString() == "file") {
+             value_type.ToString() == "file") {
     code = CB_MAP_INSERT_NEW_VALUE_STRING_IMPL;
   } else {
     code = ReplaceAll(CB_MAP_INSERT_NEW_VALUE_BASE_IMPL)
-        .Change("<VALUE_TYPE>",
-            RemoveLastSpaces(GetDataTypeString(value_type, false)));
+               .Change("<VALUE_TYPE>",
+                       RemoveLastSpaces(GetDataTypeString(value_type, false)));
   }
 
-  code = ReplaceAll(code)
-      .Change("<MAP_INSERT_NEW_KEY_FREE>", GenMapInsertNewKeyFree(key_type));
+  code = ReplaceAll(code).Change("<MAP_INSERT_NEW_KEY_FREE>",
+                                 GenMapInsertNewKeyFree(key_type));
 
   return RemoveLine(code);
 }
@@ -630,31 +609,31 @@ std::string CBodyGeneratorBase::GenMapInsertNewKeyImpl(
   std::string code;
   if (key_type.GetUserDefinedType() == BaseType::UserType::STRUCTURE ||
       key_type.GetUserDefinedType() == BaseType::UserType::DELEGATE ||
-      key_type.GetMetaType() != nullptr ||
-      key_type.GetKeyType() != nullptr) {
+      key_type.GetMetaType() != nullptr || key_type.GetKeyType() != nullptr) {
     code = ReplaceAll(CB_MAP_INSERT_NEW_KEY_USER_DEFINED_IMPL)
-        .Change("<PREFIX>", GetHandlePrefix())
-        .Change("<NAME>", key_type.GetFullName(true));
+               .Change("<PREFIX>", GetHandlePrefix())
+               .Change("<NAME>", key_type.GetFullName(true));
   } else if (key_type.ToString() == "bundle") {
     code = CB_MAP_INSERT_NEW_KEY_BUNDLE_IMPL;
   } else if (key_type.ToString() == "string" || key_type.ToString() == "file") {
     code = CB_MAP_INSERT_NEW_KEY_STRING_IMPL;
   } else {
     code = ReplaceAll(CB_MAP_INSERT_NEW_KEY_BASE_IMPL)
-        .Change("<KEY_TYPE>",
-            RemoveLastSpaces(GetDataTypeString(key_type, false)));
+               .Change("<KEY_TYPE>",
+                       RemoveLastSpaces(GetDataTypeString(key_type, false)));
   }
 
   return RemoveLine(code);
 }
 
-std::string CBodyGeneratorBase::GenMapInsert(
-    const BaseType& key_type, const BaseType& value_type) {
+std::string CBodyGeneratorBase::GenMapInsert(const BaseType& key_type,
+                                             const BaseType& value_type) {
   std::string code;
-  code = ReplaceAll(CB_MAP_INSERT)
-      .Change("<MAP_INSERT_NEW_KEY_IMPL>", GenMapInsertNewKeyImpl(key_type))
-      .Change("<MAP_INSERT_NEW_VALUE_IMPL>",
-          GenMapInsertNewValueImpl(key_type, value_type));
+  code =
+      ReplaceAll(CB_MAP_INSERT)
+          .Change("<MAP_INSERT_NEW_KEY_IMPL>", GenMapInsertNewKeyImpl(key_type))
+          .Change("<MAP_INSERT_NEW_VALUE_IMPL>",
+                  GenMapInsertNewValueImpl(key_type, value_type));
   return RemoveLine(code);
 }
 
@@ -675,16 +654,14 @@ std::string CBodyGeneratorBase::GenMapKeyValueNullCheck(
   return code;
 }
 
-std::string CBodyGeneratorBase::GenMapFreeFunc(
-    const BaseType& type) {
+std::string CBodyGeneratorBase::GenMapFreeFunc(const BaseType& type) {
   std::string code;
   if (type.GetUserDefinedType() == BaseType::UserType::STRUCTURE ||
       type.GetUserDefinedType() == BaseType::UserType::DELEGATE ||
-      type.GetMetaType() != nullptr ||
-      type.GetKeyType() != nullptr) {
+      type.GetMetaType() != nullptr || type.GetKeyType() != nullptr) {
     code = ReplaceAll(CB_MAP_USER_DEFINED_FREE_FUNC)
-        .Change("<PREFIX>", GetHandlePrefix())
-        .Change("<NAME>", type.GetFullName(true));
+               .Change("<PREFIX>", GetHandlePrefix())
+               .Change("<NAME>", type.GetFullName(true));
   } else if (type.ToString() == "bundle") {
     code = CB_MAP_BUNDLE_FREE_FUNC;
   } else {
@@ -699,10 +676,12 @@ std::string CBodyGeneratorBase::GenMapCompareKeyVarsDefinition(
   std::string code;
   if (IsPtrType(type)) {
     code = ReplaceAll(CB_MAP_COMPARE_KEY_VARS_DEF_PTR_TYPE)
-        .Change("<KEY_TYPE>", RemoveLastSpaces(GetDataTypeString(type, false)));
+               .Change("<KEY_TYPE>",
+                       RemoveLastSpaces(GetDataTypeString(type, false)));
   } else {
     code = ReplaceAll(CB_MAP_COMPARE_KEY_VARS_DEF_BASE_TYPE)
-        .Change("<KEY_TYPE>", RemoveLastSpaces(GetDataTypeString(type, false)));
+               .Change("<KEY_TYPE>",
+                       RemoveLastSpaces(GetDataTypeString(type, false)));
   }
 
   return RemoveLine(code);
@@ -720,122 +699,74 @@ std::string CBodyGeneratorBase::GenMapCompareKeyVarsImpl(const BaseType& type) {
   return RemoveLine(code);
 }
 
-std::string CBodyGeneratorBase::GenMapUnitMapValueRead(
-    const BaseType& type) {
-  std::string code;
-  if (type.GetUserDefinedType() == BaseType::UserType::ENUM)
-    code = ReplaceAll(CB_MAP_UNIT_MAP_VALUE_ENUM_TYPE_READ)
-        .Change("<VALUE>", type.GetFullName(true));
-  else
-    code = ReplaceAll(CB_MAP_UNIT_MAP_VALUE_READ)
-        .Change("<VALUE>", type.GetFullName(true));
-  return RemoveLine(code);
-}
-
-std::string CBodyGeneratorBase::GenMapUnitMapKeyRead(
-    const BaseType& type) {
-  std::string code;
-  if (type.GetUserDefinedType() == BaseType::UserType::ENUM)
-    code = ReplaceAll(CB_MAP_UNIT_MAP_KEY_ENUM_TYPE_READ)
-        .Change("<KEY>", type.GetFullName(true));
-  else
-    code = ReplaceAll(CB_MAP_UNIT_MAP_KEY_READ)
-        .Change("<KEY>", type.GetFullName(true));
-  return RemoveLine(code);
-}
-
-std::string CBodyGeneratorBase::GenMapUnitMapValueWrite(
-    const BaseType& type) {
-  std::string code;
-  if (IsPtrType(type)) {
-    code = ReplaceAll(CB_MAP_UNIT_MAP_VALUE_WRITE_PTR_TYPE)
-        .Change("<VALUE>", type.GetFullName(true))
-        .Change("<VALUE_TYPE>",
-            RemoveLastSpaces(GetDataTypeString(type, false)));
-  } else if (type.GetUserDefinedType() == BaseType::UserType::ENUM) {
-       code = ReplaceAll(CB_MAP_UNIT_MAP_VALUE_WRITE_ENUM_TYPE)
-          .Change("<KEY>", type.GetFullName(true));
-  } else {
-    code = ReplaceAll(CB_MAP_UNIT_MAP_VALUE_WRITE_BASE_TYPE)
-        .Change("<VALUE>", type.GetFullName(true))
-        .Change("<VALUE_TYPE>",
-            RemoveLastSpaces(GetDataTypeString(type, false)));
-  }
-
-  return RemoveLine(code);
-}
-
-std::string CBodyGeneratorBase::GenMapUnitMapKeyWrite(
-    const BaseType& type) {
-  std::string code;
-  if (IsPtrType(type)) {
-    code = ReplaceAll(CB_MAP_UNIT_MAP_KEY_WRITE_PTR_TYPE)
-        .Change("<KEY>", type.GetFullName(true))
-        .Change("<KEY_TYPE>", RemoveLastSpaces(GetDataTypeString(type, false)));
-  } else if (type.GetUserDefinedType() == BaseType::UserType::ENUM) {
-     code = ReplaceAll(CB_MAP_UNIT_MAP_KEY_ENUM_BASE_TYPE)
-        .Change("<KEY>", type.GetFullName(true));
-  } else {
-    code = ReplaceAll(CB_MAP_UNIT_MAP_KEY_WRITE_BASE_TYPE)
-        .Change("<KEY>", type.GetFullName(true))
-        .Change("<KEY_TYPE>", RemoveLastSpaces(GetDataTypeString(type, false)));
-  }
-
-  return RemoveLine(code);
-}
-
-void CBodyGeneratorBase::GenStructureMapBase(std::ofstream& stream,
-    const Structure& st) {
+std::string CBodyGeneratorBase::GetStructureMapBase(const Structure& st) {
   auto iter = st.GetElements().begin();
-  if (std::next(iter) == st.GetElements().end())
-    return;
+  if (std::next(iter) == st.GetElements().end()) return "";
 
   auto& key_elm = *(iter);
   auto& key_type = key_elm->GetType();
-  auto key_param_type = GetParamTypeString(ParameterType::Direction::IN,
-      key_type);
+  auto key_param_type =
+      GetParamTypeString(ParameterType::Direction::IN, key_type);
   auto& value_elm = *(std::next(iter));
   auto& value_type = value_elm->GetType();
-  auto value_param_type = GetParamTypeString(ParameterType::Direction::IN,
-      value_type);
-  auto value_param_type_out = GetParamTypeString(ParameterType::Direction::OUT,
-      value_type);
-
-  ReplaceAll(CB_STRUCTURE_MAP_BASE)
-      .Change("<PREFIX>", GetHandlePrefix())
-      .Change("<NAME>", st.GetID())
-      .Change("<KEY_TYPE>", GetDataTypeString(key_type, false))
-      .Change("<VALUE_TYPE>", GetDataTypeString(value_type, false))
-      .Change("<KEY_PARAM_TYPE>", key_param_type)
-      .Change("<VALUE_PARAM_TYPE>", value_param_type)
-      .Change("<VALUE_PARAM_TYPE_OUT>", value_param_type_out)
-      .Change("<MAP_UNIT_MAP_KEY_WRITE>", GenMapUnitMapKeyWrite(key_type))
-      .Change("<MAP_UNIT_MAP_VALUE_WRITE>", GenMapUnitMapValueWrite(value_type))
-      .Change("<MAP_UNIT_MAP_KEY_READ>", GenMapUnitMapKeyRead(key_type))
-      .Change("<MAP_UNIT_MAP_VALUE_READ>", GenMapUnitMapValueRead(value_type))
-      .Change("<MAP_COMPARE_KEY_VARS_DEF>",
-          GenMapCompareKeyVarsDefinition(key_type))
-      .Change("<MAP_COMPARE_KEY_VARS_IMPL>",
-          GenMapCompareKeyVarsImpl(key_type))
-      .Change("<MAP_KEY_FREE_FUNC>", GenMapFreeFunc(key_type))
-      .Change("<MAP_VALUE_FREE_FUNC>", GenMapFreeFunc(value_type))
-      .Change("<MAP_INSERT_ARGS_NULL_CHECK>",
-          GenMapKeyValueNullCheck(key_type, value_type))
-      .Change("<MAP_INSERT>", GenMapInsert(key_type, value_type))
-      .Change("<MAP_LOOKUP_ARGS_NULL_CHECK>",
-          GenMapKeyValueNullCheck(key_type))
-      .Change("<MAP_LOOKUP>", GenMapLookup(key_type, value_type))
-      .Change("<MAP_ERASE_ARGS_NULL_CHECK>", GenMapKeyNullCheck(key_type))
-      .Change("<MAP_ERASE>", GenMapErase(key_type))
-      .Change("<MAP_REPLACE_ARGS_NULL_CHECK>",
-          GenMapKeyValueNullCheck(key_type, value_type))
-      .Change("<MAP_FOREACH_VARS_DEF>",
-          GenMapForeachVarsDefinition(key_type, value_type))
-      .Change("<MAP_CONTAINS_ARGS_NULL_CHECK>",
-          GenMapKeyExistNullCheck(key_type))
-      .Change("<MAP_CONTAINS>", GenMapContains(key_type))
+  auto value_param_type =
+      GetParamTypeString(ParameterType::Direction::IN, value_type);
+  auto value_param_type_out =
+      GetParamTypeString(ParameterType::Direction::OUT, value_type);
+
+  bool is_user_defined_type = false;
+  bool is_string_type = false;
+  bool is_enum_type = false;
+  bool is_value_type = false;
+  bool is_ptr = IsPtrType(key_type);
+
+  if (value_type.GetUserDefinedType() == BaseType::UserType::ENUM)
+    is_enum_type = true;
+  else if (value_type.ToString() == "string" || value_type.ToString() == "file")
+    is_string_type = true;
+  else if (IsDefaultType(&value_type))
+    is_value_type = true;
+  else
+    is_user_defined_type = true;
+
+  return ReplaceAll(CB_STRUCTURE_MAP_BASE)
+      .RemoveAll("IS_PTR", !is_ptr)
+      .RemoveAll("IS_NOT_PTR", is_ptr)
+      .RemoveAll("IS_USER_DEFINED_TYPE", !is_user_defined_type)
+      .RemoveAll("IS_STRING_TYPE", !is_string_type)
+      .RemoveAll("IS_ENUM_TYPE", !is_enum_type)
+      .RemoveAll("IS_VALUE_TYPE", !is_value_type)
+      .Replace("PREFIX", GetHandlePrefix())
+      .Replace("NAME", st.GetID())
+      .Replace("PARCEL_TYPE", GetParcelType(value_type))
+      .Replace("PARCEL_TYPE_KEY", GetParcelType(key_type))
+      .Replace("KEY_TYPE", GetDataTypeString(key_type, false))
+      .Replace("VALUE_TYPE", GetDataTypeString(value_type, false))
+      .Replace("KEY_PARAM_TYPE", key_param_type)
+      .Replace("VALUE_PARAM_TYPE", value_param_type)
+      .Replace("VALUE_PARAM_TYPE_OUT", value_param_type_out)
+      .Replace("MAP_COMPARE_KEY_VARS_DEF",
+               GenMapCompareKeyVarsDefinition(key_type))
+      .Replace("MAP_COMPARE_KEY_VARS_IMPL", GenMapCompareKeyVarsImpl(key_type))
+      .Replace("MAP_KEY_FREE_FUNC", GenMapFreeFunc(key_type))
+      .Replace("MAP_VALUE_FREE_FUNC", GenMapFreeFunc(value_type))
+      .Replace("MAP_INSERT_ARGS_NULL_CHECK",
+               GenMapKeyValueNullCheck(key_type, value_type))
+      .Replace("MAP_INSERT", GenMapInsert(key_type, value_type))
+      .Replace("MAP_LOOKUP_ARGS_NULL_CHECK", GenMapKeyValueNullCheck(key_type))
+      .Replace("MAP_LOOKUP", GenMapLookup(key_type, value_type))
+      .Replace("MAP_ERASE_ARGS_NULL_CHECK", GenMapKeyNullCheck(key_type))
+      .Replace("MAP_ERASE", GenMapErase(key_type))
+      .Replace("MAP_REPLACE_ARGS_NULL_CHECK",
+               GenMapKeyValueNullCheck(key_type, value_type))
+      .Replace("MAP_FOREACH_VARS_DEF",
+               GenMapForeachVarsDefinition(key_type, value_type))
+      .Replace("MAP_CONTAINS_ARGS_NULL_CHECK",
+               GenMapKeyExistNullCheck(key_type))
+      .Replace("MAP_CONTAINS", GenMapContains(key_type))
+      .Replace("HASH_CLONE", "clone"_hash)
       .Transform([&](std::string code) { return SmartIndent(code); })
-      .Out(stream);
+      .ToString();
 }
 
 std::string CBodyGeneratorBase::GenSetContains(const BaseType& type) {
@@ -848,8 +779,7 @@ std::string CBodyGeneratorBase::GenSetContains(const BaseType& type) {
   return RemoveLine(code);
 }
 
-std::string CBodyGeneratorBase::GenSetKeyExistNullCheck(
-    const BaseType& type) {
+std::string CBodyGeneratorBase::GenSetKeyExistNullCheck(const BaseType& type) {
   std::string code;
   if (IsPtrType(type))
     code = CB_SET_HANDLE_KEY_EXIST_NULL_CHECK;
@@ -864,10 +794,12 @@ std::string CBodyGeneratorBase::GenSetForeachKeyVarDefinition(
   std::string code;
   if (IsPtrType(type)) {
     code = ReplaceAll(CB_SET_FOREACH_VARS_DEF_KEY_PTR_TYPE)
-        .Change("<KEY_TYPE>", RemoveLastSpaces(GetDataTypeString(type, false)));
+               .Change("<KEY_TYPE>",
+                       RemoveLastSpaces(GetDataTypeString(type, false)));
   } else {
     code = ReplaceAll(CB_SET_FOREACH_VARS_DEF_KEY_BASE_TYPE)
-        .Change("<KEY_TYPE>", RemoveLastSpaces(GetDataTypeString(type, false)));
+               .Change("<KEY_TYPE>",
+                       RemoveLastSpaces(GetDataTypeString(type, false)));
   }
 
   return RemoveLine(code);
@@ -887,19 +819,18 @@ std::string CBodyGeneratorBase::GenSetInsert(const BaseType& type) {
   std::string code;
   if (type.GetUserDefinedType() == BaseType::UserType::STRUCTURE ||
       type.GetUserDefinedType() == BaseType::UserType::DELEGATE ||
-      type.GetMetaType() != nullptr ||
-      type.GetKeyType() != nullptr) {
+      type.GetMetaType() != nullptr || type.GetKeyType() != nullptr) {
     code = ReplaceAll(CB_SET_INSERT_KEY_USER_DEFINED_IMPL)
-        .Change("<PREFIX>", GetHandlePrefix())
-        .Change("<NAME>", type.GetFullName(true));
+               .Change("<PREFIX>", GetHandlePrefix())
+               .Change("<NAME>", type.GetFullName(true));
   } else if (type.ToString() == "bundle") {
     code = CB_SET_INSERT_KEY_BUNDLE_IMPL;
   } else if (type.ToString() == "string" || type.ToString() == "file") {
     code = CB_SET_INSERT_KEY_STRING_IMPL;
   } else {
     code = ReplaceAll(CB_SET_INSERT_KEY_BASE_IMPL)
-        .Change("<KEY_TYPE>",
-            RemoveLastSpaces(GetDataTypeString(type, false)));
+               .Change("<KEY_TYPE>",
+                       RemoveLastSpaces(GetDataTypeString(type, false)));
   }
 
   return RemoveLine(code);
@@ -919,11 +850,10 @@ std::string CBodyGeneratorBase::GenSetKeyFreeFunc(const BaseType& type) {
   std::string code;
   if (type.GetUserDefinedType() == BaseType::UserType::STRUCTURE ||
       type.GetUserDefinedType() == BaseType::UserType::DELEGATE ||
-      type.GetMetaType() != nullptr ||
-      type.GetKeyType() != nullptr) {
+      type.GetMetaType() != nullptr || type.GetKeyType() != nullptr) {
     code = ReplaceAll(CB_SET_USER_DEFINED_FREE_FUNC)
-        .Change("<PREFIX>", GetHandlePrefix())
-        .Change("<NAME>", type.GetFullName(true));
+               .Change("<PREFIX>", GetHandlePrefix())
+               .Change("<NAME>", type.GetFullName(true));
   } else if (type.ToString() == "bundle") {
     code = CB_SET_BUNDLE_FREE_FUNC;
   } else {
@@ -938,10 +868,12 @@ std::string CBodyGeneratorBase::GenSetCompareKeyVarsDefinition(
   std::string code;
   if (IsPtrType(type)) {
     code = ReplaceAll(CB_SET_COMPARE_KEY_VARS_DEF_PTR_TYPE)
-        .Change("<KEY_TYPE>", RemoveLastSpaces(GetDataTypeString(type, false)));
+               .Change("<KEY_TYPE>",
+                       RemoveLastSpaces(GetDataTypeString(type, false)));
   } else {
     code = ReplaceAll(CB_SET_COMPARE_KEY_VARS_DEF_BASE_TYPE)
-        .Change("<KEY_TYPE>", RemoveLastSpaces(GetDataTypeString(type, false)));
+               .Change("<KEY_TYPE>",
+                       RemoveLastSpaces(GetDataTypeString(type, false)));
   }
 
   return RemoveLine(code);
@@ -959,64 +891,36 @@ std::string CBodyGeneratorBase::GenSetCompareKeyVarsImpl(const BaseType& type) {
   return RemoveLine(code);
 }
 
-std::string CBodyGeneratorBase::GenSetUnitMapKeyRead(const BaseType& type) {
-  std::string code;
-
-  if (type.GetUserDefinedType() == BaseType::UserType::ENUM)
-    code = CB_SET_UNIT_MAP_KEY_ENUM_TYPE_READ;
-  else
-    code = ReplaceAll(CB_SET_UNIT_MAP_KEY_READ)
-        .Change("<KEY>", type.GetFullName(true));
-  return RemoveLine(code);
-}
-
-std::string CBodyGeneratorBase::GenSetUnitMapKeyWrite(const BaseType& type) {
-  std::string code;
-  if (IsPtrType(type)) {
-    code = ReplaceAll(CB_SET_UNIT_MAP_KEY_WRITE_PTR_TYPE)
-        .Change("<KEY>", type.GetFullName(true))
-        .Change("<KEY_TYPE>", RemoveLastSpaces(GetDataTypeString(type, false)));
-  } else if (type.GetUserDefinedType() == BaseType::UserType::ENUM) {
-       code = CB_SET_UNIT_MAP_KEY_WRITE_ENUM_TYPE;
-  } else {
-    code = ReplaceAll(CB_SET_UNIT_MAP_KEY_WRITE_BASE_TYPE)
-        .Change("<KEY>", type.GetFullName(true))
-        .Change("<KEY_TYPE>", RemoveLastSpaces(GetDataTypeString(type, false)));
-  }
-
-  return RemoveLine(code);
-}
-
-void CBodyGeneratorBase::GenStructureSetBase(std::ofstream& stream,
-    const Structure& st) {
+std::string CBodyGeneratorBase::GetStructureSetBase(const Structure& st) {
   auto& key_elm = *(st.GetElements().begin());
   auto& key_type = key_elm->GetType();
-  auto key_param_type = GetParamTypeString(ParameterType::Direction::IN,
-      key_type);
-
-  ReplaceAll(CB_STRUCTURE_SET_BASE)
-      .Change("<PREFIX>", GetHandlePrefix())
-      .Change("<NAME>", st.GetID())
-      .Change("<KEY_TYPE>", GetDataTypeString(key_type, false))
-      .Change("<KEY_PARAM_TYPE>", key_param_type)
-      .Change("<SET_UNIT_MAP_KEY_WRITE>", GenSetUnitMapKeyWrite(key_type))
-      .Change("<SET_UNIT_MAP_KEY_READ>", GenSetUnitMapKeyRead(key_type))
-      .Change("<SET_COMPARE_KEY_VARS_DEF>",
-          GenSetCompareKeyVarsDefinition(key_type))
-      .Change("<SET_COMPARE_KEY_VARS_IMPL>",
-          GenSetCompareKeyVarsImpl(key_type))
-      .Change("<SET_KEY_FREE_FUNC>", GenSetKeyFreeFunc(key_type))
-      .Change("<SET_INSERT_ARGS_NULL_CHECK>", GenSetKeyNullCheck(key_type))
-      .Change("<SET_INSERT>", GenSetInsert(key_type))
-      .Change("<SET_ERASE_ARGS_NULL_CHECK>", GenSetKeyNullCheck(key_type))
-      .Change("<SET_ERASE>", GenSetErase(key_type))
-      .Change("<SET_FOREACH_VARS_DEF>",
-          GenSetForeachKeyVarDefinition(key_type))
-      .Change("<SET_CONTAINS_ARGS_NULL_CHECK>",
-          GenSetKeyExistNullCheck(key_type))
-      .Change("<SET_CONTAINS>", GenSetContains(key_type))
+  auto key_param_type =
+      GetParamTypeString(ParameterType::Direction::IN, key_type);
+  bool is_ptr = IsPtrType(key_type);
+
+  return ReplaceAll(CB_STRUCTURE_SET_BASE)
+      .RemoveAll("IS_PTR", !is_ptr)
+      .RemoveAll("IS_NOT_PTR", is_ptr)
+      .Replace("PREFIX", GetHandlePrefix())
+      .Replace("NAME", st.GetID())
+      .Replace("PARCEL_TYPE_KEY", GetParcelType(key_type))
+      .Replace("KEY_TYPE", GetDataTypeString(key_type, false))
+      .Replace("KEY_PARAM_TYPE", key_param_type)
+      .Replace("SET_COMPARE_KEY_VARS_DEF",
+               GenSetCompareKeyVarsDefinition(key_type))
+      .Replace("SET_COMPARE_KEY_VARS_IMPL", GenSetCompareKeyVarsImpl(key_type))
+      .Replace("SET_KEY_FREE_FUNC", GenSetKeyFreeFunc(key_type))
+      .Replace("SET_INSERT_ARGS_NULL_CHECK", GenSetKeyNullCheck(key_type))
+      .Replace("SET_INSERT", GenSetInsert(key_type))
+      .Replace("SET_ERASE_ARGS_NULL_CHECK", GenSetKeyNullCheck(key_type))
+      .Replace("SET_ERASE", GenSetErase(key_type))
+      .Replace("SET_FOREACH_VARS_DEF", GenSetForeachKeyVarDefinition(key_type))
+      .Replace("SET_CONTAINS_ARGS_NULL_CHECK",
+               GenSetKeyExistNullCheck(key_type))
+      .Replace("SET_CONTAINS", GenSetContains(key_type))
+      .Replace("HASH_CLONE", "clone"_hash)
       .Transform([&](std::string code) { return SmartIndent(code); })
-      .Out(stream);
+      .ToString();
 }
 
 std::string CBodyGeneratorBase::GenBaseElementFree(
@@ -1027,15 +931,15 @@ std::string CBodyGeneratorBase::GenBaseElementFree(
       type.GetUserDefinedType() == BaseType::UserType::DELEGATE ||
       type.GetMetaType() != nullptr || type.GetKeyType() != nullptr) {
     code = ReplaceAll(CB_STRUCTURE_BASE_USER_DEFINED_FREE)
-        .Change("<PREFIX>", GetHandlePrefix())
-        .Change("<NAME>", GetFullNameFromType(type))
-        .Change("<ELEMENT_NAME>", elm->GetID());
+               .Change("<PREFIX>", GetHandlePrefix())
+               .Change("<NAME>", GetFullNameFromType(type))
+               .Change("<ELEMENT_NAME>", elm->GetID());
   } else if (type.ToString() == "bundle") {
     code = ReplaceAll(CB_STRUCTURE_BASE_BUNDLE_FREE)
-        .Change("<ELEMENT_NAME>", elm->GetID());
+               .Change("<ELEMENT_NAME>", elm->GetID());
   } else if (type.ToString() == "string" || type.ToString() == "file") {
     code = ReplaceAll(CB_STRUCTURE_BASE_STRING_FREE)
-        .Change("<ELEMENT_NAME>", elm->GetID());
+               .Change("<ELEMENT_NAME>", elm->GetID());
   }
 
   return code;
@@ -1043,8 +947,7 @@ std::string CBodyGeneratorBase::GenBaseElementFree(
 
 std::string CBodyGeneratorBase::GenBaseElementsFree(const Elements& elms) {
   std::string code;
-  for (const auto& elm : elms)
-    code += GenBaseElementFree(elm);
+  for (const auto& elm : elms) code += GenBaseElementFree(elm);
 
   return RemoveLine(code);
 }
@@ -1056,11 +959,13 @@ std::string CBodyGeneratorBase::GenBaseUnitMapWrite(const Elements& elms) {
 
     if (type.GetUserDefinedType() == BaseType::UserType::ENUM)
       code += ReplaceAll(CB_STRUCTURE_ENUM_UNIT_MAP_WRITE)
-          .Change("<ELEMENT_NAME>", elm->GetID());
+                  .Replace("ELEMENT_NAME", elm->GetID())
+                  .Replace("HASH_ELEMENT_NAME", GetHashCodeStr(elm->GetID()));
     else
       code += ReplaceAll(CB_STRUCTURE_BASE_UNIT_MAP_WRITE)
-          .Change("<ELEMENT_TYPE>", GetFullNameFromType(type))
-          .Change("<ELEMENT_NAME>", elm->GetID());
+                  .Replace("ELEMENT_TYPE", GetFullNameFromType(type))
+                  .Replace("ELEMENT_NAME", elm->GetID())
+                  .Replace("HASH_ELEMENT_NAME", GetHashCodeStr(elm->GetID()));
   }
 
   return RemoveLine(code);
@@ -1072,11 +977,13 @@ std::string CBodyGeneratorBase::GenBaseUnitMapRead(const Elements& elms) {
     auto& type = elm->GetType();
     if (type.GetUserDefinedType() == BaseType::UserType::ENUM)
       code += ReplaceAll(CB_STRUCTURE_ENUM_UNIT_MAP_READ)
-          .Change("<ELEMENT_NAME>", elm->GetID());
+                  .Replace("ELEMENT_NAME", elm->GetID())
+                  .Replace("HASH_ELEMENT_NAME", GetHashCodeStr(elm->GetID()));
     else
       code += ReplaceAll(CB_STRUCTURE_BASE_UNIT_MAP_READ)
-          .Change("<ELEMENT_TYPE>", GetFullNameFromType(type))
-          .Change("<ELEMENT_NAME>", elm->GetID());
+                  .Replace("ELEMENT_TYPE", GetFullNameFromType(type))
+                  .Replace("ELEMENT_NAME", elm->GetID())
+                  .Replace("HASH_ELEMENT_NAME", GetHashCodeStr(elm->GetID()));
   }
 
   return RemoveLine(code);
@@ -1090,21 +997,21 @@ std::string CBodyGeneratorBase::GenBaseSet(
       type.GetUserDefinedType() == BaseType::UserType::STRUCTURE ||
       type.GetMetaType() != nullptr || type.GetKeyType() != nullptr) {
     code = ReplaceAll(CB_STRUCTURE_BASE_USER_DEFINED_SET)
-        .Change("<PREFIX>", GetHandlePrefix())
-        .Change("<NAME>", GetFullNameFromType(type))
-        .Change("<ELEMENT_FREE>", RemoveLine(GenBaseElementFree(elm)))
-        .Change("<ELEMENT_NAME>", elm->GetID());
+               .Change("<PREFIX>", GetHandlePrefix())
+               .Change("<NAME>", GetFullNameFromType(type))
+               .Change("<ELEMENT_FREE>", RemoveLine(GenBaseElementFree(elm)))
+               .Change("<ELEMENT_NAME>", elm->GetID());
   } else if (type.ToString() == "bundle") {
     code = ReplaceAll(CB_STRUCTURE_BASE_BUNDLE_SET)
-        .Change("<ELEMENT_FREE>", RemoveLine(GenBaseElementFree(elm)))
-        .Change("<ELEMENT_NAME>", elm->GetID());
+               .Change("<ELEMENT_FREE>", RemoveLine(GenBaseElementFree(elm)))
+               .Change("<ELEMENT_NAME>", elm->GetID());
   } else if (type.ToString() == "string" || type.ToString() == "file") {
     code = ReplaceAll(CB_STRUCTURE_BASE_STRING_SET)
-        .Change("<ELEMENT_FREE>", RemoveLine(GenBaseElementFree(elm)))
-        .Change("<ELEMENT_NAME>", elm->GetID());
+               .Change("<ELEMENT_FREE>", RemoveLine(GenBaseElementFree(elm)))
+               .Change("<ELEMENT_NAME>", elm->GetID());
   } else {
     code = ReplaceAll(CB_STRUCTURE_BASE_BASE_SET)
-        .Change("<ELEMENT_NAME>", elm->GetID());
+               .Change("<ELEMENT_NAME>", elm->GetID());
   }
 
   return RemoveLine(code);
@@ -1118,25 +1025,25 @@ std::string CBodyGeneratorBase::GenBaseGet(
       type.GetUserDefinedType() == BaseType::UserType::STRUCTURE ||
       type.GetMetaType() != nullptr || type.GetKeyType() != nullptr) {
     code = ReplaceAll(CB_STRUCTURE_BASE_USER_DEFINED_GET)
-        .Change("<PREFIX>", GetHandlePrefix())
-        .Change("<NAME>", GetFullNameFromType(type))
-        .Change("<ELEMENT_NAME>", elm->GetID());
+               .Change("<PREFIX>", GetHandlePrefix())
+               .Change("<NAME>", GetFullNameFromType(type))
+               .Change("<ELEMENT_NAME>", elm->GetID());
   } else if (type.ToString() == "bundle") {
     code = ReplaceAll(CB_STRUCTURE_BASE_BUNDLE_GET)
-        .Change("<ELEMENT_NAME>", elm->GetID());
+               .Change("<ELEMENT_NAME>", elm->GetID());
   } else if (type.ToString() == "string" || type.ToString() == "file") {
     code = ReplaceAll(CB_STRUCTURE_BASE_STRING_GET)
-        .Change("<ELEMENT_NAME>", elm->GetID());
+               .Change("<ELEMENT_NAME>", elm->GetID());
   } else {
     code = ReplaceAll(CB_STRUCTURE_BASE_BASE_GET)
-        .Change("<ELEMENT_NAME>", elm->GetID());
+               .Change("<ELEMENT_NAME>", elm->GetID());
   }
 
   return RemoveLine(code);
 }
 
 std::string CBodyGeneratorBase::GenBaseSetGet(const std::string& name,
-    const Elements& elms) {
+                                              const Elements& elms) {
   std::string code;
   for (const auto& elm : elms) {
     auto& type = elm->GetType();
@@ -1146,268 +1053,175 @@ std::string CBodyGeneratorBase::GenBaseSetGet(const std::string& name,
         GetParamTypeString(ParameterType::Direction::OUT, type, name);
 
     code += ReplaceAll(CB_STRUCTURE_BASE_SET_GET)
-        .Change("<PREFIX>", GetHandlePrefix())
-        .Change("<NAME>", name)
-        .Change("<ELEMENT_NAME>", elm->GetID())
-        .Change("<PARAM_TYPE_IN>", param_type_in)
-        .Change("<PARAM_TYPE_OUT>", param_type_out)
-        .Change("<BASE_SET>", GenBaseSet(elm))
-        .Change("<BASE_GET>", GenBaseGet(elm));
+                .Change("<PREFIX>", GetHandlePrefix())
+                .Change("<NAME>", name)
+                .Change("<ELEMENT_NAME>", elm->GetID())
+                .Change("<PARAM_TYPE_IN>", param_type_in)
+                .Change("<PARAM_TYPE_OUT>", param_type_out)
+                .Change("<BASE_SET>", GenBaseSet(elm))
+                .Change("<BASE_GET>", GenBaseGet(elm));
   }
 
   return RemoveLine(code);
 }
 
-void CBodyGeneratorBase::GenStructureBase(std::ofstream& stream,
-    const Structure& st) {
+std::string CBodyGeneratorBase::GetStructureBase(const Structure& st) {
   auto elms = GetElements(st);
-  ReplaceAll(CB_STRUCTURE_BASE)
-      .Change("<PREFIX>", GetHandlePrefix())
-      .Change("<NAME>", st.GetID())
-      .Change("<ELEMENTS_FREE>", GenBaseElementsFree(elms))
-      .Change("<UNIT_MAP_WRITE>", GenBaseUnitMapWrite(elms))
-      .Change("<UNIT_MAP_READ>", GenBaseUnitMapRead(elms))
+  return ReplaceAll(CB_STRUCTURE_BASE)
+      .Repeat("TO_ELEMENTS", GetElements(st),
+              [&](auto& r, const auto& i) {
+                bool is_val_type = IsDefaultType(&i->GetType());
+
+                r.Remove("IS_VALUE_TYPE", !is_val_type)
+                    .Remove("IS_PTR_TYPE", is_val_type)
+                    .Replace("ELEMENT_NAME", i->GetID())
+                    .Replace("PARCEL_TYPE", GetParcelType(i->GetType()));
+                return true;
+              })
+      .Repeat("FROM_ELEMENTS", GetElements(st),
+              [&](auto& r, const auto& i) {
+                bool is_val_type = IsDefaultType(&i->GetType());
+                bool is_enum = i->GetType().IsEnumType();
+
+                r.Remove("IS_VALUE_TYPE", !is_val_type)
+                    .Remove("IS_PTR_TYPE", is_val_type)
+                    .Remove("IS_ENUM", !is_enum)
+                    .Replace("ELEMENT_NAME", i->GetID())
+                    .Replace("PARCEL_TYPE", GetParcelType(i->GetType()));
+                return true;
+              })
+      .Replace("PREFIX", GetHandlePrefix())
+      .Replace("NAME", st.GetID())
+      .Replace("ELEMENTS_FREE", GenBaseElementsFree(elms))
+      .Replace("HASH_CLONE", "clone"_hash)
       .Transform([&](std::string code) {
-            return SmartIndent(code + GenBaseSetGet(st.GetID(), elms));
-          })
-      .Out(stream);
-}
-
-void CBodyGeneratorBase::AddParameterType(const Interface& iface,
-    const BaseType& type, ParameterType::Direction direction) {
-  if (IsDelegateType(iface, type)) {
-    AddParameterType(
-        std::make_shared<ParameterType>(
-          new BaseType("delegate", "delegate", true),
-          ParameterType::Direction::IN));
-    AddParameterType(
-        std::make_shared<ParameterType>(
-          new BaseType("delegate", "delegate", true),
-          ParameterType::Direction::OUT));
-    return;
-  } else if (type.IsUserDefinedType()) {
-    AddParameterType(
-        std::make_shared<ParameterType>(
-          new BaseType(type), ParameterType::Direction::IN));
-    AddParameterType(
-        std::make_shared<ParameterType>(
-          new BaseType(type), ParameterType::Direction::OUT));
-  } else if (type.GetMetaType() != nullptr) {
-    AddParameterType(
-        std::make_shared<ParameterType>(
-          new BaseType(type), ParameterType::Direction::IN));
-    AddParameterType(
-        std::make_shared<ParameterType>(
-          new BaseType(type), ParameterType::Direction::OUT));
-    AddParameterType(
-        std::make_shared<ParameterType>(
-          new BaseType(*type.GetMetaType()), ParameterType::Direction::IN));
-    AddParameterType(
-        std::make_shared<ParameterType>(
-          new BaseType(*type.GetMetaType()), ParameterType::Direction::OUT));
-  } else if (type.GetKeyType() != nullptr) {
-    AddParameterType(
-        std::make_shared<ParameterType>(
-          new BaseType(type), ParameterType::Direction::IN));
-    AddParameterType(
-        std::make_shared<ParameterType>(
-          new BaseType(type), ParameterType::Direction::OUT));
-    AddParameterType(
-        std::make_shared<ParameterType>(
-          new BaseType(*type.GetKeyType()), ParameterType::Direction::IN));
-    AddParameterType(
-        std::make_shared<ParameterType>(
-          new BaseType(*type.GetKeyType()), ParameterType::Direction::OUT));
-    if (type.GetValueType() != nullptr) {
-      AddParameterType(
-          std::make_shared<ParameterType>(
-            new BaseType(*type.GetValueType()), ParameterType::Direction::IN));
-      AddParameterType(
-          std::make_shared<ParameterType>(
-            new BaseType(*type.GetValueType()), ParameterType::Direction::OUT));
-    }
-  } else if (type.GetFullName() != "file") {
-    AddParameterType(
-        std::make_shared<ParameterType>(
-          new BaseType(type), direction));
-  }
+        return SmartIndent(code + GenBaseSetGet(st.GetID(), elms));
+      })
+      .ToString();
 }
 
 void CBodyGeneratorBase::AddParameterType(
     std::shared_ptr<ParameterType> param_type) {
   auto& type = param_type->GetBaseType();
-  if (type.GetUserDefinedType() == BaseType::UserType::ENUM)
-    return;
+  if (type.GetUserDefinedType() == BaseType::UserType::ENUM) return;
 
-  std::string key = param_type->GetBaseType().GetFullName(true) +
+  std::string key =
+      param_type->GetBaseType().GetFullName(true) +
       std::to_string(static_cast<int>(param_type->GetDirection()));
   key = GetEnumTypeString(key);
-  if (param_types_.find(key) != param_types_.end())
-    return;
+  if (param_types_.find(key) != param_types_.end()) return;
 
   param_types_[key] = std::move(param_type);
 }
 
-void CBodyGeneratorBase::GenUnitMapDefinition(std::ofstream& stream) {
-  stream << SmartIndent(CB_UNIT_MAP_DEFS);
+std::string CBodyGeneratorBase::GetUnitMapDefinition() {
+  return SmartIndent(CB_UNIT_MAP_DEFS);
 }
 
 void CBodyGeneratorBase::GenParameterMap() {
-  AddParameterType(
-      std::make_shared<ParameterType>(
-        new BaseType("int", "int"), ParameterType::Direction::IN));
-  AddParameterType(
-          std::make_shared<ParameterType>(
-            new BaseType("int", "int"), ParameterType::Direction::OUT));
-
-  if (HasDelegate()) {
-    AddParameterType(
-        std::make_shared<ParameterType>(
-          new BaseType("bool", "bool"), ParameterType::Direction::IN));
-    AddParameterType(
-        std::make_shared<ParameterType>(
-          new BaseType("bool", "bool"), ParameterType::Direction::OUT));
-  }
-
-  if (GetChannelType() != ChannelType::TYPE_GROUP) {
-    AddParameterType(
-        std::make_shared<ParameterType>(
-          new BaseType("string", "string"), ParameterType::Direction::IN));
-    AddParameterType(
-       std::make_shared<ParameterType>(
-         new BaseType("string", "string"), ParameterType::Direction::OUT));
-  }
+  AddParameterType(std::make_shared<ParameterType>(
+      new BaseType("int", "int"), ParameterType::Direction::IN));
+  AddParameterType(std::make_shared<ParameterType>(
+      new BaseType("int", "int"), ParameterType::Direction::OUT));
 
   for (auto& block : GetDocument().GetBlocks()) {
-    if (block->GetType() == Block::TYPE_INTERFACE) {
-      auto& iface = static_cast<const Interface&>(*block);
-      if (GetChannelType() != ChannelType::TYPE_GROUP) {
-        AddParameterType(
-            std::make_shared<ParameterType>(
-              new BaseType("remote_exception", "", true),
-              ParameterType::Direction::OUT));
-        AddParameterType(
-            std::make_shared<ParameterType>(
-              new BaseType("remote_exception", "", true),
-              ParameterType::Direction::IN));
-      }
+    if (block->GetType() != Block::TYPE_INTERFACE) continue;
+    auto& iface = static_cast<const Interface&>(*block);
+    if (GetChannelType() != ChannelType::TYPE_GROUP) {
+      AddParameterType(std::make_shared<ParameterType>(
+          new BaseType("remote_exception", "", true),
+          ParameterType::Direction::OUT));
+      AddParameterType(std::make_shared<ParameterType>(
+          new BaseType("remote_exception", "", true),
+          ParameterType::Direction::IN));
+    }
 
-      for (const auto& decl : iface.GetDeclarations()) {
-        for (const auto& param : decl->GetParameters()) {
-          auto& type = param->GetParameterType().GetBaseType();
-          if (decl->GetMethodType() == Declaration::MethodType::DELEGATE) {
-            AddParameterType(iface, type, ParameterType::Direction::OUT);
+    for (const auto& decl : iface.GetDeclarations()) {
+      for (const auto& param : decl->GetParameters()) {
+        auto dir = param->GetParameterType().GetDirection();
+        const auto& type = param->GetParameterType().GetBaseType();
+
+        if (decl->GetMethodType() == Declaration::MethodType::DELEGATE) {
+          AddParameterType(std::make_shared<ParameterType>(
+              new BaseType(type), ParameterType::Direction::OUT));
+        } else {
+          if (type.GetUserDefinedType() == BaseType::UserType::DELEGATE)
+            continue;
+
+          if (dir == ParameterType::Direction::REF ||
+              GetChannelType() == ChannelType::TYPE_GROUP) {
+            AddParameterType(std::make_shared<ParameterType>(
+                new BaseType(type), ParameterType::Direction::IN));
+            AddParameterType(std::make_shared<ParameterType>(
+                new BaseType(type), ParameterType::Direction::OUT));
           } else {
-            auto direction = param->GetParameterType().GetDirection();
-            if (direction == ParameterType::Direction::REF) {
-              AddParameterType(iface, type,
-                  ParameterType::Direction::IN);
-              AddParameterType(iface, type,
-                  ParameterType::Direction::OUT);
-            } else {
-              AddParameterType(iface, type,
-                  param->GetParameterType().GetDirection());
-            }
+            AddParameterType(
+                std::make_shared<ParameterType>(new BaseType(type), dir));
           }
         }
-
-        auto& type = decl->GetType();
-        if (decl->GetMethodType() == Declaration::MethodType::SYNC) {
-          AddParameterType(iface, type, ParameterType::Direction::OUT);
-        } else if (decl->GetMethodType() == Declaration::MethodType::DELEGATE) {
-          AddParameterType(
-              std::make_shared<ParameterType>(
-                new BaseType("delegate", "delegate", true),
-                ParameterType::Direction::OUT));
-          AddParameterType(
-              std::make_shared<ParameterType>(
-                new BaseType(iface.GetID() + "_" + decl->GetID(), "", true),
-                  ParameterType::Direction::IN));
-          AddParameterType(
-              std::make_shared<ParameterType>(
-                new BaseType(iface.GetID() + "_" + decl->GetID(), "", true),
-                ParameterType::Direction::OUT));
-        }
       }
-    } else {
-      auto& st = static_cast<const Structure&>(*block);
-      AddParameterType(
-        std::make_shared<ParameterType>(
-          new BaseType(st.GetID(), st.GetID(), true),
+
+      auto& type = decl->GetType();
+      if (decl->GetMethodType() == Declaration::MethodType::SYNC) {
+        AddParameterType(std::make_shared<ParameterType>(
+            new BaseType(type), ParameterType::Direction::OUT));
+      } else if (decl->GetMethodType() == Declaration::MethodType::DELEGATE) {
+        AddParameterType(std::make_shared<ParameterType>(
+            new BaseType("delegate", "delegate", true),
             ParameterType::Direction::IN));
-      AddParameterType(
-        std::make_shared<ParameterType>(
-          new BaseType(st.GetID(), st.GetID(), true),
+        AddParameterType(std::make_shared<ParameterType>(
+            new BaseType("delegate", "delegate", true),
             ParameterType::Direction::OUT));
 
-      for (auto& elm : st.GetElements()) {
-        auto& type = elm->GetType();
-        AddParameterType(
-            std::make_shared<ParameterType>(
-              new BaseType(type), ParameterType::Direction::IN));
-        AddParameterType(
-            std::make_shared<ParameterType>(
-              new BaseType(type), ParameterType::Direction::OUT));
+        AddParameterType(std::make_shared<ParameterType>(
+            new BaseType(iface.GetID() + "_" + decl->GetID(), "", true),
+            ParameterType::Direction::IN));
+        AddParameterType(std::make_shared<ParameterType>(
+            new BaseType(iface.GetID() + "_" + decl->GetID(), "", true),
+            ParameterType::Direction::OUT));
       }
     }
   }
-
-  for (auto& i : GetStructures()) {
-    auto& st = *i.second;
-    AddParameterType(
-        std::make_shared<ParameterType>(
-          new BaseType(st.GetID(), st.GetID(), true)));
-
-    for (auto& elm : st.GetElements()) {
-      auto& type = elm->GetType();
-      AddParameterType(
-          std::make_shared<ParameterType>(
-            new BaseType(type), ParameterType::Direction::IN));
-      AddParameterType(
-          std::make_shared<ParameterType>(
-            new BaseType(type), ParameterType::Direction::OUT));
-    }
-  }
 }
 
-void CBodyGeneratorBase::GenUnitMapBase(std::ofstream& stream) {
-  stream << SmartIndent(CB_UNIT_MAP_BASE);
+std::string CBodyGeneratorBase::GetUnitMapBase() {
+  std::string ret = SmartIndent(CB_UNIT_MAP_BASE);
 
-  if (GetChannelType() == ChannelType::TYPE_PROXY)
-    stream << SmartIndent(CB_UNIT_MAP_CLEAR_BASE);
+  if (GetChannelType() == ChannelType::TYPE_PROXY) {
+    ret += SmartIndent(CB_UNIT_MAP_CLEAR_BASE);
+  }
 
   GenParameterMap();
 
   std::string code;
   for (const auto& iter : param_types_) {
-    if (!code.empty())
-      code += NLine(1);
-
     auto& param_type = *iter.second;
+
+    if (!code.empty()) code += NLine(1);
+
     if (param_type.GetDirection() == ParameterType::Direction::IN) {
-      if (GetChannelType() == ChannelType::TYPE_GROUP) {
-        code += GenUnitMapWrite(param_type);
-        code += GenUnitMapRead(param_type);
-      } else if (GetChannelType() == ChannelType::TYPE_PROXY) {
+      if (GetChannelType() == ChannelType::TYPE_PROXY) {
         code += GenUnitMapWrite(param_type);
       } else {
         code += GenUnitMapRead(param_type);
       }
-    } else {
-      if (GetChannelType() == ChannelType::TYPE_PROXY)
+    } else if (param_type.GetDirection() == ParameterType::Direction::OUT) {
+      if (GetChannelType() == ChannelType::TYPE_PROXY) {
         code += GenUnitMapRead(param_type);
-      else if (GetChannelType() == ChannelType::TYPE_STUB)
+      } else {
         code += GenUnitMapWrite(param_type);
+      }
     }
   }
 
-  stream << SmartIndent(code);
+  ret += SmartIndent(code);
+
+  return ret;
 }
 
 std::string CBodyGeneratorBase::GetFullTypeNameFromType(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;
 
   return GetFullNameFromType(type);
 }
@@ -1416,33 +1230,37 @@ std::string CBodyGeneratorBase::GenUnitMapWrite(
     const ParameterType& param_type) {
   std::string code;
   auto& type = param_type.GetBaseType();
-  if (type.IsUserDefinedType() ||
-      type.GetMetaType() != nullptr ||
+  if (type.IsUserDefinedType() || type.GetMetaType() != nullptr ||
       type.GetKeyType() != nullptr) {
     if (type.ToString() == "delegate") {
-      code = std::string(CB_UNIT_MAP_DELEGATE_WRITE);
+      code = ReplaceAll(CB_UNIT_MAP_DELEGATE_WRITE)
+                 .Replace("HASH_DELEGATE", "delegate"_hash);
     } else {
       code += ReplaceAll(CB_UNIT_MAP_USER_DEFINED_WRITE)
-          .Change("<TYPE_NAME>", GetFullNameFromType(type))
-          .Change("<FULL_TYPE_NAME>", GetFullTypeNameFromType(type))
-          .Change("<PARAM_TYPE>",
-              GetParamTypeString(ParameterType::Direction::IN,
-                param_type.GetBaseType()))
-          .Change("<FULL_PARAM_TYPE>",
-              GetParamTypeString(ParameterType::Direction::IN,
-                param_type.GetBaseType(), "", true));
+                  .Replace("TYPE_NAME", GetFullNameFromType(type))
+                  .Replace("FULL_TYPE_NAME", GetFullTypeNameFromType(type))
+                  .Replace("HASH_FULL_TYPE_NAME",
+                           GetHashCodeStr(GetFullTypeNameFromType(type)))
+                  .Replace("PARAM_TYPE",
+                           GetParamTypeString(ParameterType::Direction::IN,
+                                              param_type.GetBaseType()));
     }
   } else if (type.ToString() == "bundle") {
-    code = std::string(CB_UNIT_MAP_BUNDLE_WRITE);
+    code = ReplaceAll(CB_UNIT_MAP_BUNDLE_WRITE)
+               .Replace("HASH_BUNDLE", "bundle"_hash);
   } else if (type.ToString() == "string") {
-    code = std::string(CB_UNIT_MAP_STRING_WRITE);
+    code = ReplaceAll(CB_UNIT_MAP_STRING_WRITE)
+               .Replace("HASH_STRING", "string"_hash);
+  } else if (type.ToString() == "file") {
+    code = ReplaceAll(CB_UNIT_MAP_FILE_WRITE).Replace("HASH_FILE", "file"_hash);
   } else {
     code = ReplaceAll(CB_UNIT_MAP_BASE_WRITE)
-        .Change("<TYPE_NAME>", type.ToString())
-        .Change("<PARAM_TYPE>",
-            GetParamTypeString(ParameterType::Direction::IN,
-              param_type.GetBaseType()))
-        .Change("<PARCEL_TYPE>", GetParcelType(param_type.GetBaseType()));
+               .Replace("TYPE_NAME", type.ToString())
+               .Replace("HASH_TYPE_NAME", GetHashCodeStr(type.ToString()))
+               .Replace("PARAM_TYPE",
+                        GetParamTypeString(ParameterType::Direction::IN,
+                                           param_type.GetBaseType()))
+               .Replace("PARCEL_TYPE", GetParcelType(param_type.GetBaseType()));
   }
 
   return code;
@@ -1452,59 +1270,83 @@ std::string CBodyGeneratorBase::GenUnitMapRead(
     const ParameterType& param_type) {
   std::string code;
   auto& type = param_type.GetBaseType();
-  if (type.IsUserDefinedType() ||
-      type.GetMetaType() != nullptr ||
+  std::string ctor = GetHandlePrefix() + "_" +
+                     GetFullNameFromType(param_type.GetBaseType()) + "_create";
+
+  if (type.IsUserDefinedType() || type.GetMetaType() != nullptr ||
       type.GetKeyType() != nullptr) {
     if (type.ToString() == "delegate") {
-      code = std::string(CB_UNIT_MAP_DELEGATE_READ);
+      code = ReplaceAll(CB_UNIT_MAP_DELEGATE_READ)
+                 .Replace("HASH_DELEGATE", "delegate"_hash);
+    } else if (type.ToString() == "remote_exception") {
+      code =
+          ReplaceAll(CB_UNIT_MAP_REMOTE_EXCEPTION_READ)
+              .Replace("HASH_REMOTE_EXCEPTION", "remote_exception"_hash)
+              .Replace("PARAM_TYPE_OUT",
+                       GetParamTypeString(ParameterType::Direction::OUT,
+                                          param_type.GetBaseType()))
+              .Replace("PARAM_TYPE_IN",
+                       GetParamTypeString(ParameterType::Direction::IN,
+                                          param_type.GetBaseType(), "", true))
+              .Replace("PARAM_TYPE_CTOR", ctor);
     } else {
-      std::string ctor = GetHandlePrefix() + "_" +
-          GetFullNameFromType(param_type.GetBaseType()) + "_create";
-      code = ReplaceAll(CB_UNIT_MAP_USER_DEFINED_READ)
-          .Change("<TYPE_NAME>", GetEnumTypeString(GetFullNameFromType(type)))
-          .Change("<FULL_TYPE_NAME>", GetFullTypeNameFromType(type))
-          .Change("<PARAM_TYPE_OUT>",
-              GetParamTypeString(ParameterType::Direction::OUT,
-                param_type.GetBaseType()))
-          .Change("<PARAM_TYPE_IN>",
-              GetParamTypeString(ParameterType::Direction::IN,
-                param_type.GetBaseType(), "", true))
-          .Change("<PARAM_TYPE_CTOR>", ctor);
+      code =
+          ReplaceAll(CB_UNIT_MAP_USER_DEFINED_READ)
+              .Replace("TYPE_NAME",
+                       GetEnumTypeString(GetFullNameFromType(type)))
+              .Replace("FULL_TYPE_NAME", GetFullTypeNameFromType(type))
+              .Replace("HASH_FULL_TYPE_NAME",
+                       GetHashCodeStr(GetFullTypeNameFromType(type)))
+              .Replace("PARAM_TYPE_OUT",
+                       GetParamTypeString(ParameterType::Direction::OUT,
+                                          param_type.GetBaseType()))
+              .Replace("PARAM_TYPE_IN",
+                       GetParamTypeString(ParameterType::Direction::IN,
+                                          param_type.GetBaseType(), "", true))
+              .Replace("PARAM_TYPE_CTOR", ctor);
     }
   } else if (type.ToString() == "bundle") {
-    code = std::string(CB_UNIT_MAP_BUNDLE_READ);
+    code = ReplaceAll(CB_UNIT_MAP_BUNDLE_READ)
+               .Replace("HASH_BUNDLE", "bundle"_hash);
   } else if (type.ToString() == "string") {
-    code = std::string(CB_UNIT_MAP_STRING_READ);
+    code = ReplaceAll(CB_UNIT_MAP_STRING_READ)
+               .Replace("HASH_STRING", "string"_hash);
+  } else if (type.ToString() == "file") {
+    code = ReplaceAll(CB_UNIT_MAP_FILE_READ).Replace("HASH_FILE", "file"_hash);
   } else {
     code = ReplaceAll(CB_UNIT_MAP_BASE_READ)
-        .Change("<TYPE_NAME>", type.ToString())
-        .Change("<PARAM_TYPE>",
-            GetParamTypeString(ParameterType::Direction::OUT,
-              param_type.GetBaseType()))
-        .Change("<PARCEL_TYPE>", GetParcelType(param_type.GetBaseType()));
+               .Replace("TYPE_NAME", type.ToString())
+               .Replace("HASH_TYPE_NAME", GetHashCodeStr(type.ToString()))
+               .Replace("PARAM_TYPE",
+                        GetParamTypeString(ParameterType::Direction::OUT,
+                                           param_type.GetBaseType()))
+               .Replace("PARCEL_TYPE", GetParcelType(param_type.GetBaseType()));
   }
 
   return code;
 }
 
-void CBodyGeneratorBase::GenRemoteExceptionDefinition(std::ofstream& stream) {
-  ReplaceAll(CB_REMOTE_EXCEPTION_DEF)
-      .Change("<PREFIX>", GetHandlePrefix())
+std::string CBodyGeneratorBase::GetRemoteExceptionDefinition() {
+  return ReplaceAll(CB_REMOTE_EXCEPTION_DEF)
+      .Replace("PREFIX", GetHandlePrefix())
       .Transform([&](std::string code) { return SmartIndent(code); })
-      .Out(stream);
+      .ToString();
 }
 
-void CBodyGeneratorBase::GenRemoteExceptionBase(std::ofstream& stream) {
-  ReplaceAll(CB_REMOTE_EXCEPTION_BASE)
-      .Change("<PREFIX>", GetHandlePrefix())
-      .Transform([&](std::string code) { return SmartIndent(code); })
-      .Out(stream);
+std::string CBodyGeneratorBase::GetRemoteExceptionBase() {
+  std::string ret =
+      ReplaceAll(CB_REMOTE_EXCEPTION_BASE)
+          .Replace("PREFIX", GetHandlePrefix())
+          .Transform([&](std::string code) { return SmartIndent(code); })
+          .ToString();
 
-  ReplaceAll(IsProxy() ? CB_PROXY_REMOTE_EXCEPTION_BASE
-                       : CB_STUB_REMOTE_EXCEPTION_BASE)
-      .Change("<PREFIX>", GetHandlePrefix())
-      .Transform([&](std::string code) { return SmartIndent(code); })
-      .Out(stream);
+  ret += ReplaceAll(IsProxy() ? CB_PROXY_REMOTE_EXCEPTION_BASE
+                              : CB_STUB_REMOTE_EXCEPTION_BASE)
+             .Replace("PREFIX", GetHandlePrefix())
+             .Transform([&](std::string code) { return SmartIndent(code); })
+             .ToString();
+
+  return ret;
 }
 
 }  // namespace version2
index 4444889d20130b32d541d3a5d20d2abad228a959..a10bbae2c822b6f8ca70e578a16bb53ecad3f6c6 100644 (file)
@@ -31,66 +31,55 @@ class CBodyGeneratorBase : public tidl::CBodyGeneratorBase {
   explicit CBodyGeneratorBase(std::shared_ptr<Document> doc);
   virtual ~CBodyGeneratorBase() = default;
 
-  void GenStructureDefinition(std::ofstream& stream);
-  void GenStructure(std::ofstream& stream);
-  void GenDelegateBase(std::ofstream& stream);
-  void GenUnitMapDefinition(std::ofstream& stream);
-  void GenUnitMapBase(std::ofstream& stream);
+  std::string GetStructureDefinition();
+  std::string GetStructure();
+  std::string GetUnitMapDefinition();
+  std::string GetUnitMapBase();
   bool HasDelegate();
-  void GenIncludeLemHeaders(std::ofstream& stream);
   std::string GetHandlePrefixReverse();
-  void GenRemoteExceptionDefinition(std::ofstream& stream);
-  void GenRemoteExceptionBase(std::ofstream& stream);
+  std::string GetRemoteExceptionDefinition();
+  std::string GetRemoteExceptionBase();
+  std::string GetRpcPortInternalAPIs();
 
  private:
   void AddTypeName(const Structure& st);
-  void GenStructureArrayBaseDefinition(std::ofstream& stream,
-      const Structure& st);
-  void GenStructureListBaseDefinition(std::ofstream& stream,
-      const Structure& st);
-  void GenStructureMapBaseDefinition(std::ofstream& stream,
-      const Structure& st);
-  void GenStructureSetBaseDefinition(std::ofstream& stream,
-      const Structure& st);
+  std::string GetStructureArrayBaseDefinition(const Structure& st);
+  std::string GetStructureListBaseDefinition(const Structure& st);
+  std::string GetStructureMapBaseDefinition(const Structure& st);
+  std::string GetStructureSetBaseDefinition(const Structure& st);
   std::string GenBaseElements(const Elements& elms, const std::string& id);
-  void GenStructureBaseDefinition(std::ofstream& stream, const Structure& st);
+  std::string GetStructureBaseDefinition(const Structure& st);
 
-  std::string GenArrayUnitMapWrite(const std::shared_ptr<Element>& elm);
-  std::string GenArrayUnitMapRead(const std::shared_ptr<Element>& elm);
   std::string GenArrayElementsFree(const std::shared_ptr<Element>& elm);
-  void GenStructureArrayBase(std::ofstream& stream, const Structure& st);
+  std::string GetStructureArrayBase(const Structure& st);
   std::string GenListDataFree(const std::shared_ptr<Element>& elm);
   std::string GenListUnitMapWrite(const std::shared_ptr<Element>& elm);
   std::string GenListUnitMapRead(const std::shared_ptr<Element>& elm);
   std::string GenListAdd(const std::shared_ptr<Element>& elm);
   std::string GenListCallbackParamType(const std::shared_ptr<Element>& elm);
-  void GenStructureListBase(std::ofstream& stream, const Structure& st);
+  std::string GetStructureListBase(const Structure& st);
   std::string GenMapContains(const BaseType& key_type);
   std::string GenMapKeyExistNullCheck(const BaseType& key_type);
   std::string GenMapForeachVarsDefinition(const BaseType& key_type,
-      const BaseType& value_type);
+                                          const BaseType& value_type);
   std::string GenMapErase(const BaseType& key_type);
   std::string GenMapKeyNullCheck(const BaseType& key_type);
   std::string GenMapLookupValueSet(const BaseType& value_type);
   std::string GenMapLookup(const BaseType& key_type,
-      const BaseType& value_type);
+                           const BaseType& value_type);
   std::string GenMapKeyValueNullCheck(const BaseType& key_type);
   std::string GenMapInsertNewKeyFree(const BaseType& key_type);
   std::string GenMapInsertNewValueImpl(const BaseType& key_type,
-      const BaseType& value_type);
+                                       const BaseType& value_type);
   std::string GenMapInsertNewKeyImpl(const BaseType& key_type);
   std::string GenMapInsert(const BaseType& key_type,
-      const BaseType& value_type);
+                           const BaseType& value_type);
   std::string GenMapKeyValueNullCheck(const BaseType& key_type,
-      const BaseType& value_type);
+                                      const BaseType& value_type);
   std::string GenMapFreeFunc(const BaseType& type);
   std::string GenMapCompareKeyVarsDefinition(const BaseType& type);
   std::string GenMapCompareKeyVarsImpl(const BaseType& type);
-  std::string GenMapUnitMapValueRead(const BaseType& type);
-  std::string GenMapUnitMapKeyRead(const BaseType& type);
-  std::string GenMapUnitMapValueWrite(const BaseType& type);
-  std::string GenMapUnitMapKeyWrite(const BaseType& type);
-  void GenStructureMapBase(std::ofstream& stream, const Structure& st);
+  std::string GetStructureMapBase(const Structure& st);
   std::string GenSetContains(const BaseType& type);
   std::string GenSetKeyExistNullCheck(const BaseType& type);
   std::string GenSetForeachKeyVarDefinition(const BaseType& type);
@@ -100,9 +89,7 @@ class CBodyGeneratorBase : public tidl::CBodyGeneratorBase {
   std::string GenSetKeyFreeFunc(const BaseType& type);
   std::string GenSetCompareKeyVarsDefinition(const BaseType& type);
   std::string GenSetCompareKeyVarsImpl(const BaseType& type);
-  std::string GenSetUnitMapKeyRead(const BaseType& type);
-  std::string GenSetUnitMapKeyWrite(const BaseType& type);
-  void GenStructureSetBase(std::ofstream& stream, const Structure& st);
+  std::string GetStructureSetBase(const Structure& st);
   std::string GenBaseElementFree(const std::shared_ptr<Element>& elm);
   std::string GenBaseElementsFree(const Elements& elms);
   std::string GenBaseUnitMapWrite(const Elements& elms);
@@ -110,10 +97,7 @@ class CBodyGeneratorBase : public tidl::CBodyGeneratorBase {
   std::string GenBaseSet(const std::shared_ptr<Element>& elm);
   std::string GenBaseGet(const std::shared_ptr<Element>& elm);
   std::string GenBaseSetGet(const std::string& name, const Elements& elms);
-  void GenStructureBase(std::ofstream& stream, const Structure& st);
-
-  void AddParameterType(const Interface& iface, const BaseType& type,
-      ParameterType::Direction direction);
+  std::string GetStructureBase(const Structure& st);
   void AddParameterType(std::shared_ptr<ParameterType> type);
 
   std::string GetFullTypeNameFromType(const BaseType& type);
index 1ae929de3b29908853676e2350946415d8cf7e22..d37cc63b1fb5bf0a2a0039201e089d14c234681b 100644 (file)
 namespace tidl {
 namespace version2 {
 
-constexpr const char CB_LEM_HEADER[] =
-R"__c_cb(
-#include <unistd.h>
-#include <dlfcn.h>
-#include <app_common.h>
-)__c_cb";
-
 constexpr const char CB_UNIT_MAP_DEFS[] =
 R"__c_cb(
+typedef void (*rpc_port_unit_write_func)(rpc_port_parcel_h parcel, void* data);
+
 typedef struct rpc_port_unit_s {
   rpc_port_parcelable_t parcelable;
-  char *name;
-  char *type;
+  int name;
+  int type;
   rpc_port_parcel_h parcel;
+  rpc_port_unit_write_func write_cb;
+  void *data;
 } rpc_port_unit_t;
 
 typedef rpc_port_unit_t *rpc_port_unit_h;
@@ -51,58 +48,103 @@ R"__c_cb(
 static void __rpc_port_unit_to(rpc_port_parcel_h parcel, void *user_data)
 {
   rpc_port_unit_h unit = user_data;
-  void *raw = nullptr;
-  unsigned int size = 0;
+  size_t size = 0;
+  unsigned int size_pos = 0;
+  unsigned int cur_pos = 0;
   int ret;
 
-  ret = rpc_port_parcel_write_string(parcel, unit->name);
+  ret = rpc_port_parcel_write_int32(parcel, unit->name);
+  if (ret != RPC_PORT_ERROR_NONE) {
+    set_last_result(ret);
+    return;
+  }
+
+  ret = rpc_port_parcel_write_int32(parcel, unit->type);
+  if (ret != RPC_PORT_ERROR_NONE) {
+    set_last_result(ret);
+    return;
+  }
+
+  ret = rpc_port_parcel_get_data_size(parcel, &size_pos);
   if (ret != RPC_PORT_ERROR_NONE) {
     set_last_result(ret);
     return;
   }
 
-  ret = rpc_port_parcel_write_string(parcel, unit->type);
+  ret = rpc_port_parcel_reserve(parcel, sizeof(unsigned int));
   if (ret != RPC_PORT_ERROR_NONE) {
     set_last_result(ret);
     return;
   }
 
-  ret = rpc_port_parcel_get_raw(unit->parcel, &raw, &size);
+  if (unit->write_cb)
+    unit->write_cb(parcel, unit);
+
+  ret = rpc_port_parcel_get_data_size(parcel, &cur_pos);
   if (ret != RPC_PORT_ERROR_NONE) {
     set_last_result(ret);
     return;
   }
 
-  ret = rpc_port_parcel_write_array_count(parcel, size & INT_MAX);
+  size = cur_pos - size_pos - sizeof(unsigned int);
+  ret = rpc_port_parcel_set_data_size(parcel, size_pos);
   if (ret != RPC_PORT_ERROR_NONE) {
     set_last_result(ret);
     return;
   }
 
-  ret = rpc_port_parcel_burst_write(parcel, raw, size);
+  ret = rpc_port_parcel_write_int32(parcel, size);
+  if (ret != RPC_PORT_ERROR_NONE) {
+    set_last_result(ret);
+    return;
+  }
+
+  ret = rpc_port_parcel_set_data_size(parcel, cur_pos);
+
   set_last_result(ret);
 }
 
 static void __rpc_port_unit_from(rpc_port_parcel_h parcel, void *user_data)
 {
   rpc_port_unit_h unit = user_data;
-  unsigned char *raw;
   int size = 0;
+  unsigned int start_pos = 0;
+  int ret;
+  rpc_port_parcel_h sub_parcel = NULL;
 
-  rpc_port_parcel_read_string(parcel, &unit->name);
-  rpc_port_parcel_read_string(parcel, &unit->type);
+  rpc_port_parcel_read_int32(parcel, &unit->name);
+  rpc_port_parcel_read_int32(parcel, &unit->type);
   rpc_port_parcel_read_array_count(parcel, &size);
+  if (size == 0) return;
 
-  raw = malloc(size);
-  if (raw == nullptr) {
-    _E("malloc() is failed");
-    set_last_result(RPC_PORT_ERROR_OUT_OF_MEMORY);
+  ret = rpc_port_parcel_get_reader(parcel, &start_pos);
+  if (ret != RPC_PORT_ERROR_NONE) {
+    set_last_result(ret);
     return;
   }
 
-  rpc_port_parcel_burst_read(parcel, (void *)raw, size);
-  rpc_port_parcel_burst_write(unit->parcel, raw, size);
-  free(raw);
+  ret = rpc_port_parcel_create_from_parcel(&sub_parcel, parcel, start_pos,
+                                           size);
+  if (ret != RPC_PORT_ERROR_NONE) {
+    set_last_result(ret);
+    return;
+  }
+
+  ret = rpc_port_parcel_reserve(sub_parcel, size);
+  if (ret != RPC_PORT_ERROR_NONE) {
+    rpc_port_parcel_destroy(sub_parcel);
+    set_last_result(ret);
+    return;
+  }
+
+  ret = rpc_port_parcel_set_reader(parcel, start_pos + size);
+  if (ret != RPC_PORT_ERROR_NONE) {
+    rpc_port_parcel_destroy(sub_parcel);
+    set_last_result(ret);
+    return;
+  }
+
+  unit->parcel = sub_parcel;
   set_last_result(RPC_PORT_ERROR_NONE);
 }
 
@@ -116,19 +158,12 @@ static void rpc_port_unit_destroy(gpointer user_data)
   if (unit->parcel)
     rpc_port_parcel_destroy(unit->parcel);
 
-  if (unit->type)
-    free(unit->type);
-
-  if (unit->name)
-    free(unit->name);
-
   free(unit);
 }
 
-static rpc_port_unit_h rpc_port_unit_create(const char *name, const char *type)
+static rpc_port_unit_h rpc_port_unit_create(int name, int type)
 {
   rpc_port_unit_h unit;
-  int ret;
 
   unit = calloc(1, sizeof(rpc_port_unit_t));
   if (unit == nullptr) {
@@ -136,33 +171,11 @@ static rpc_port_unit_h rpc_port_unit_create(const char *name, const char *type)
     return nullptr;
   }
 
-  if (name != nullptr) {
-    unit->name = strdup(name);
-    if (unit->name == nullptr) {
-        _E("strdup() is failed. name: %s", name);
-        rpc_port_unit_destroy(unit);
-        return nullptr;
-    }
-  }
-
-  if (type != nullptr) {
-    unit->type = strdup(type);
-    if (unit->type == nullptr) {
-      _E("strdup() is failed. type: %s", type);
-      rpc_port_unit_destroy(unit);
-      return nullptr;
-    }
-  }
-
-  ret = rpc_port_parcel_create_without_header(&unit->parcel);
-  if (ret != RPC_PORT_ERROR_NONE) {
-    _E("rpc_port_parcel_create_without_header() is failed. error: %d", ret);
-    rpc_port_unit_destroy(unit);
-    return nullptr;
-  }
-
+  unit->name = name;
+  unit->type = type;
   unit->parcelable.to = __rpc_port_unit_to;
   unit->parcelable.from = __rpc_port_unit_from;
+  unit->write_cb = nullptr;
 
   return unit;
 }
@@ -193,8 +206,9 @@ static void __rpc_port_unit_map_from(rpc_port_parcel_h parcel, void *user_data)
   int i;
 
   rpc_port_parcel_read_array_count(parcel, &size);
+  rpc_port_parcel_pin(parcel);
   for (i = 0; i < size; ++i) {
-    unit = rpc_port_unit_create(nullptr, nullptr);
+    unit = rpc_port_unit_create(0, 0);
     if (unit == nullptr) {
       set_last_result(RPC_PORT_ERROR_OUT_OF_MEMORY);
       break;
@@ -206,7 +220,7 @@ static void __rpc_port_unit_map_from(rpc_port_parcel_h parcel, void *user_data)
       break;
     }
 
-    g_hash_table_insert(unit_map->table, unit->name, unit);
+    g_hash_table_insert(unit_map->table, GINT_TO_POINTER(unit->name), unit);
   }
 }
 
@@ -231,7 +245,7 @@ static rpc_port_unit_map_h rpc_port_unit_map_create(void)
     return nullptr;
   }
 
-  unit_map->table = g_hash_table_new_full(g_str_hash, g_str_equal, nullptr, rpc_port_unit_destroy);
+  unit_map->table = g_hash_table_new_full(g_direct_hash, g_direct_equal, nullptr, rpc_port_unit_destroy);
   if (unit_map->table == nullptr) {
     _E("g_hash_table_new_full() is failed");
     rpc_port_unit_map_destroy(unit_map);
@@ -268,21 +282,29 @@ static int rpc_port_unit_map_clear(rpc_port_unit_map_h map)
  */
 constexpr const char CB_UNIT_MAP_USER_DEFINED_WRITE[] =
 R"__c_cb(
+static void rpc_port_unit_map_write_<TYPE_NAME>_write_cb(rpc_port_parcel_h parcel, void* data)
+{
+  rpc_port_unit_h unit = data;
+  <PARAM_TYPE> handle = unit->data;
+
+  rpc_port_parcel_write(parcel, &handle->parcelable, handle);
+}
+
 static int rpc_port_unit_map_write_<TYPE_NAME>(rpc_port_unit_map_h unit_map,
-    const char *name, <PARAM_TYPE>value)
+    int name, <PARAM_TYPE> value)
 {
-  <FULL_PARAM_TYPE>handle = value;
   rpc_port_unit_h unit;
 
-  if (unit_map == nullptr || name == nullptr || handle == nullptr)
+  if (unit_map == nullptr)
     return RPC_PORT_ERROR_INVALID_PARAMETER;
 
-  unit = rpc_port_unit_create(name, "<FULL_TYPE_NAME>");
+  unit = rpc_port_unit_create(name, <HASH_FULL_TYPE_NAME> /*<FULL_TYPE_NAME>*/);
   if (unit == nullptr)
     return RPC_PORT_ERROR_OUT_OF_MEMORY;
 
-  rpc_port_parcel_write(unit->parcel, &handle->parcelable, handle);
-  g_hash_table_insert(unit_map->table, unit->name, unit);
+  unit->data = value;
+  unit->write_cb = rpc_port_unit_map_write_<TYPE_NAME>_write_cb;
+  g_hash_table_insert(unit_map->table, GINT_TO_POINTER(unit->name), unit);
 
   return RPC_PORT_ERROR_NONE;
 }
@@ -290,20 +312,29 @@ static int rpc_port_unit_map_write_<TYPE_NAME>(rpc_port_unit_map_h unit_map,
 
 constexpr const char CB_UNIT_MAP_DELEGATE_WRITE[] =
 R"__c_cb(
+static void rpc_port_unit_map_write_delegate_write_cb(rpc_port_parcel_h parcel, void* data)
+{
+  rpc_port_unit_h unit = data;
+  rpc_port_delegate_h handle = unit->data;
+
+  rpc_port_parcel_write(parcel, &handle->parcelable, handle);
+}
+
 static int rpc_port_unit_map_write_delegate(rpc_port_unit_map_h unit_map,
-    const char *name, rpc_port_delegate_h value)
+    int name, rpc_port_delegate_h value)
 {
   rpc_port_unit_h unit;
 
-  if (unit_map == nullptr || name == nullptr || value == nullptr)
+  if (unit_map == nullptr || value == nullptr)
     return RPC_PORT_ERROR_INVALID_PARAMETER;
 
-  unit = rpc_port_unit_create(name, "delegate");
+  unit = rpc_port_unit_create(name, <HASH_DELEGATE> /*delegate*/);
   if (unit == nullptr)
     return RPC_PORT_ERROR_OUT_OF_MEMORY;
 
-  rpc_port_parcel_write(unit->parcel, &value->parcelable, value);
-  g_hash_table_insert(unit_map->table, unit->name, unit);
+  unit->data = value;
+  unit->write_cb = rpc_port_unit_map_write_delegate_write_cb;
+  g_hash_table_insert(unit_map->table, GINT_TO_POINTER(unit->name), unit);
 
   return RPC_PORT_ERROR_NONE;
 }
@@ -311,20 +342,29 @@ static int rpc_port_unit_map_write_delegate(rpc_port_unit_map_h unit_map,
 
 constexpr const char CB_UNIT_MAP_BUNDLE_WRITE[] =
 R"__c_cb(
+static void rpc_port_unit_map_write_bundle_write_cb(rpc_port_parcel_h parcel, void* data)
+{
+  rpc_port_unit_h unit = data;
+  bundle *handle = unit->data;
+
+  rpc_port_parcel_write_bundle(parcel, handle);
+}
+
 static int rpc_port_unit_map_write_bundle(rpc_port_unit_map_h unit_map,
-    const char *name, bundle *value)
+    int name, bundle *value)
 {
   rpc_port_unit_h unit;
 
-  if (unit_map == nullptr || name == nullptr || value == nullptr)
+  if (unit_map == nullptr || value == nullptr)
     return RPC_PORT_ERROR_INVALID_PARAMETER;
 
-  unit = rpc_port_unit_create(name, "bundle");
+  unit = rpc_port_unit_create(name, <HASH_BUNDLE> /*bundle*/);
   if (unit == nullptr)
     return RPC_PORT_ERROR_OUT_OF_MEMORY;
 
-  rpc_port_parcel_write_bundle(unit->parcel, value);
-  g_hash_table_insert(unit_map->table, unit->name, unit);
+  unit->data = value;
+  unit->write_cb = rpc_port_unit_map_write_bundle_write_cb;
+  g_hash_table_insert(unit_map->table, GINT_TO_POINTER(unit->name), unit);
 
   return RPC_PORT_ERROR_NONE;
 }
@@ -332,20 +372,59 @@ static int rpc_port_unit_map_write_bundle(rpc_port_unit_map_h unit_map,
 
 constexpr const char CB_UNIT_MAP_STRING_WRITE[] =
 R"__c_cb(
+static void rpc_port_unit_map_write_string_write_cb(rpc_port_parcel_h parcel, void* data)
+{
+  rpc_port_unit_h unit = data;
+  const char *handle = unit->data;
+
+  rpc_port_parcel_write_string(parcel, handle);
+}
+
 static int rpc_port_unit_map_write_string(rpc_port_unit_map_h unit_map,
-    const char *name, const char *value)
+    int name, const char *value)
 {
   rpc_port_unit_h unit;
 
-  if (unit_map == nullptr || name == nullptr || value == nullptr)
+  if (unit_map == nullptr || value == nullptr)
     return RPC_PORT_ERROR_INVALID_PARAMETER;
 
-  unit = rpc_port_unit_create(name, "string");
+  unit = rpc_port_unit_create(name, <HASH_STRING> /*string*/);
   if (unit == nullptr)
     return RPC_PORT_ERROR_OUT_OF_MEMORY;
 
-  rpc_port_parcel_write_string(unit->parcel, value);
-  g_hash_table_insert(unit_map->table, unit->name, unit);
+  unit->data = (void*)value;
+  unit->write_cb = rpc_port_unit_map_write_string_write_cb;
+  g_hash_table_insert(unit_map->table, GINT_TO_POINTER(unit->name), unit);
+
+  return RPC_PORT_ERROR_NONE;
+}
+)__c_cb";
+
+constexpr const char CB_UNIT_MAP_FILE_WRITE[] =
+R"__c_cb(
+static void rpc_port_unit_map_write_file_write_cb(rpc_port_parcel_h parcel, void* data)
+{
+  rpc_port_unit_h unit = data;
+  const char *handle = unit->data;
+
+  rpc_port_parcel_write_string(parcel, handle);
+}
+
+static int rpc_port_unit_map_write_file(rpc_port_unit_map_h unit_map,
+    int name, const char *value)
+{
+  rpc_port_unit_h unit;
+
+  if (unit_map == nullptr || value == nullptr)
+    return RPC_PORT_ERROR_INVALID_PARAMETER;
+
+  unit = rpc_port_unit_create(name, <HASH_FILE> /*file*/);
+  if (unit == nullptr)
+    return RPC_PORT_ERROR_OUT_OF_MEMORY;
+
+  unit->data = (void*)value;
+  unit->write_cb = rpc_port_unit_map_write_file_write_cb;
+  g_hash_table_insert(unit_map->table, GINT_TO_POINTER(unit->name), unit);
 
   return RPC_PORT_ERROR_NONE;
 }
@@ -358,20 +437,30 @@ static int rpc_port_unit_map_write_string(rpc_port_unit_map_h unit_map,
  */
 constexpr const char CB_UNIT_MAP_BASE_WRITE[] =
 R"__c_cb(
+static void rpc_port_unit_map_write_<TYPE_NAME>_write_cb(rpc_port_parcel_h parcel, void* data)
+{
+  rpc_port_unit_h unit = data;
+  <PARAM_TYPE> *handle = unit->data;
+
+  rpc_port_parcel_write_<PARCEL_TYPE>(parcel, *handle);
+}
+
 static int rpc_port_unit_map_write_<TYPE_NAME>(rpc_port_unit_map_h unit_map,
-    const char *name, <PARAM_TYPE>value)
+    int name, <PARAM_TYPE> *value)
 {
   rpc_port_unit_h unit;
 
-  if (unit_map == nullptr || name == nullptr)
+  if (unit_map == nullptr)
     return RPC_PORT_ERROR_INVALID_PARAMETER;
 
-  unit = rpc_port_unit_create(name, "<TYPE_NAME>");
+  unit = rpc_port_unit_create(name, <HASH_TYPE_NAME> /*<TYPE_NAME>*/);
   if (unit == nullptr)
     return RPC_PORT_ERROR_OUT_OF_MEMORY;
 
-  rpc_port_parcel_write_<PARCEL_TYPE>(unit->parcel, value);
-  g_hash_table_insert(unit_map->table, unit->name, unit);
+  unit->data = value;
+  unit->write_cb = rpc_port_unit_map_write_<TYPE_NAME>_write_cb;
+
+  g_hash_table_insert(unit_map->table, GINT_TO_POINTER(unit->name), unit);
 
   return RPC_PORT_ERROR_NONE;
 }
@@ -387,7 +476,7 @@ static int rpc_port_unit_map_write_<TYPE_NAME>(rpc_port_unit_map_h unit_map,
 constexpr const char CB_UNIT_MAP_USER_DEFINED_READ[] =
 R"__c_cb(
 static void rpc_port_unit_map_read_<TYPE_NAME>(rpc_port_unit_map_h unit_map,
-    const char *name, <PARAM_TYPE_OUT>value)
+    int name, <PARAM_TYPE_OUT>value)
 {
   rpc_port_unit_h unit;
   <PARAM_TYPE_IN>handle;
@@ -405,19 +494,19 @@ static void rpc_port_unit_map_read_<TYPE_NAME>(rpc_port_unit_map_h unit_map,
   }
 
   *value = handle;
-  if (unit_map == nullptr || name == nullptr) {
+  if (unit_map == nullptr) {
     _E("Invalid parameter");
     return;
   }
 
-  unit = g_hash_table_lookup(unit_map->table, name);
+  unit = g_hash_table_lookup(unit_map->table, GINT_TO_POINTER(name));
   if (unit == nullptr) {
-    _E("g_hash_table_lookup() is failed. name: %s", name);
+    _E("g_hash_table_lookup() is failed. name: %d", name);
     return;
   }
 
-  if (strncmp(unit->type, "<FULL_TYPE_NAME>", strlen("<FULL_TYPE_NAME>")) != 0) {
-    _E("type(%s) is not <FULL_TYPE_NAME>", unit->type);
+  if (unit->type != <HASH_FULL_TYPE_NAME> /*<FULL_TYPE_NAME>*/) {
+    _E("type(%d) is not <FULL_TYPE_NAME>", unit->type);
     return;
   }
 
@@ -425,10 +514,50 @@ static void rpc_port_unit_map_read_<TYPE_NAME>(rpc_port_unit_map_h unit_map,
 }
 )__c_cb";
 
+constexpr const char CB_UNIT_MAP_REMOTE_EXCEPTION_READ[] =
+R"__c_cb(
+static void rpc_port_unit_map_read_remote_exception(rpc_port_unit_map_h unit_map,
+    int name, <PARAM_TYPE_OUT>value)
+{
+  rpc_port_unit_h unit;
+  <PARAM_TYPE_IN>handle;
+  int ret;
+
+  if (value == nullptr) {
+    _E("Invalid parameter");
+    return;
+  }
+
+  if (unit_map == nullptr) {
+    _E("Invalid parameter");
+    return;
+  }
+
+  unit = g_hash_table_lookup(unit_map->table, GINT_TO_POINTER(name));
+  if (unit == nullptr) {
+    return;
+  }
+
+  if (unit->type != <HASH_REMOTE_EXCEPTION> /*remote_exception*/) {
+    _E("type(%d) is not remote_exception", unit->type);
+    return;
+  }
+
+  ret = <PARAM_TYPE_CTOR>((<PARAM_TYPE_OUT>)&handle);
+  if (ret != RPC_PORT_ERROR_NONE) {
+    *value = nullptr;
+    return;
+  }
+
+  rpc_port_parcel_read(unit->parcel, &handle->parcelable, handle);
+  *value = handle;
+}
+)__c_cb";
+
 constexpr const char CB_UNIT_MAP_DELEGATE_READ[] =
 R"__c_cb(
 static void rpc_port_unit_map_read_delegate(rpc_port_unit_map_h unit_map,
-    const char *name, rpc_port_delegate_h *value)
+    int name, rpc_port_delegate_h *value)
 {
   rpc_port_unit_h unit;
   rpc_port_delegate_h delegate;
@@ -444,19 +573,19 @@ static void rpc_port_unit_map_read_delegate(rpc_port_unit_map_h unit_map,
   if (delegate == nullptr)
     return;
 
-  if (unit_map == nullptr || name == nullptr) {
+  if (unit_map == nullptr) {
      _E("Invalid parameter");
     return;
   }
 
-  unit = g_hash_table_lookup(unit_map->table, name);
+  unit = g_hash_table_lookup(unit_map->table, GINT_TO_POINTER(name));
   if (unit == nullptr) {
-    _E("g_hash_table_lookup() is failed. name: %s", name);
+    _E("g_hash_table_lookup() is failed. name: %d", name);
     return;
   }
 
-  if (strcmp(unit->type, "delegate") != 0) {
-    _E("type(%s) is not delegate", unit->type);
+  if (unit->type != <HASH_DELEGATE> /*delegate*/) {
+    _E("type(%d) is not delegate", unit->type);
     return;
   }
 
@@ -467,7 +596,7 @@ static void rpc_port_unit_map_read_delegate(rpc_port_unit_map_h unit_map,
 constexpr const char CB_UNIT_MAP_BUNDLE_READ[] =
 R"__c_cb(
 static void rpc_port_unit_map_read_bundle(rpc_port_unit_map_h unit_map,
-    const char *name, bundle **value)
+    int name, bundle **value)
 {
   rpc_port_unit_h unit;
 
@@ -476,21 +605,21 @@ static void rpc_port_unit_map_read_bundle(rpc_port_unit_map_h unit_map,
     return;
   }
 
-  if (unit_map == nullptr || name == nullptr) {
+  if (unit_map == nullptr) {
     *value = bundle_create();
     _E("Invalid parameter");
     return;
   }
 
-  unit = g_hash_table_lookup(unit_map->table, name);
+  unit = g_hash_table_lookup(unit_map->table, GINT_TO_POINTER(name));
   if (unit == nullptr) {
-    _E("g_hash_table_lookup() is failed. name: %s", name);
+    _E("g_hash_table_lookup() is failed. name: %d", name);
     *value = bundle_create();
     return;
   }
 
-  if (strcmp(unit->type, "bundle") != 0) {
-    _E("type(%s) is not bundle", unit->type);
+  if (unit->type != <HASH_BUNDLE> /*bundle*/) {
+    _E("type(%d) is not bundle", unit->type);
     *value = bundle_create();
     return;
   }
@@ -502,7 +631,7 @@ static void rpc_port_unit_map_read_bundle(rpc_port_unit_map_h unit_map,
 constexpr const char CB_UNIT_MAP_STRING_READ[] =
 R"__c_cb(
 static void rpc_port_unit_map_read_string(rpc_port_unit_map_h unit_map,
-    const char *name, char **value)
+    int name, char **value)
 {
   rpc_port_unit_h unit;
 
@@ -511,21 +640,56 @@ static void rpc_port_unit_map_read_string(rpc_port_unit_map_h unit_map,
     return;
   }
 
-  if (unit_map == nullptr || name == nullptr) {
+  if (unit_map == nullptr) {
     *value = strdup("");
     _E("Invalid parameter");
     return;
   }
 
-  unit = g_hash_table_lookup(unit_map->table, name);
+  unit = g_hash_table_lookup(unit_map->table, GINT_TO_POINTER(name));
   if (unit == nullptr) {
-    _E("g_hash_table_lookup() is failed. name: %s", name);
+    _E("g_hash_table_lookup() is failed. name: %d", name);
     *value = strdup("");
     return;
   }
 
-  if (strcmp(unit->type, "string") != 0) {
-    _E("type(%s) is not string", unit->type);
+  if (unit->type != <HASH_STRING> /*string*/) {
+    _E("type(%d) is not string", unit->type);
+    *value = strdup("");
+    return;
+  }
+
+  rpc_port_parcel_read_string(unit->parcel, value);
+}
+)__c_cb";
+
+constexpr const char CB_UNIT_MAP_FILE_READ[] =
+R"__c_cb(
+static void rpc_port_unit_map_read_file(rpc_port_unit_map_h unit_map,
+    int name, char **value)
+{
+  rpc_port_unit_h unit;
+
+  if (value == nullptr) {
+    _E("Invalid parameter");
+    return;
+  }
+
+  if (unit_map == nullptr) {
+    *value = strdup("");
+    _E("Invalid parameter");
+    return;
+  }
+
+  unit = g_hash_table_lookup(unit_map->table, GINT_TO_POINTER(name));
+  if (unit == nullptr) {
+    _E("g_hash_table_lookup() is failed. name: %d", name);
+    *value = strdup("");
+    return;
+  }
+
+  if (unit->type != <HASH_FILE> /*file*/) {
+    _E("type(%d) is not string", unit->type);
     *value = strdup("");
     return;
   }
@@ -542,7 +706,7 @@ static void rpc_port_unit_map_read_string(rpc_port_unit_map_h unit_map,
 constexpr const char CB_UNIT_MAP_BASE_READ[] =
 R"__c_cb(
 static void rpc_port_unit_map_read_<TYPE_NAME>(rpc_port_unit_map_h unit_map,
-    const char *name, <PARAM_TYPE>value)
+    int name, <PARAM_TYPE>value)
 {
   rpc_port_unit_h unit;
 
@@ -551,21 +715,21 @@ static void rpc_port_unit_map_read_<TYPE_NAME>(rpc_port_unit_map_h unit_map,
     return;
   }
 
-  if (unit_map == nullptr || name == nullptr) {
+  if (unit_map == nullptr) {
     *value = 0;
     _E("Invalid parameter");
     return;
   }
 
-  unit = g_hash_table_lookup(unit_map->table, name);
+  unit = g_hash_table_lookup(unit_map->table, GINT_TO_POINTER(name));
   if (unit == nullptr) {
-    _E("g_hash_table_lookup() is failed. name: %s", name);
+    _E("g_hash_table_lookup() is failed. name: %d", name);
     *value = 0;
     return;
   }
 
-  if (strcmp(unit->type, "<TYPE_NAME>") != 0) {
-    _E("type(%s) is not <TYPE_NAME>", unit->type);
+  if (unit->type != <HASH_TYPE_NAME> /*<TYPE_NAME>*/) {
+    _E("type(%d) is not <TYPE_NAME>", unit->type);
     *value = 0;
     return;
   }
@@ -599,7 +763,6 @@ R"__c_cb(
 static void __<PREFIX>_<NAME>_to(rpc_port_parcel_h parcel, void *data)
 {
   <PREFIX>_<NAME>_t *handle = data;
-  rpc_port_unit_map_h map;
 
   if (parcel == nullptr || handle == nullptr) {
     _E("Invalid parameter");
@@ -607,23 +770,21 @@ static void __<PREFIX>_<NAME>_to(rpc_port_parcel_h parcel, void *data)
     return;
   }
 
-  map = rpc_port_unit_map_create();
-  if (map == nullptr) {
-    set_last_result(RPC_PORT_ERROR_OUT_OF_MEMORY);
-    return;
-  }
-
-  <UNIT_MAP_WRITE>
+  <TO_ELEMENTS*>
+  <IS_VALUE_TYPE?>
+  rpc_port_parcel_write_<PARCEL_TYPE>(parcel, handle-><ELEMENT_NAME>);
+  </IS_VALUE_TYPE?>
+  <IS_PTR_TYPE?>
+  rpc_port_parcel_write(parcel, &handle-><ELEMENT_NAME>->parcelable, handle-><ELEMENT_NAME>);
+  </IS_PTR_TYPE?>
+  </TO_ELEMENTS*>
 
-  rpc_port_parcel_write(parcel, &map->parcelable, map);
-  rpc_port_unit_map_destroy(map);
   set_last_result(RPC_PORT_ERROR_NONE);
 }
 
 static void __<PREFIX>_<NAME>_from(rpc_port_parcel_h parcel, void *data)
 {
   <PREFIX>_<NAME>_t *handle = data;
-  rpc_port_unit_map_h map;
 
   if (parcel == nullptr || handle == nullptr) {
     _E("Invalid parameter");
@@ -631,17 +792,15 @@ static void __<PREFIX>_<NAME>_from(rpc_port_parcel_h parcel, void *data)
     return;
   }
 
-  map = rpc_port_unit_map_create();
-  if (map == nullptr) {
-    set_last_result(RPC_PORT_ERROR_OUT_OF_MEMORY);
-    return;
-  }
-
-  rpc_port_parcel_read(parcel, &map->parcelable, map);
+  <FROM_ELEMENTS*>
+  <IS_VALUE_TYPE?>
+  rpc_port_parcel_read_<PARCEL_TYPE>(parcel, <IS_ENUM?>(int*)</IS_ENUM?>&handle-><ELEMENT_NAME>);
+  </IS_VALUE_TYPE?>
+  <IS_PTR_TYPE?>
+  rpc_port_parcel_read(parcel, &handle-><ELEMENT_NAME>->parcelable, &handle-><ELEMENT_NAME>);
+  </IS_PTR_TYPE?>
+  </FROM_ELEMENTS*>
 
-  <UNIT_MAP_READ>
-
-  rpc_port_unit_map_destroy(map);
   set_last_result(RPC_PORT_ERROR_NONE);
 }
 
@@ -686,32 +845,42 @@ int <PREFIX>_<NAME>_destroy(<PREFIX>_<NAME>_h h)
 
 int <PREFIX>_<NAME>_clone(<PREFIX>_<NAME>_h h, <PREFIX>_<NAME>_h *clone)
 {
-  <PREFIX>_<NAME>_t *handle = h;
-  rpc_port_unit_map_h map;
+  <PREFIX>_<NAME>_h handle;
+  rpc_port_parcel_h parcel;
   int ret;
 
-  if (handle == nullptr || clone == nullptr) {
+  if (h == nullptr || clone == nullptr) {
     _E("Invalid parameter");
     return RPC_PORT_ERROR_INVALID_PARAMETER;
   }
 
-  map = rpc_port_unit_map_create();
-  if (map == nullptr) {
-    _E("Failed to create unit map");
-    return RPC_PORT_ERROR_OUT_OF_MEMORY;
+  ret = <PREFIX>_<NAME>_create(&handle);
+  if (ret != RPC_PORT_ERROR_NONE) {
+    _E("Failed to create handle. error(%d)", ret);
+    return ret;
   }
 
-  ret = rpc_port_unit_map_write_<NAME>(map, "clone", handle);
+  ret = rpc_port_parcel_create(&parcel);
   if (ret != RPC_PORT_ERROR_NONE) {
-    _E("Failed to write <NAME>. error(%d)", ret);
-    rpc_port_unit_map_destroy(map);
+    _E("Failed to create parcel handle. error(%d)", ret);
+    <PREFIX>_<NAME>_destroy(handle);
     return ret;
   }
 
-  rpc_port_unit_map_read_<NAME>(map, "clone", clone);
-  rpc_port_unit_map_destroy(map);
+  rpc_port_parcel_write(parcel, &h->parcelable, h);
+  rpc_port_parcel_read(parcel, &handle->parcelable, handle);
+  ret = get_last_result();
+  rpc_port_parcel_destroy(parcel);
 
-  return ret;
+  if (ret != RPC_PORT_ERROR_NONE) {
+    _E("Failed to read data. error(%d)", ret);
+    <PREFIX>_<NAME>_destroy(handle);
+    return ret;
+  }
+
+  *clone = handle;
+
+  return RPC_PORT_ERROR_NONE;
 }
 )__c_cb";
 
@@ -726,15 +895,13 @@ int <PREFIX>_<NAME>_clone(<PREFIX>_<NAME>_h h, <PREFIX>_<NAME>_h *clone)
  */
 constexpr const char CB_STRUCTURE_BASE_SET_GET[] =
 R"__c_cb(
-int <PREFIX>_<NAME>_set_<ELEMENT_NAME>(<PREFIX>_<NAME>_h h, <PARAM_TYPE_IN>value)
+int <PREFIX>_<NAME>_set_<ELEMENT_NAME>(<PREFIX>_<NAME>_h handle, <PARAM_TYPE_IN>value)
 {
-  <PREFIX>_<NAME>_t *handle = h;
   <BASE_SET>
 }
 
-int <PREFIX>_<NAME>_get_<ELEMENT_NAME>(<PREFIX>_<NAME>_h h, <PARAM_TYPE_OUT>value)
+int <PREFIX>_<NAME>_get_<ELEMENT_NAME>(<PREFIX>_<NAME>_h handle, <PARAM_TYPE_OUT>value)
 {
-  <PREFIX>_<NAME>_t *handle = h;
   <BASE_GET>
 }
 )__c_cb";
@@ -745,7 +912,7 @@ int <PREFIX>_<NAME>_get_<ELEMENT_NAME>(<PREFIX>_<NAME>_h h, <PARAM_TYPE_OUT>valu
  */
 constexpr const char CB_STRUCTURE_BASE_UNIT_MAP_WRITE[] =
 R"__c_cb(
-rpc_port_unit_map_write_<ELEMENT_TYPE>(map, "<ELEMENT_NAME>", handle-><ELEMENT_NAME>);
+rpc_port_unit_map_write_<ELEMENT_TYPE>(map, <HASH_ELEMENT_NAME> /*<ELEMENT_NAME>*/, handle-><ELEMENT_NAME>);
 )__c_cb";
 
 /**
@@ -753,7 +920,7 @@ rpc_port_unit_map_write_<ELEMENT_TYPE>(map, "<ELEMENT_NAME>", handle-><ELEMENT_N
  */
 constexpr const char CB_STRUCTURE_ENUM_UNIT_MAP_WRITE[] =
 R"__c_cb(
-rpc_port_unit_map_write_int(map, "<ELEMENT_NAME>", (int)handle-><ELEMENT_NAME>);
+rpc_port_unit_map_write_int(map, <HASH_ELEMENT_NAME> /*<ELEMENT_NAME>*/, (int)handle-><ELEMENT_NAME>);
 )__c_cb";
 
 /**
@@ -762,7 +929,7 @@ rpc_port_unit_map_write_int(map, "<ELEMENT_NAME>", (int)handle-><ELEMENT_NAME>);
  */
 constexpr const char CB_STRUCTURE_BASE_UNIT_MAP_READ[] =
 R"__c_cb(
-rpc_port_unit_map_read_<ELEMENT_TYPE>(map, "<ELEMENT_NAME>", &handle-><ELEMENT_NAME>);
+rpc_port_unit_map_read_<ELEMENT_TYPE>(map, <HASH_ELEMENT_NAME> /*<ELEMENT_NAME>*/, &handle-><ELEMENT_NAME>);
 )__c_cb";
 
 /**
@@ -771,7 +938,7 @@ rpc_port_unit_map_read_<ELEMENT_TYPE>(map, "<ELEMENT_NAME>", &handle-><ELEMENT_N
  */
 constexpr const char CB_STRUCTURE_ENUM_UNIT_MAP_READ[] =
 R"__c_cb(
-rpc_port_unit_map_read_int(map, "<ELEMENT_NAME>", (int *)&handle-><ELEMENT_NAME>);
+rpc_port_unit_map_read_int(map, <HASH_ELEMENT_NAME> /*<ELEMENT_NAME>*/, (int *)&handle-><ELEMENT_NAME>);
 )__c_cb";
 
 /**
@@ -1051,7 +1218,7 @@ typedef struct <PREFIX>_remote_exception_s {
   char *message;
 } <PREFIX>_remote_exception_t;
 
-static __thread <PREFIX>_remote_exception_h __<PREFIX>_remote_exception;
+static <PREFIX>_remote_exception_h __<PREFIX>_remote_exception;
 
 int <PREFIX>_remote_exception_create(<PREFIX>_remote_exception_h *h);
 )__c_cb";
@@ -1064,36 +1231,20 @@ R"__c_cb(
 static void __<PREFIX>_remote_exception_to(rpc_port_parcel_h parcel, void *user_data)
 {
   <PREFIX>_remote_exception_h h = user_data;
-  rpc_port_unit_map_h map;
 
-  map = rpc_port_unit_map_create();
-  if (map == nullptr) {
-    set_last_result(RPC_PORT_ERROR_OUT_OF_MEMORY);
-    return;
-  }
+  rpc_port_parcel_write_int32(parcel, h->cause);
+  rpc_port_parcel_write_string(parcel, h->message);
 
-  rpc_port_unit_map_write_int(map, "cause", h->cause);
-  rpc_port_unit_map_write_string(map, "message", h->message);
-  rpc_port_parcel_write(parcel, &map->parcelable, map);
-  rpc_port_unit_map_destroy(map);
   set_last_result(RPC_PORT_ERROR_NONE);
 }
 
 static void __<PREFIX>_remote_exception_from(rpc_port_parcel_h parcel, void *user_data)
 {
   <PREFIX>_remote_exception_h h = user_data;
-  rpc_port_unit_map_h map;
 
-  map = rpc_port_unit_map_create();
-  if (map == nullptr) {
-    set_last_result(RPC_PORT_ERROR_OUT_OF_MEMORY);
-    return;
-  }
+  rpc_port_parcel_read_int32(parcel,  &h->cause);
+  rpc_port_parcel_read_string(parcel, &h->message);
 
-  rpc_port_parcel_read(parcel, &map->parcelable, map);
-  rpc_port_unit_map_read_int(map, "cause", &h->cause);
-  rpc_port_unit_map_read_string(map, "message", &h->message);
-  rpc_port_unit_map_destroy(map);
   set_last_result(RPC_PORT_ERROR_NONE);
 }
 
@@ -1202,7 +1353,7 @@ constexpr const char CB_PROXY_REMOTE_EXCEPTION_BASE[] =
 R"__cpp_cb(
 int <PREFIX>_get_remote_exception(<PREFIX>_remote_exception_h *h)
 {
-  rpc_port_unit_map_h map;
+  <PREFIX>_remote_exception_h handle;
   int ret;
 
   if (h == nullptr) {
@@ -1216,21 +1367,16 @@ int <PREFIX>_get_remote_exception(<PREFIX>_remote_exception_h *h)
     return RPC_PORT_ERROR_NONE;
   }
 
-  map = rpc_port_unit_map_create();
-  if (map == nullptr) {
-    _E("Failed to create unit map");
-    return RPC_PORT_ERROR_OUT_OF_MEMORY;
-  }
-
-  ret = rpc_port_unit_map_write_remote_exception(map, "clone", __<PREFIX>_remote_exception);
+  ret = <PREFIX>_remote_exception_create(&handle);
   if (ret != RPC_PORT_ERROR_NONE) {
-    _E("Failed to write remote exception. error(%d)", ret);
-    rpc_port_unit_map_destroy(map);
-    return ret;
+    _E("Failed to create remote exception");
+    return RPC_PORT_ERROR_OUT_OF_MEMORY;
   }
 
-  rpc_port_unit_map_read_remote_exception(map, "clone", h);
-  rpc_port_unit_map_destroy(map);
+  handle->cause = __<PREFIX>_remote_exception->cause;
+  handle->message = __<PREFIX>_remote_exception->message ?
+      strdup(__<PREFIX>_remote_exception->message) : nullptr;
+  *h = handle;
 
   return RPC_PORT_ERROR_NONE;
 }
@@ -1240,7 +1386,7 @@ constexpr const char CB_STUB_REMOTE_EXCEPTION_BASE[] =
 R"__cpp_cb(
 int <PREFIX>_remote_exception_throw(<PREFIX>_remote_exception_h h)
 {
-  rpc_port_unit_map_h map;
+  <PREFIX>_remote_exception_h handle;
   int ret;
 
   if (h == nullptr) {
@@ -1248,17 +1394,10 @@ int <PREFIX>_remote_exception_throw(<PREFIX>_remote_exception_h h)
     return RPC_PORT_ERROR_INVALID_PARAMETER;
   }
 
-   map = rpc_port_unit_map_create();
-  if (map == nullptr) {
-    _E("Failed to create unit map");
-    return RPC_PORT_ERROR_OUT_OF_MEMORY;
-  }
-
-  ret = rpc_port_unit_map_write_remote_exception(map, "clone", h);
+  ret = <PREFIX>_remote_exception_create(&handle);
   if (ret != RPC_PORT_ERROR_NONE) {
-    _E("Failed to write remote exception. error(%d)", ret);
-    rpc_port_unit_map_destroy(map);
-    return ret;
+    _E("Failed to create remote exception");
+    return RPC_PORT_ERROR_OUT_OF_MEMORY;
   }
 
   if (__<PREFIX>_remote_exception != nullptr) {
@@ -1266,13 +1405,98 @@ int <PREFIX>_remote_exception_throw(<PREFIX>_remote_exception_h h)
     __<PREFIX>_remote_exception = nullptr;
   }
 
-  rpc_port_unit_map_read_remote_exception(map, "clone", &__<PREFIX>_remote_exception);
-  rpc_port_unit_map_destroy(map);
+  handle->cause = h->cause;
+  handle->message = h->message ? strdup(h->message) : nullptr;
+  __<PREFIX>_remote_exception = handle;
 
   return ret;
 }
 )__cpp_cb";
 
+constexpr const char CB_RPC_PORT_INTERNAL_APIS[] =
+R"__cpp_cb(
+
+typedef int (*rpc_port_parcel_reserve_t)(rpc_port_parcel_h h, unsigned int size);
+typedef int (*rpc_port_parcel_create_from_parcel_t)(rpc_port_parcel_h* h,
+                                                    rpc_port_parcel_h origin_parcel,
+                                                    unsigned int start_pos,
+                                                    unsigned int size);
+typedef int (*rpc_port_parcel_set_data_size_t)(rpc_port_parcel_h h, unsigned int size);
+typedef int (*rpc_port_parcel_get_data_size_t)(rpc_port_parcel_h h, unsigned int* size);
+typedef int (*rpc_port_parcel_pin_t)(rpc_port_parcel_h h);
+typedef int (*rpc_port_parcel_get_reader_t)(rpc_port_parcel_h h, unsigned int* reader_pos);
+typedef int (*rpc_port_parcel_set_reader_t)(rpc_port_parcel_h h, unsigned int reader_pos);
+
+static rpc_port_parcel_reserve_t rpc_port_parcel_reserve;
+static rpc_port_parcel_create_from_parcel_t rpc_port_parcel_create_from_parcel;
+static rpc_port_parcel_set_data_size_t rpc_port_parcel_set_data_size;
+static rpc_port_parcel_get_data_size_t rpc_port_parcel_get_data_size;
+static rpc_port_parcel_pin_t rpc_port_parcel_pin;
+static rpc_port_parcel_get_reader_t rpc_port_parcel_get_reader;
+static rpc_port_parcel_set_reader_t rpc_port_parcel_set_reader;
+static bool rpc_port_internal_loaded;
+
+static void rpc_port_internal_init(void)
+{
+    const char *symbol = "rpc_port_parcel_reserve";
+
+    if (rpc_port_internal_loaded)
+      return;
+
+    rpc_port_parcel_reserve = dlsym(RTLD_DEFAULT, symbol);
+    if (rpc_port_parcel_reserve == nullptr) {
+      _E("Failed to find symbol(%s). Please check rpc-port version", symbol);
+      return;
+    }
+
+    symbol = "rpc_port_parcel_create_from_parcel";
+    rpc_port_parcel_create_from_parcel = dlsym(RTLD_DEFAULT, symbol);
+    if (rpc_port_parcel_create_from_parcel == nullptr) {
+      _E("Failed to find symbol(%s). Please check rpc-port version", symbol);
+      return;
+    }
+
+    symbol = "rpc_port_parcel_set_data_size";
+    rpc_port_parcel_set_data_size = dlsym(RTLD_DEFAULT, symbol);
+    if (rpc_port_parcel_set_data_size == nullptr) {
+      _E("Failed to find symbol(%s). Please check rpc-port version", symbol);
+      return;
+    }
+
+    symbol = "rpc_port_parcel_get_data_size";
+    rpc_port_parcel_get_data_size = dlsym(RTLD_DEFAULT, symbol);
+    if (rpc_port_parcel_get_data_size == nullptr) {
+      _E("Failed to find symbol(%s). Please check rpc-port version", symbol);
+      return;
+    }
+
+    symbol = "rpc_port_parcel_pin";
+    rpc_port_parcel_pin = dlsym(RTLD_DEFAULT, symbol);
+    if (rpc_port_parcel_pin == nullptr) {
+      _E("Failed to find symbol(%s). Please check rpc-port version", symbol);
+      return;
+    }
+
+    symbol = "rpc_port_parcel_get_reader";
+    rpc_port_parcel_get_reader = dlsym(RTLD_DEFAULT, symbol);
+    if (rpc_port_parcel_get_reader == nullptr) {
+      _E("Failed to find symbol(%s). Please check rpc-port version", symbol);
+      return;
+    }
+
+    symbol = "rpc_port_parcel_set_reader";
+    rpc_port_parcel_set_reader = dlsym(RTLD_DEFAULT, symbol);
+    if (rpc_port_parcel_set_reader == nullptr) {
+      _E("Failed to find symbol(%s). Please check rpc-port version", symbol);
+      return;
+    }
+
+    rpc_port_internal_loaded = true;
+}
+
+)__cpp_cb";
+
+
 }  // namespace version2
 }  // namespace tidl
 
index 2b0e219ac2788ed9b74f2bd210f18f3fda59eca3..94c8f63d1d5e934dc1fd015bf04b21f1f0e1595d 100644 (file)
@@ -48,10 +48,7 @@ R"__c_cb(
 static void __<PREFIX>_<NAME>_to(rpc_port_parcel_h parcel, void *data)
 {
   <PREFIX>_<NAME>_t *handle = data;
-  rpc_port_unit_map_h map;
   <DATA_TYPE>value;
-  char index[12];
-  int i;
   GList *iter;
 
   if (parcel == nullptr || handle == nullptr) {
@@ -60,35 +57,36 @@ static void __<PREFIX>_<NAME>_to(rpc_port_parcel_h parcel, void *data)
     return;
   }
 
-  map = rpc_port_unit_map_create();
-  if (map == nullptr) {
-    _E("Failed to create unit map");
-    set_last_result(RPC_PORT_ERROR_OUT_OF_MEMORY);
-    return;
-  }
-
-  rpc_port_unit_map_write_int(map, "length", g_list_length(handle->list));
+  rpc_port_parcel_write_array_count(parcel, g_list_length(handle->list));
 
-  i = 0;
   iter = handle->list;
   while (iter) {
     value = iter->data;
     iter = g_list_next(iter);
-    snprintf(index, sizeof(index), "%d", i++);
-    <UNIT_MAP_WRITE>
+
+    <IS_BUNDLE_TYPE?>
+    rpc_port_parcel_write_bundle(parcel, value);
+    </IS_BUNDLE_TYPE?>
+
+    <IS_STRING_TYPE?>
+    rpc_port_parcel_write_string(parcel, STRING_GET(value));
+    </IS_STRING_TYPE?>
+
+    <IS_DEFAULT_TYPE?>
+    rpc_port_parcel_write_<PARCEL_TYPE>(parcel, *value);
+    </IS_DEFAULT_TYPE?>
+
+    <IS_PARCELABLE_TYPE?>
+    rpc_port_parcel_write(parcel, &value->parcelable, value);
+    </IS_PARCELABLE_TYPE?>
   }
 
-  rpc_port_parcel_write(parcel, &map->parcelable, map);
-  rpc_port_unit_map_destroy(map);
   set_last_result(RPC_PORT_ERROR_NONE);
 }
 
 static void __<PREFIX>_<NAME>_from(rpc_port_parcel_h parcel, void *data)
 {
   <PREFIX>_<NAME>_t *handle = data;
-  <DATA_TYPE>value = nullptr;
-  rpc_port_unit_map_h map;
-  char index[12];
   int len = 0;
   int i;
 
@@ -98,23 +96,48 @@ static void __<PREFIX>_<NAME>_from(rpc_port_parcel_h parcel, void *data)
     return;
   }
 
-  map = rpc_port_unit_map_create();
-  if (map == nullptr) {
-    _E("Failed to create unit map");
-    set_last_result(RPC_PORT_ERROR_OUT_OF_MEMORY);
-    return;
-  }
-
-  rpc_port_parcel_read(parcel, &map->parcelable, map);
-
-  rpc_port_unit_map_read_int(map, "length", &len);
-
+  rpc_port_parcel_read_array_count(parcel, &len);
   for (i = 0; i < len; ++i) {
-    snprintf(index, sizeof(index), "%d", i);
-    <UNIT_MAP_READ>
+    <IS_BUNDLE_TYPE?>
+    bundle* value;
+    rpc_port_parcel_read_bundle(parcel, &value);
+    </IS_BUNDLE_TYPE?>
+
+    <IS_STRING_TYPE?>
+    char* value;
+    rpc_port_parcel_read_string(parcel, &value);
+    </IS_STRING_TYPE?>
+
+    <IS_DEFAULT_TYPE?>
+    <DATA_TYPE>value = nullptr;
+    value = calloc(1, sizeof(<DATA_TYPE_WITHOUT_POINTER>));
+    if (value == nullptr) {
+      _E("Out of memory");
+      set_last_result(RPC_PORT_ERROR_OUT_OF_MEMORY);
+      return;
+    }
+    rpc_port_parcel_read_<PARCEL_TYPE>(parcel, <IS_ENUM?>(int*)</IS_ENUM?>value);
+    </IS_DEFAULT_TYPE?>
+
+    <IS_PARCELABLE_TYPE?>
+    <PREFIX>_<NAME>_h value;
+    int ret = <PREFIX>_<NAME>_create(&value);
+    if (ret != RPC_PORT_ERROR_NONE) {
+      _E("Failed to create handle. error(%d)", ret);
+      set_last_result(ret);
+      return;
+    }
+
+    rpc_port_parcel_read(parcel, &value->parcelable, value);
+    if (get_last_result() != RPC_PORT_ERROR_NONE) {
+      _E("Failed to read data. error(%d)", get_last_result());
+      <PREFIX>_<NAME>_destroy(value);
+      return;
+    }
+    </IS_PARCELABLE_TYPE?>
+    handle->list = g_list_append(handle->list, value);
   }
 
-  rpc_port_unit_map_destroy(map);
   set_last_result(RPC_PORT_ERROR_NONE);
 }
 
@@ -170,32 +193,42 @@ int <PREFIX>_<NAME>_destroy(<PREFIX>_<NAME>_h h)
 
 int <PREFIX>_<NAME>_clone(<PREFIX>_<NAME>_h h, <PREFIX>_<NAME>_h *clone)
 {
-  <PREFIX>_<NAME>_t *handle = h;
-  rpc_port_unit_map_h map;
+  <PREFIX>_<NAME>_h handle;
+  rpc_port_parcel_h parcel;
   int ret;
 
-  if (handle == nullptr || clone == nullptr) {
+  if (h == nullptr || clone == nullptr) {
     _E("Invalid parameter");
     return RPC_PORT_ERROR_INVALID_PARAMETER;
   }
 
-  map = rpc_port_unit_map_create();
-  if (map == nullptr) {
-    _E("Failed to create unit map");
-    return RPC_PORT_ERROR_OUT_OF_MEMORY;
+  ret = <PREFIX>_<NAME>_create(&handle);
+  if (ret != RPC_PORT_ERROR_NONE) {
+    _E("Failed to create handle. error(%d)", ret);
+    return ret;
   }
 
-  ret = rpc_port_unit_map_write_<NAME>(map, "clone", handle);
+  ret = rpc_port_parcel_create(&parcel);
   if (ret != RPC_PORT_ERROR_NONE) {
-    _E("Failed to write <NAME>. error(%d)", ret);
-    rpc_port_unit_map_destroy(map);
+    _E("Failed to create parcel handle. error(%d)", ret);
+    <PREFIX>_<NAME>_destroy(handle);
     return ret;
   }
 
-  rpc_port_unit_map_read_<NAME>(map, "clone", clone);
-  rpc_port_unit_map_destroy(map);
+  rpc_port_parcel_write(parcel, &h->parcelable, h);
+  rpc_port_parcel_read(parcel, &handle->parcelable, handle);
+  ret = get_last_result();
+  rpc_port_parcel_destroy(parcel);
 
-  return ret;
+  if (ret != RPC_PORT_ERROR_NONE) {
+    _E("Failed to read data. error(%d)", ret);
+    <PREFIX>_<NAME>_destroy(handle);
+    return ret;
+  }
+
+  *clone = handle;
+
+  return RPC_PORT_ERROR_NONE;
 }
 
 int <PREFIX>_<NAME>_add(<PREFIX>_<NAME>_h h, <PARAM_TYPE_IN>value)
@@ -269,22 +302,22 @@ int <PREFIX>_<NAME>_length(<PREFIX>_<NAME>_h h, unsigned int *length)
  */
 constexpr const char CB_STRUCTURE_LIST_USER_DEFINED_UNIT_MAP_WRITE[] =
 R"__c_cb(
-rpc_port_unit_map_write_<TYPE_NAME>(map, index, value);
+rpc_port_parcel_write(parcel, &value->parcelable, value);
 )__c_cb";
 
 constexpr const char CB_STRUCTURE_LIST_ENUM_UNIT_MAP_WRITE[] =
 R"__c_cb(
-rpc_port_unit_map_write_int(map, index, (int)value);
+rpc_port_parcel_write_int32(parcel, (int)value);
 )__c_cb";
 
 constexpr const char CB_STRUCTURE_LIST_BUNDLE_UNIT_MAP_WRITE[] =
 R"__c_cb(
-rpc_port_unit_map_write_bundle(map, index, value);
+rpc_port_parcel_write_bundle(parcel, value);
 )__c_cb";
 
 constexpr const char CB_STRUCTURE_LIST_STRING_UNIT_MAP_WRITE[] =
 R"__c_cb(
-rpc_port_unit_map_write_string(parcel, index, STRING_GET(value));
+rpc_port_parcel_write_string(parcel, STRING_GET(value));
 )__c_cb";
 
 /**
@@ -292,7 +325,7 @@ rpc_port_unit_map_write_string(parcel, index, STRING_GET(value));
  */
 constexpr const char CB_STRUCTURE_LIST_BASE_UNIT_MAP_WRITE[] =
 R"__c_cb(
-rpc_port_unit_map_write_<TYPE_NAME>(parcel, index, *value);
+rpc_port_parcel_write_<PARCEL_TYPE>(parcel, *value);
 )__c_cb";
 
 /**
@@ -300,37 +333,52 @@ rpc_port_unit_map_write_<TYPE_NAME>(parcel, index, *value);
  */
 constexpr const char CB_STRUCTURE_LIST_USER_DEFINED_UNIT_MAP_READ[] =
 R"__c_cb(
-value = nullptr;
-rpc_port_unit_map_read_<TYPE_NAME>(map, index, &value);
+ret = <PREFIX>_<NAME>_create(&value);
+if (ret != RPC_PORT_ERROR_NONE) {
+  _E("Failed to create handle. error(%d)", ret);
+  set_last_result(ret);
+  return;
+}
+
+rpc_port_parcel_read(parcel, &value->parcelable, value);
+if (get_last_result() != RPC_PORT_ERROR_NONE) {
+  _E("Failed to read data. error(%d)", get_last_result());
+  <PREFIX>_<NAME>_destroy(value);
+  return;
+}
+
 handle->list = g_list_append(handle->list, value);
 )__c_cb";
 
 constexpr const char CB_STRUCTURE_LIST_ENUM_UNIT_MAP_READ[] =
 R"__c_cb(
-value = calloc(1, sizeof(sizeof(<VALUE_TYPE>)));
+rpc_port_parcel_read_i32(parcel, (int*)&value);
+)__c_cb";
+
+constexpr const char CB_STRUCTURE_LIST_BUNDLE_UNIT_MAP_READ[] =
+R"__c_cb(
+rpc_port_parcel_read_bundle(parcel, &value);
 if (value == nullptr) {
-  _E("Out of memory");
-  rpc_port_unit_map_destroy(map);
+  _E("Failed to read data");
   set_last_result(RPC_PORT_ERROR_OUT_OF_MEMORY);
   return;
 }
 
-rpc_port_unit_map_read_int(map, index, (int*)&value);
 handle->list = g_list_append(handle->list, value);
-)__c_cb";
-
-constexpr const char CB_STRUCTURE_LIST_BUNDLE_UNIT_MAP_READ[] =
-R"__c_cb(
 value = nullptr;
-rpc_port_unit_map_read_bundle(map, index, &value);
-handle->list = g_list_append(handle->list, value);
 )__c_cb";
 
 constexpr const char CB_STRUCTURE_LIST_STRING_UNIT_MAP_READ[] =
 R"__c_cb(
-value = nullptr;
-rpc_port_unit_map_read_string(map, index, &value);
+rpc_port_parcel_read_string(parcel, &value);
+if (value == nullptr) {
+  _E("Failed to read data");
+  set_last_result(RPC_PORT_ERROR_OUT_OF_MEMORY);
+  return;
+}
+
 handle->list = g_list_append(handle->list, value);
+value = nullptr;
 )__c_cb";
 
 /**
@@ -342,12 +390,11 @@ R"__c_cb(
 value = calloc(1, sizeof(sizeof(<VALUE_TYPE>)));
 if (value == nullptr) {
   _E("Out of memory");
-  rpc_port_unit_map_destroy(map);
   set_last_result(RPC_PORT_ERROR_OUT_OF_MEMORY);
   return;
 }
 
-rpc_port_unit_map_read_<TYPE_NAME>(map, index, value);
+rpc_port_parcel_read_<PARCEL_TYPE>(parcel, value);
 handle->list = g_list_append(handle->list, value);
 )__c_cb";
 
index 036cf378545de6cb767d426779e1d1e3821a6823..4cd27806d1b35f11564c8cc30a766f31cd94d493 100644 (file)
@@ -33,7 +33,7 @@ typedef struct <PREFIX>_<NAME>_s {
 } <PREFIX>_<NAME>_t;
 
 typedef struct <PREFIX>_<NAME>_traverse_info_s {
-  rpc_port_unit_map_h map;
+  rpc_port_parcel_h parcel;
   int number;
 } <PREFIX>_<NAME>_traverse_info_t;
 
@@ -76,13 +76,26 @@ R"__c_cb(
 static gboolean __<PREFIX>_<NAME>_traverse_cb(gpointer key, gpointer value, gpointer user_data)
 {
   <PREFIX>_<NAME>_traverse_info_t *info = user_data;
-  char name[32];
 
-  snprintf(name, sizeof(name), "key-%d", info->number);
-  <MAP_UNIT_MAP_KEY_WRITE>
-
-  snprintf(name, sizeof(name), "value-%d", info->number++);
-  <MAP_UNIT_MAP_VALUE_WRITE>
+  <IS_PTR?>
+  rpc_port_parcel_write_<PARCEL_TYPE_KEY>(info->parcel, (<KEY_TYPE>)key);
+  </IS_PTR?>
+  <IS_NOT_PTR?>
+  rpc_port_parcel_write_<PARCEL_TYPE_KEY>(info->parcel, *(<KEY_TYPE> *)key);
+  </IS_NOT_PTR?>
+
+  <IS_USER_DEFINED_TYPE?>
+  rpc_port_parcel_write(info->parcel, &(((<VALUE_TYPE>)value)->parcelable), value);
+  </IS_USER_DEFINED_TYPE?>
+  <IS_STRING_TYPE?>
+  rpc_port_parcel_write_string(info->parcel, STRING_GET(value));
+  </IS_STRING_TYPE?>
+  <IS_ENUM_TYPE?>
+  rpc_port_parcel_write_int32(info->parcel, *(int *)value);
+  </IS_ENUM_TYPE?>
+  <IS_VALUE_TYPE?>
+  rpc_port_parcel_write_<PARCEL_TYPE>(info->parcel, *(<VALUE_TYPE> *)value);
+  </IS_VALUE_TYPE?>
 
   return FALSE;
 }
@@ -91,7 +104,6 @@ static void __<PREFIX>_<NAME>_to(rpc_port_parcel_h parcel, void *data)
 {
   <PREFIX>_<NAME>_traverse_info_t info;
   <PREFIX>_<NAME>_t *handle = data;
-  rpc_port_unit_map_h map;
 
   if (parcel == nullptr || handle == nullptr) {
     _E("Invalid parameter");
@@ -99,21 +111,12 @@ static void __<PREFIX>_<NAME>_to(rpc_port_parcel_h parcel, void *data)
     return;
   }
 
-  map = rpc_port_unit_map_create();
-  if (map == nullptr) {
-    _E("Failed to create unit map");
-    set_last_result(RPC_PORT_ERROR_OUT_OF_MEMORY);
-    return;
-  }
-
-  rpc_port_unit_map_write_int(map, "size", g_tree_nnodes(handle->node));
+  rpc_port_parcel_write_array_count(parcel, g_tree_nnodes(handle->node));
 
-  info.map = map;
+  info.parcel = parcel;
   info.number = 0;
   g_tree_foreach(handle->node, __<PREFIX>_<NAME>_traverse_cb, &info);
 
-  rpc_port_parcel_write(parcel, &map->parcelable, map);
-  rpc_port_unit_map_destroy(map);
   set_last_result(RPC_PORT_ERROR_NONE);
 }
 
@@ -122,8 +125,6 @@ static void __<PREFIX>_<NAME>_from(rpc_port_parcel_h parcel, void *data)
   <PREFIX>_<NAME>_t *handle = data;
   <KEY_TYPE>key;
   <VALUE_TYPE>value;
-  rpc_port_unit_map_h map;
-  char name[32];
   int size = 0;
   int ret;
   int i;
@@ -134,32 +135,31 @@ static void __<PREFIX>_<NAME>_from(rpc_port_parcel_h parcel, void *data)
     return;
   }
 
-  map = rpc_port_unit_map_create();
-  if (map == nullptr) {
-    _E("Failed to create unit map");
-    set_last_result(RPC_PORT_ERROR_OUT_OF_MEMORY);
-    return;
-  }
-
-  rpc_port_parcel_read(parcel, &map->parcelable, map);
-
-  rpc_port_unit_map_read_int(map, "size", &size);
+  rpc_port_parcel_read_array_count(parcel, &size);
 
   for (i = 0; i < size; ++i) {
-    snprintf(name, sizeof(name), "key-%d", i);
-    <MAP_UNIT_MAP_KEY_READ>
-    snprintf(name, sizeof(name), "value-%d", i);
-    <MAP_UNIT_MAP_VALUE_READ>
+    rpc_port_parcel_read_<PARCEL_TYPE_KEY>(parcel, &key);
+
+    <IS_USER_DEFINED_TYPE?>
+    rpc_port_parcel_read(parcel, &value->parcelable, &value);
+    </IS_USER_DEFINED_TYPE?>
+    <IS_STRING_TYPE?>
+    rpc_port_parcel_read_string(parcel, &value);
+    </IS_STRING_TYPE?>
+    <IS_ENUM_TYPE?>
+    rpc_port_parcel_read_int32(parcel, (int*)&value);
+    </IS_ENUM_TYPE?>
+    <IS_VALUE_TYPE?>
+    rpc_port_parcel_read_<PARCEL_TYPE>(parcel, &value);
+    </IS_VALUE_TYPE?>
 
     ret = <PREFIX>_<NAME>_insert(handle, key, value);
     if (ret != RPC_PORT_ERROR_NONE) {
-      rpc_port_unit_map_destroy(map);
       set_last_result(ret);
       return;
     }
   }
 
-  rpc_port_unit_map_destroy(map);
   set_last_result(RPC_PORT_ERROR_NONE);
 }
 
@@ -219,32 +219,42 @@ int <PREFIX>_<NAME>_destroy(<PREFIX>_<NAME>_h h)
 
 int <PREFIX>_<NAME>_clone(<PREFIX>_<NAME>_h h, <PREFIX>_<NAME>_h *clone)
 {
-  <PREFIX>_<NAME>_t *handle = h;
-  rpc_port_unit_map_h map;
+  <PREFIX>_<NAME>_h handle;
+  rpc_port_parcel_h parcel;
   int ret;
 
-  if (handle == nullptr || clone == nullptr) {
+  if (h == nullptr || clone == nullptr) {
     _E("Invalid parameter");
     return RPC_PORT_ERROR_INVALID_PARAMETER;
   }
 
-  map = rpc_port_unit_map_create();
-  if (map == nullptr) {
-    _E("Failed to create unit map");
-    return RPC_PORT_ERROR_OUT_OF_MEMORY;
+  ret = <PREFIX>_<NAME>_create(&handle);
+  if (ret != RPC_PORT_ERROR_NONE) {
+    _E("Failed to create handle. error(%d)", ret);
+    return ret;
   }
 
-  ret = rpc_port_unit_map_write_<NAME>(map, "clone", handle);
+  ret = rpc_port_parcel_create(&parcel);
   if (ret != RPC_PORT_ERROR_NONE) {
-    _E("Failed to write <NAME>. error(%d)", ret);
-    rpc_port_unit_map_destroy(map);
+    _E("Failed to create parcel handle. error(%d)", ret);
+    <PREFIX>_<NAME>_destroy(handle);
     return ret;
   }
 
-  rpc_port_unit_map_read_<NAME>(map, "clone", clone);
-  rpc_port_unit_map_destroy(map);
+  rpc_port_parcel_write(parcel, &h->parcelable, h);
+  rpc_port_parcel_read(parcel, &handle->parcelable, handle);
+  ret = get_last_result();
+  rpc_port_parcel_destroy(parcel);
 
-  return ret;
+  if (ret != RPC_PORT_ERROR_NONE) {
+    _E("Failed to read data. error(%d)", ret);
+    <PREFIX>_<NAME>_destroy(handle);
+    return ret;
+  }
+
+  *clone = handle;
+
+  return RPC_PORT_ERROR_NONE;
 }
 
 int <PREFIX>_<NAME>_insert(<PREFIX>_<NAME>_h h, <KEY_PARAM_TYPE>key, <VALUE_PARAM_TYPE>value)
@@ -398,78 +408,6 @@ if (key_a == key_b)
 return -1;
 )__c_cb";
 
-/**
- * <KEY> The name of the key.
- * <KEY_TYPE> The type of the key.
- */
-constexpr const char CB_MAP_UNIT_MAP_KEY_WRITE_PTR_TYPE[] =
-R"__c_cb(
-rpc_port_unit_map_write_<KEY>(info->map, name, (<KEY_TYPE>)key);
-)__c_cb";
-
-/**
- * <KEY> The name of the key.
- * <KEY_TYPE> The pointer type of the key.
- */
-constexpr const char CB_MAP_UNIT_MAP_KEY_WRITE_BASE_TYPE[] =
-R"__c_cb(
-rpc_port_unit_map_write_<KEY>(info->map, name, *(<KEY_TYPE> *)key);
-)__c_cb";
-
-constexpr const char CB_MAP_UNIT_MAP_KEY_ENUM_BASE_TYPE[] =
-R"__c_cb(
-rpc_port_unit_map_write_int(info->map, name, *(int *)key);
-)__c_cb";
-
-/**
- * <VALUE> The name of the value.
- * <VALUE_TYPE> The type of the value.
- */
-constexpr const char CB_MAP_UNIT_MAP_VALUE_WRITE_PTR_TYPE[] =
-R"__c_cb(
-rpc_port_unit_map_write_<VALUE>(info->map, name, (<VALUE_TYPE>)value);
-)__c_cb";
-
-constexpr const char CB_MAP_UNIT_MAP_VALUE_WRITE_ENUM_TYPE[] =
-R"__c_cb(
-rpc_port_unit_map_write_int(info->map, name, *(int *)value);
-)__c_cb";
-
-/**
- * <VALUE> The name of the value.
- * <VALUE_TYPE> The pointer type of the value.
- */
-constexpr const char CB_MAP_UNIT_MAP_VALUE_WRITE_BASE_TYPE[] =
-R"__c_cb(
-rpc_port_unit_map_write_<VALUE>(info->map, name, *(<VALUE_TYPE> *)value);
-)__c_cb";
-
-/**
- * <KEY> The name of the key.
- */
-constexpr const char CB_MAP_UNIT_MAP_KEY_READ[] =
-R"__c_cb(
-rpc_port_unit_map_read_<KEY>(map, name, &key);
-)__c_cb";
-
-constexpr const char CB_MAP_UNIT_MAP_KEY_ENUM_TYPE_READ[] =
-R"__c_cb(
-rpc_port_unit_map_read_int(map, name, (int *)&key);
-)__c_cb";
-
-/**
- * <VALUE> The name of the value.
- */
-constexpr const char CB_MAP_UNIT_MAP_VALUE_READ[] =
-R"__c_cb(
-rpc_port_unit_map_read_<VALUE>(map, name, &value);
-)__c_cb";
-
-constexpr const char CB_MAP_UNIT_MAP_VALUE_ENUM_TYPE_READ[] =
-R"__c_cb(
-rpc_port_unit_map_read_int(map, name, (int *)&value);
-)__c_cb";
-
 /**
  * <KEY_TYPE> The type of the key.
  */
index 124526c6d62991f65ebbfa5ad66d8f4bde733107..51def6b895eb72aac354e5ceace9e28c8fe6b071 100644 (file)
@@ -32,7 +32,7 @@ typedef struct <PREFIX>_<NAME>_s {
 } <PREFIX>_<NAME>_t;
 
 typedef struct <PREFIX>_<NAME>_traverse_info_s {
-  rpc_port_unit_map_h map;
+  rpc_port_parcel_h parcel;
   int number;
 } <PREFIX>_<NAME>_traverse_info_t;
 
@@ -65,10 +65,12 @@ R"__c_cb(
 static gboolean __<PREFIX>_<NAME>_traverse_cb(gpointer key, gpointer value, gpointer user_data)
 {
   <PREFIX>_<NAME>_traverse_info_t *info = user_data;
-  char name[32];
-
-  snprintf(name, sizeof(name), "key-%d", info->number++);
-  <SET_UNIT_MAP_KEY_WRITE>
+  <IS_PTR?>
+  rpc_port_parcel_write_<PARCEL_TYPE_KEY>(info->parcel, (<KEY_TYPE>)key);
+  </IS_PTR?>
+  <IS_NOT_PTR?>
+  rpc_port_parcel_write_<PARCEL_TYPE_KEY>(info->parcel, *(<KEY_TYPE> *)key);
+  </IS_NOT_PTR?>
 
   return FALSE;
 }
@@ -77,7 +79,6 @@ static void __<PREFIX>_<NAME>_to(rpc_port_parcel_h parcel, void *data)
 {
   <PREFIX>_<NAME>_traverse_info_t info;
   <PREFIX>_<NAME>_t *handle = data;
-  rpc_port_unit_map_h map;
 
   if (parcel == nullptr || handle == nullptr) {
     _E("Invalid parameter");
@@ -85,21 +86,12 @@ static void __<PREFIX>_<NAME>_to(rpc_port_parcel_h parcel, void *data)
     return;
   }
 
-  map = rpc_port_unit_map_create();
-  if (map == nullptr) {
-    _E("Failed to create unit map");
-    set_last_result(RPC_PORT_ERROR_OUT_OF_MEMORY);
-    return;
-  }
-
-  rpc_port_unit_map_write_int(map, "size", g_tree_nnodes(handle->node));
+  rpc_port_parcel_write_array_count(parcel, g_tree_nnodes(handle->node));
 
-  info.map = map;
+  info.parcel = parcel;
   info.number = 0;
   g_tree_foreach(handle->node, __<PREFIX>_<NAME>_traverse_cb, &info);
 
-  rpc_port_parcel_write(parcel, &map->parcelable, map);
-  rpc_port_unit_map_destroy(map);
   set_last_result(RPC_PORT_ERROR_NONE);
 }
 
@@ -107,8 +99,6 @@ static void __<PREFIX>_<NAME>_from(rpc_port_parcel_h parcel, void *data)
 {
   <PREFIX>_<NAME>_t *handle = data;
   <KEY_TYPE>key;
-  rpc_port_unit_map_h map;
-  char name[32];
   int size = 0;
   int ret;
   int i;
@@ -119,30 +109,17 @@ static void __<PREFIX>_<NAME>_from(rpc_port_parcel_h parcel, void *data)
     return;
   }
 
-  map = rpc_port_unit_map_create();
-  if (map == nullptr) {
-    _E("Failed to create unit map");
-    set_last_result(RPC_PORT_ERROR_OUT_OF_MEMORY);
-    return;
-  }
-
-  rpc_port_parcel_read(parcel, &map->parcelable, map);
-
-  rpc_port_unit_map_read_int(map, "size", &size);
-
+  rpc_port_parcel_read_array_count(parcel, &size);
   for (i = 0; i < size; ++i) {
-    snprintf(name, sizeof(name), "key-%d", i);
-    <SET_UNIT_MAP_KEY_READ>
+    rpc_port_parcel_read_<PARCEL_TYPE_KEY>(parcel, &key);
 
     ret = <PREFIX>_<NAME>_insert(handle, key);
     if (ret != RPC_PORT_ERROR_NONE) {
-      rpc_port_unit_map_destroy(map);
       set_last_result(ret);
       return;
     }
   }
 
-  rpc_port_unit_map_destroy(map);
   set_last_result(RPC_PORT_ERROR_NONE);
 }
 
@@ -202,32 +179,42 @@ int <PREFIX>_<NAME>_destroy(<PREFIX>_<NAME>_h h)
 
 int <PREFIX>_<NAME>_clone(<PREFIX>_<NAME>_h h, <PREFIX>_<NAME>_h *clone)
 {
-  <PREFIX>_<NAME>_t *handle = h;
-  rpc_port_unit_map_h map;
+  <PREFIX>_<NAME>_h handle;
+  rpc_port_parcel_h parcel;
   int ret;
 
-  if (handle == nullptr || clone == nullptr) {
+  if (h == nullptr || clone == nullptr) {
     _E("Invalid parameter");
     return RPC_PORT_ERROR_INVALID_PARAMETER;
   }
 
-  map = rpc_port_unit_map_create();
-  if (map == nullptr) {
-    _E("Failed to create unit map");
-    return RPC_PORT_ERROR_OUT_OF_MEMORY;
+  ret = <PREFIX>_<NAME>_create(&handle);
+  if (ret != RPC_PORT_ERROR_NONE) {
+    _E("Failed to create handle. error(%d)", ret);
+    return ret;
   }
 
-  ret = rpc_port_unit_map_write_<NAME>(map, "clone", handle);
+  ret = rpc_port_parcel_create(&parcel);
   if (ret != RPC_PORT_ERROR_NONE) {
-    _E("Failed to write <NAME>. error(%d)", ret);
-    rpc_port_unit_map_destroy(map);
+    _E("Failed to create parcel handle. error(%d)", ret);
+    <PREFIX>_<NAME>_destroy(handle);
     return ret;
   }
 
-  rpc_port_unit_map_read_<NAME>(map, "clone", clone);
-  rpc_port_unit_map_destroy(map);
+  rpc_port_parcel_write(parcel, &h->parcelable, h);
+  rpc_port_parcel_read(parcel, &handle->parcelable, handle);
+  ret = get_last_result();
+  rpc_port_parcel_destroy(parcel);
 
-  return ret;
+  if (ret != RPC_PORT_ERROR_NONE) {
+    _E("Failed to read data. error(%d)", ret);
+    <PREFIX>_<NAME>_destroy(handle);
+    return ret;
+  }
+
+  *clone = handle;
+
+  return RPC_PORT_ERROR_NONE;
 }
 
 int <PREFIX>_<NAME>_insert(<PREFIX>_<NAME>_h h, <KEY_PARAM_TYPE>key)
@@ -352,42 +339,6 @@ if (key_a == key_b)
 return -1;
 )__c_cb";
 
-/**
- * <KEY> The name of the key.
- * <KEY_TYPE> The type of the key.
- */
-constexpr const char CB_SET_UNIT_MAP_KEY_WRITE_PTR_TYPE[] =
-R"__c_cb(
-rpc_port_unit_map_write_<KEY>(info->map, name, (<KEY_TYPE>)key);
-)__c_cb";
-
-constexpr const char CB_SET_UNIT_MAP_KEY_WRITE_ENUM_TYPE[] =
-R"__c_cb(
-rpc_port_unit_map_write_int(info->map, name, *(int *)key);
-)__c_cb";
-
-/**
- * <KEY> The name of the key.
- * <KEY_TYPE> The pointer type of the key.
- */
-constexpr const char CB_SET_UNIT_MAP_KEY_WRITE_BASE_TYPE[] =
-R"__c_cb(
-rpc_port_unit_map_write_<KEY>(info->map, name, *(<KEY_TYPE> *)key);
-)__c_cb";
-
-constexpr const char CB_SET_UNIT_MAP_KEY_ENUM_TYPE_READ[] =
-R"__c_cb(
-rpc_port_unit_map_read_int(map, name, (int *)&key);
-)__c_cb";
-
-/**
- * <KEY> The name of the key.
- */
-constexpr const char CB_SET_UNIT_MAP_KEY_READ[] =
-R"__c_cb(
-rpc_port_unit_map_read_<KEY>(map, name, &key);
-)__c_cb";
-
 /**
  * <KEY_TYPE> The type of the key.
  */
index e06ca31caf13fda86de61d84413c397a9e733869..ee8416f40cc9387cb6d8ae48b0b50d01797ca3ef 100644 (file)
  * limitations under the License.
  */
 
-#include <algorithm>
-
 #include "idlc/gen/version2/c_group_body_generator.hh"
 
+#include <algorithm>
+
 namespace {
 #include "idlc/gen/version2/c_group_body_generator_cb.hh"
 
 constexpr const char PREFIX_RPC_PORT_GROUP[] = "rpc_port_group";
-}
+}  // namespace
 
 namespace tidl {
 namespace version2 {
 
 CGroupBodyGenerator::CGroupBodyGenerator(std::shared_ptr<Document> doc)
-    : CBodyGeneratorBase(doc) {
-}
+    : CBodyGeneratorBase(doc) {}
 
 void CGroupBodyGenerator::OnInitGen(std::ofstream& stream) {
-  GenVersion(stream);
-  GenGNUSourceDefinition(stream);
-  GenIncludeDefaultHeaders(stream, true);
-  GenIncludeHeader(stream);
-  GenLogTag(stream, std::string("RPC_PORT_GROUP"));
-  GenLogDefinition(stream);
-  GenVersionDefinition(stream);
-  GenBaseDefinition(stream);
-  GenUnitMapDefinition(stream);
-  GenInterfaceMethodHandlerType(stream);
-  GenInterfaceEnums(stream);
-  GenStructureDefinition(stream);
-  GenInterfaceDefinition(stream);
-  GenUnitMapBase(stream);
-  GenHelper(stream);
-  GenStructure(stream);
-  GenInterfaces(stream);
+  auto interface_enums = [&](auto& r, const auto& i) {
+    if (i->GetType() != Block::TYPE_INTERFACE) return false;
+    auto& iface = static_cast<const Interface&>(*i);
+    auto prefix = GetHandlePrefix();
+
+    auto enum_fields = [&](auto& r, const auto& i) {
+      r.ReplaceToUpper("UPPERCASE_PREFIX", prefix)
+          .ReplaceToUpper("UPPERCASE_NAME", iface.GetID())
+          .ReplaceToUpper("UPPERCASE_METHOD_NAME", i->GetID());
+
+      return true;
+    };
+
+    r.Repeat("ENUM_FIELDS", iface.GetDeclarations(), enum_fields)
+        .Replace("PREFIX", prefix)
+        .Replace("NAME", iface.GetID())
+        .Transform([&](std::string str) { return SmartIndent(str); });
+
+    return true;
+  };
+
+  auto iface_def = [&](auto& r, const auto& i) {
+    if (i->GetType() != Block::TYPE_INTERFACE) return false;
+
+    const auto& iface = static_cast<const Interface&>(*i);
+    r.Replace("PREFIX", GetHandlePrefix())
+        .Replace("NAME", iface.GetID())
+        .Transform([&](std::string str) { return SmartIndent(str); });
+    return true;
+  };
+
+  auto interfaces = [&](auto& r, const auto& i) {
+    if (i->GetType() != Block::TYPE_INTERFACE) return false;
+    const Interface& iface = static_cast<const Interface&>(*i);
+    std::string prefix = GetHandlePrefix();
+    std::string name = iface.GetID();
+    r.Repeat(
+         "METHODS", iface.GetDeclarations(),
+         [&](auto& r, const auto& i) {
+           r.Replace("METHOD_NAME", i->GetID())
+               .Replace("METHOD_HANDLER_ARGS_DECL",
+                        GenMethodHandlerArgsDecl(iface, *i))
+               .Replace("METHOD_UNIT_MAP_READ", GenMethodUnitMapRead(iface, *i))
+               .Replace("METHOD_HANDLER_CALLBACK_INVOKE",
+                        GenMethodHandlerCallbackInvoke(*i))
+               .Replace("METHOD_HANDLER_ARGS_FREE",
+                        GenMethodHandlerArgsFree(iface, *i))
+               .Transform([&](std::string str) { return SmartIndent(str); });
+           return true;
+         })
+        .Repeat("METHODS_BASE", iface.GetDeclarations(),
+                [&](auto& r, const auto& i) {
+                  r.Replace("METHOD_BASE", GenMethodAsyncBase(iface, *i));
+                  return true;
+                })
+        .Replace("METHOD_HANDLERS", GenMethodHandlers(iface))
+        .Replace("PREFIX", prefix)
+        .Replace("NAME", name)
+        .Replace("HASH_METHOD", "[METHOD]"_hash)
+        .Transform([&](std::string str) { return SmartIndent(str); });
+    return true;
+  };
+
+  ReplaceAll(CB_MAIN_GROUP)
+      .Repeat("INTERFACE_ENUMS", GetDocument().GetBlocks(), interface_enums)
+      .Repeat("INTERFACE_DEFINITIONS", GetDocument().GetBlocks(), iface_def)
+      .Repeat("INTERFACES", GetDocument().GetBlocks(), interfaces)
+      .Replace("VERSION", std::string(FULLVER))
+      .Replace("UNIT_MAP_DEFINITION", GetUnitMapDefinition())
+      .Replace("STRUCTURE_DEFINITION", GetStructureDefinition())
+      .Replace("UNIT_MAP_BASE", GetUnitMapBase())
+      .Replace("STRUCTURE", GetStructure())
+      .Replace("INCLUDE", GetIncludeHeader())
+      .Replace("RPC_PORT_INTERNAL_APIS", GetRpcPortInternalAPIs())
+      .Out(stream);
 }
 
-void CGroupBodyGenerator::OnFiniGen(std::ofstream& stream) {
-}
+void CGroupBodyGenerator::OnFiniGen(std::ofstream& stream) {}
 
 std::string CGroupBodyGenerator::GetHandlePrefix() {
   std::string prefix = PREFIX_RPC_PORT_GROUP;
-  if (!HasNamespace())
-    return prefix;
+  if (!HasNamespace()) return prefix;
 
   return prefix + "_" + GetFileNamespace();
 }
 
-void CGroupBodyGenerator::GenIncludeDefaultHeaders(std::ofstream& stream, bool body) {
-  CGeneratorBase::GenIncludeDefaultHeaders(stream, body);
-  stream << CB_INTERFACE_EXTRA_HEADER;
-}
-
-void CGroupBodyGenerator::GenHelper(std::ofstream& stream) {
-  stream << SmartIndent(CB_HELPER);
-}
-
-void CGroupBodyGenerator::GenInterfaceDefinition(std::ofstream& stream) {
-  for (auto& iter : GetDocument().GetBlocks()) {
-    if (iter->GetType() != Block::TYPE_INTERFACE)
-      continue;
-
-    const auto& iface = static_cast<const Interface&>(*iter);
-    GenInterfaceBaseDefinition(stream, iface);
-  }
-}
-
-void CGroupBodyGenerator::GenInterfaceBaseDefinition(std::ofstream& stream,
-    const Interface& iface) {
-  ReplaceAll(CB_INTERFACE_BASE_DEF)
-      .Change("<PREFIX>", GetHandlePrefix())
-      .Change("<NAME>", iface.GetID())
-      .Transform([&](std::string str) { return SmartIndent(str); })
-      .Out(stream);
-}
-
-void CGroupBodyGenerator::GenInterfaceEnums(std::ofstream& stream) {
-  for (auto& b : GetDocument().GetBlocks()) {
-    if (b->GetType() != Block::TYPE_INTERFACE)
-      continue;
-
-    auto& iface = static_cast<const Interface&>(*b);
-    GenInterfaceEnum(stream, iface);
-  }
-}
-
-// @see #CB_INTERFACE_METHOD_ENUM
-std::string CGroupBodyGenerator::GenMethodEnums(const Interface& iface) {
-  std::string method_enums;
-
-  for (const auto& d : iface.GetDeclarations()) {
-    std::string method_enum(ReplaceAll(CB_INTERFACE_METHOD_ENUM, {
-        { "<UPPERCASE_PREFIX>", GetHandlePrefix() },
-        { "<UPPERCASE_NAME>", iface.GetID() },
-        { "<UPPERCASE_METHOD_NAME>", d->GetID() }
-    }));
-
-    method_enums += RemoveLine(method_enum);
-  }
-  std::transform(method_enums.begin(), method_enums.end(), method_enums.begin(),
-      ::toupper);
-
-  return method_enums;
-}
-
-void CGroupBodyGenerator::GenInterfaceEnum(std::ofstream& stream,
-    const Interface& iface) {
-  ReplaceAll(CB_INTERFACE_METHOD_ENUM_BASE, {
-      { "<PREFIX>", GetHandlePrefix() },
-      { "<NAME>", iface.GetID() },
-      { "<METHOD_ENUMS>", GenMethodEnums(iface) }
-  })
-  .Transform([&](std::string str){
-    return SmartIndent(str);
-  })
-  .Out(stream);
-}
-
-void CGroupBodyGenerator::GenInterfaces(std::ofstream& stream) {
-  for (auto& i : GetDocument().GetBlocks()) {
-    if (i->GetType() != Block::TYPE_INTERFACE)
-      continue;
-
-    const Interface &iface = static_cast<const Interface&>(*i);
-    GenInterface(stream, iface);
-  }
-}
-
-void CGroupBodyGenerator::GenInterface(std::ofstream& stream, const Interface& iface) {
-  for (const auto& d : iface.GetDeclarations()) {
-    GenInterfaceMethodHandlerBase(stream, iface, *d);
-  }
-
-  GenInterfaceMethodTable(stream, iface);
-  GenInterfaceBase(stream, iface);
-
-  for (const auto& d : iface.GetDeclarations()) {
-    GenInterfaceMethodBase(stream, iface, *d);
-  }
-}
-
-// @see #CB_INTERFACE_METHOD_TABLE
-void CGroupBodyGenerator::GenInterfaceMethodTable(std::ofstream& stream,
-    const Interface& iface) {
-  ReplaceAll(CB_INTERFACE_METHOD_TABLE, {
-      { "<NAME>", iface.GetID() },
-      { "<METHOD_HANDLERS>", GenMethodHandlers(iface) }
-  })
-  .Transform([&](std::string str){
-    return SmartIndent(str);
-  })
-  .Out(stream);
-}
-
 // @see #CB_INTERFACE_METHOD_HANDLER
 std::string CGroupBodyGenerator::GenMethodHandlers(const Interface& iface) {
   std::string code;
   for (const auto& d : iface.GetDeclarations()) {
-    if (d->GetMethodType() == Declaration::MethodType::DELEGATE)
-      continue;
+    if (d->GetMethodType() == Declaration::MethodType::DELEGATE) continue;
 
-    std::string enum_value = GetHandlePrefix() + "_" + iface.GetID() +
-      "_METHOD_" + d->GetID();
+    std::string enum_value =
+        GetHandlePrefix() + "_" + iface.GetID() + "_METHOD_" + d->GetID();
     std::transform(enum_value.begin(), enum_value.end(), enum_value.begin(),
-        ::toupper);
+                   ::toupper);
 
-    std::string method_handler(ReplaceAll(CB_INTERFACE_METHOD_HANDLER, {
-        { "<ENUM_VALUE>", enum_value },
-        { "<PREFIX>", GetHandlePrefix() },
-        { "<NAME>", iface.GetID() },
-        { "<METHOD_NAME>", d->GetID() }
-    }));
+    auto method_handler = ReplaceAll(CB_INTERFACE_METHOD_HANDLER)
+                              .Replace("ENUM_VALUE", enum_value)
+                              .Replace("PREFIX", GetHandlePrefix())
+                              .Replace("NAME", iface.GetID())
+                              .Replace("METHOD_NAME", d->GetID())
+                              .ToString();
 
     code += RemoveLine(method_handler);
   }
@@ -193,50 +141,11 @@ std::string CGroupBodyGenerator::GenMethodHandlers(const Interface& iface) {
   return code;
 }
 
-// @see #CB_INTERFACE_BASE
-void CGroupBodyGenerator::GenInterfaceBase(std::ofstream& stream,
-    const Interface& iface) {
-  std::string prefix = GetHandlePrefix();
-  std::string name = iface.GetID();
-  ReplaceAll(CB_INTERFACE_BASE)
-      .Change("<PREFIX>", prefix)
-      .Change("<NAME>", name)
-      .Transform([&](std::string str) {
-        return SmartIndent(str);
-      })
-      .Out(stream);
-}
-
-// @see #CB_INTERFACE_METHOD_HANDLER_TYPE
-void CGroupBodyGenerator::GenInterfaceMethodHandlerType(std::ofstream& stream) {
-  stream << SmartIndent(CB_INTERFACE_METHOD_HANDLER_TYPE);
-}
-
-// @see #CB_INTERFACE_METHOD_HANDLER_BASE
-void CGroupBodyGenerator::GenInterfaceMethodHandlerBase(std::ofstream& stream,
-    const Interface& iface, const Declaration& decl) {
-  ReplaceAll(CB_INTERFACE_METHOD_HANDLER_BASE, {
-      { "<PREFIX>", GetHandlePrefix() },
-      { "<NAME>", iface.GetID() },
-      { "<METHOD_NAME>", decl.GetID() },
-      { "<METHOD_HANDLER_ARGS_DECL>", GenMethodHandlerArgsDecl(iface, decl) },
-      { "<METHOD_UNIT_MAP_READ>",
-          GenMethodUnitMapRead(iface, decl) },
-      { "<METHOD_HANDLER_CALLBACK_INVOKE>",
-          GenMethodHandlerCallbackInvoke(decl) },
-      { "<METHOD_HANDLER_ARGS_FREE>", GenMethodHandlerArgsFree(iface, decl) }
-  })
-  .Transform([&](std::string str){
-    return SmartIndent(str);
-  })
-  .Out(stream);
-}
-
 // @see #CB_INTERFACE_METHOD_CALLBACK_INVOKE
 std::string CGroupBodyGenerator::GenMethodHandlerCallbackInvoke(
     const Declaration& decl) {
   std::string code(ReplaceAll(CB_INTERFACE_METHOD_CALLBACK_INVOKE,
-      "<METHOD_NAME>", decl.GetID()));
+                              "<METHOD_NAME>", decl.GetID()));
 
   if (decl.GetMethodType() == Declaration::MethodType::SYNC)
     code = ReplaceAll(code, "<RES_SET>", "res_ = ");
@@ -246,11 +155,9 @@ std::string CGroupBodyGenerator::GenMethodHandlerCallbackInvoke(
   std::string args;
   bool first = true;
   for (const auto& p : decl.GetParameters()) {
-    if (!first)
-      args += ", ";
+    if (!first) args += ", ";
     auto& param_type = p->GetParameterType();
-    if (param_type.GetDirection() != ParameterType::Direction::IN)
-      args += "&";
+    if (param_type.GetDirection() != ParameterType::Direction::IN) args += "&";
 
     args += p->GetID();
     first = false;
@@ -260,62 +167,20 @@ std::string CGroupBodyGenerator::GenMethodHandlerCallbackInvoke(
   return RemoveLine(code);
 }
 
-// @see #CB_INTERFACE_METHOD_DELEGATE_PARCEL_READ
-// @see #CB_INTERFACE_METHOD_USER_DEFINED_PARCEL_READ
-// @see #CB_INTERFACE_METHOD_BUNDLE_PARCEL_READ
-// @see #CB_INTERFACE_METHOD_STRING_PARCEL_READ
-// @see #CB_INTERFACE_METHOD_BASE_PARCEL_READ
-std::string CGroupBodyGenerator::GenMethodHandlerParcelRead(const Interface& iface,
-    const Declaration& decl) {
-  std::string code;
-  for (const auto& p : decl.GetParameters()) {
-    std::string parcel_read_code;
-    auto& param_type = p->GetParameterType();
-    if (param_type.GetDirection() != ParameterType::Direction::IN)
-      continue;
-
-    auto& type = param_type.GetBaseType();
-    if (type.IsUserDefinedType() ||
-        type.ToString() == "list" ||
-        type.ToString() == "array") {
-      parcel_read_code = ReplaceAll(
-          CB_INTERFACE_METHOD_USER_DEFINED_PARCEL_READ, "<PREFIX>",
-          GetHandlePrefix());
-      parcel_read_code = ReplaceAll(parcel_read_code, "<NAME>",
-          GetFullNameFromType(type, iface));
-      parcel_read_code = ReplaceAll(parcel_read_code, "<ARG>", p->GetID());
-    } else if (type.ToString() == "bundle") {
-      parcel_read_code = ReplaceAll(CB_INTERFACE_METHOD_BUNDLE_PARCEL_READ,
-          "<ARG>", p->GetID());
-    } else if (type.ToString() == "string") {
-      parcel_read_code = ReplaceAll(CB_INTERFACE_METHOD_STRING_PARCEL_READ,
-          "<ARG>", p->GetID());
-    } else {
-      parcel_read_code = ReplaceAll(CB_INTERFACE_METHOD_BASE_PARCEL_READ,
-          "<PARCEL_TYPE>", GetParcelType(type));
-      parcel_read_code = ReplaceAll(parcel_read_code, "<ARG>", p->GetID());
-    }
-
-    code += parcel_read_code;
-  }
-
-  return RemoveLine(code);
-}
-
-std::string CGroupBodyGenerator::GenMethodHandlerArgsDecl(const Interface& iface,
-    const Declaration& decl) {
+std::string CGroupBodyGenerator::GenMethodHandlerArgsDecl(
+    const Interface& iface, const Declaration& decl) {
   std::string args_decl;
   for (const auto& p : decl.GetParameters()) {
     auto& param_type = p->GetParameterType();
     auto& type = param_type.GetBaseType();
     args_decl += GetArgTypeString(type, iface) + p->GetID() + " = " +
-        GetErrorValue(type) + ";" + NLine(1);
+                 GetErrorValue(type) + ";" + NLine(1);
   }
 
   if (decl.GetMethodType() == Declaration::MethodType::SYNC) {
     args_decl += "rpc_port_parcel_h parcel_;" + NLine(1);
-    args_decl += GetArgTypeString(decl.GetType(), iface) + "res_ = " +
-        GetErrorValue(decl.GetType()) + ";" + NLine(1);
+    args_decl += GetArgTypeString(decl.GetType(), iface) +
+                 "res_ = " + GetErrorValue(decl.GetType()) + ";" + NLine(1);
   }
 
   return args_decl;
@@ -324,27 +189,26 @@ std::string CGroupBodyGenerator::GenMethodHandlerArgsDecl(const Interface& iface
 // @see #CB_INTERFACE_METHOD_USER_DEFINED_FREE
 // @see #CB_INTERFACE_METHOD_BUNDLE_FREE
 // @see #CB_INTERFACE_METHOD_STRING_FREE
-std::string CGroupBodyGenerator::GenMethodHandlerArgsFree(const Interface& iface,
-    const Declaration& decl) {
+std::string CGroupBodyGenerator::GenMethodHandlerArgsFree(
+    const Interface& iface, const Declaration& decl) {
   std::string free_code;
   std::string code;
   for (const auto& p : decl.GetParameters()) {
     auto& param_type = p->GetParameterType();
     auto& type = param_type.GetBaseType();
-    if (type.IsUserDefinedType() ||
-      type.ToString() == "list" ||
-      type.ToString() == "array") {
-      free_code = ReplaceAll(CB_INTERFACE_METHOD_USER_DEFINED_FREE,
-          "<PREFIX>", GetHandlePrefix());
-      free_code = ReplaceAll(free_code, "<NAME>",
-          GetFullNameFromType(type, iface));
+    if (type.IsUserDefinedType() || type.ToString() == "list" ||
+        type.ToString() == "array") {
+      free_code = ReplaceAll(CB_INTERFACE_METHOD_USER_DEFINED_FREE, "<PREFIX>",
+                             GetHandlePrefix());
+      free_code =
+          ReplaceAll(free_code, "<NAME>", GetFullNameFromType(type, iface));
       free_code = ReplaceAll(free_code, "<ARG>", p->GetID());
     } else if (type.ToString() == "bundle") {
-      free_code = ReplaceAll(CB_INTERFACE_METHOD_BUNDLE_FREE,
-          "<ARG>", p->GetID());
+      free_code =
+          ReplaceAll(CB_INTERFACE_METHOD_BUNDLE_FREE, "<ARG>", p->GetID());
     } else if (type.ToString() == "string") {
-      free_code = ReplaceAll(CB_INTERFACE_METHOD_STRING_FREE,
-          "<ARG>", p->GetID());
+      free_code =
+          ReplaceAll(CB_INTERFACE_METHOD_STRING_FREE, "<ARG>", p->GetID());
     } else {
       free_code.clear();
     }
@@ -356,21 +220,21 @@ std::string CGroupBodyGenerator::GenMethodHandlerArgsFree(const Interface& iface
 }
 
 std::string CGroupBodyGenerator::GenMethodParams(const Interface& iface,
-    const Declaration& decl) {
+                                                 const Declaration& decl) {
   std::string params;
   for (const auto& p : decl.GetParameters()) {
     params += ", ";
     auto& param_type = p->GetParameterType();
     auto& type = param_type.GetBaseType();
-    params += GetParamTypeString(param_type.GetDirection(), type, iface) +
-        p->GetID();
+    params +=
+        GetParamTypeString(param_type.GetDirection(), type, iface) + p->GetID();
   }
 
   return params;
 }
 
-std::string CGroupBodyGenerator::GenMethodUnitMapWrite(const Interface& iface,
-    const Declaration& decl) {
+std::string CGroupBodyGenerator::GenMethodUnitMapWrite(
+    const Interface& iface, const Declaration& decl) {
   std::string code;
   for (const auto& param : decl.GetParameters()) {
     auto& param_type = param->GetParameterType();
@@ -378,28 +242,34 @@ std::string CGroupBodyGenerator::GenMethodUnitMapWrite(const Interface& iface,
     auto& type = param_type.GetBaseType();
     if (type.GetUserDefinedType() == BaseType::UserType::ENUM) {
       code += ReplaceAll(CB_INTERFACE_METHOD_ENUM_UNIT_MAP_WRITE)
-          .Change("<TYPE_NAME>", param->GetID())
-          .Change("<ARG>", param->GetID());
-    } else if (type.IsUserDefinedType() || type.GetMetaType() != nullptr) {
+                  .Replace("HASH_ARG", GetHashCodeStr(param->GetID()))
+                  .Replace("ARG", param->GetID());
+    } else if (type.IsUserDefinedType() || type.GetMetaType() != nullptr ||
+               type.GetKeyType() != nullptr) {
       code += ReplaceAll(CB_INTERFACE_METHOD_USER_DEFINED_UNIT_MAP_WRITE)
-          .Change("<TYPE_NAME>", GetFullNameFromType(type, iface))
-          .Change("<ARG>", param->GetID());
+                  .Replace("TYPE_NAME", GetFullNameFromType(type, iface))
+                  .Replace("ARG", param->GetID())
+                  .Replace("HASH_ARG", GetHashCodeStr(param->GetID()));
       code += GetPrivateSharingString(type, iface, "h->port", param->GetID());
     } else if (type.ToString() == "bundle") {
       code += ReplaceAll(CB_INTERFACE_METHOD_BUNDLE_UNIT_MAP_WRITE)
-          .Change("<ARG>", param->GetID());
+                  .Replace("ARG", param->GetID())
+                  .Replace("HASH_ARG", GetHashCodeStr(param->GetID()));
     } else if (type.ToString() == "string") {
       code += ReplaceAll(CB_INTERFACE_METHOD_STRING_UNIT_MAP_WRITE)
-          .Change("<ARG>", param->GetID());
+                  .Replace("ARG", param->GetID())
+                  .Replace("HASH_ARG", GetHashCodeStr(param->GetID()));
     } else if (type.ToString() == "file") {
       code += ReplaceAll(CB_INTERFACE_METHOD_STRING_UNIT_MAP_WRITE)
-          .Change("<ARG>", param->GetID());
+                  .Replace("ARG", param->GetID())
+                  .Replace("HASH_ARG", GetHashCodeStr(param->GetID()));
       code += GetPrivateSharingString(type, iface, "h->port", param->GetID());
     } else {
       code += ReplaceAll(CB_INTERFACE_METHOD_BASE_UNIT_MAP_WRITE)
-          .Change("<TYPE_NAME>", GetFullNameFromType(type, iface))
-          .Change("<ARG_NAME>",  param->GetID())
-          .Change("<ARG>", param->GetID());
+                  .Replace("TYPE_NAME", GetFullNameFromType(type, iface))
+                  .Replace("ARG_NAME", param->GetID())
+                  .Replace("ARG", param->GetID())
+                  .Replace("HASH_ARG", GetHashCodeStr(param->GetID()));
     }
   }
 
@@ -407,38 +277,43 @@ std::string CGroupBodyGenerator::GenMethodUnitMapWrite(const Interface& iface,
 }
 
 std::string CGroupBodyGenerator::GenMethodUnitMapReadBase(
-    const Interface& iface, const BaseType& type,
-    const std::string& arg_name, const std::string& arg) {
+    const Interface& iface, const BaseType& type, const std::string& arg_name,
+    const std::string& arg) {
   std::string code;
   if (type.GetUserDefinedType() == BaseType::UserType::ENUM) {
-     code += ReplaceAll(CB_INTERFACE_METHOD_EMUM_UNIT_MAP_READ)
-        .Change("<ARG_NAME>", arg_name)
-        .Change("<ARG>", arg);
+    code += ReplaceAll(CB_INTERFACE_METHOD_EMUM_UNIT_MAP_READ)
+                .Replace("ARG_NAME", arg_name)
+                .Replace("HASH_ARG_NAME", GetHashCodeStr(arg_name))
+                .Replace("ARG", arg);
   } else if (type.IsUserDefinedType() || type.GetMetaType() != nullptr) {
     code = ReplaceAll(CB_INTERFACE_METHOD_USER_DEFINED_UNIT_MAP_READ)
-        .Change("<TYPE_NAME>", GetFullNameFromType(type, iface))
-        .Change("<ARG_NAME>", arg_name)
-        .Change("<ARG>", arg);
+               .Replace("TYPE_NAME", GetFullNameFromType(type, iface))
+               .Replace("ARG_NAME", arg_name)
+               .Replace("HASH_ARG_NAME", GetHashCodeStr(arg_name))
+               .Replace("ARG", arg);
   } else if (type.ToString() == "bundle") {
     code = ReplaceAll(CB_INTERFACE_METHOD_BUNDLE_UNIT_MAP_READ)
-        .Change("<ARG_NAME>", arg_name)
-        .Change("<ARG>", arg);
+               .Replace("ARG_NAME", arg_name)
+               .Replace("HASH_ARG_NAME", GetHashCodeStr(arg_name))
+               .Replace("ARG", arg);
   } else if (type.ToString() == "string" || type.ToString() == "file") {
     code = ReplaceAll(CB_INTERFACE_METHOD_STRING_UNIT_MAP_READ)
-        .Change("<ARG_NAME>", arg_name)
-        .Change("<ARG>", arg);
+               .Replace("ARG_NAME", arg_name)
+               .Replace("HASH_ARG_NAME", GetHashCodeStr(arg_name))
+               .Replace("ARG", arg);
   } else {
     code = ReplaceAll(CB_INTERFACE_METHOD_BASE_UNIT_MAP_READ)
-        .Change("<TYPE_NAME>", GetFullNameFromType(type, iface))
-        .Change("<ARG_NAME>", arg_name)
-        .Change("<ARG>", arg);
+               .Replace("TYPE_NAME", GetFullNameFromType(type, iface))
+               .Replace("ARG_NAME", arg_name)
+               .Replace("HASH_ARG_NAME", GetHashCodeStr(arg_name))
+               .Replace("ARG", arg);
   }
 
   return code;
 }
 
 std::string CGroupBodyGenerator::GenMethodUnitMapRead(const Interface& iface,
-    const Declaration& decl) {
+                                                      const Declaration& decl) {
   std::string code;
   std::string parcel_read_code;
   for (const auto& p : decl.GetParameters()) {
@@ -450,19 +325,16 @@ std::string CGroupBodyGenerator::GenMethodUnitMapRead(const Interface& iface,
   return RemoveLine(code);
 }
 
-
 std::string CGroupBodyGenerator::GenMethodParamsCheck(const Interface& iface,
-    const Declaration& decl) {
+                                                      const Declaration& decl) {
   std::string params_check;
   for (const auto& p : decl.GetParameters()) {
     auto& param_type = p->GetParameterType();
     auto& type = param_type.GetBaseType();
     if (type.GetUserDefinedType() == BaseType::UserType::STRUCTURE ||
         type.GetUserDefinedType() == BaseType::UserType::DELEGATE ||
-        type.ToString() == "list" ||
-        type.ToString() == "array" ||
-        type.ToString() == "bundle" ||
-        type.ToString() == "string" ||
+        type.ToString() == "list" || type.ToString() == "array" ||
+        type.ToString() == "bundle" || type.ToString() == "string" ||
         type.ToString() == "file")
       params_check += " || " + p->GetID() + " == nullptr";
   }
@@ -472,31 +344,31 @@ std::string CGroupBodyGenerator::GenMethodParamsCheck(const Interface& iface,
 
 // @see #CB_INTERFACE_METHOD_ASYNC_BASE
 std::string CGroupBodyGenerator::GenMethodAsyncBase(const Interface& iface,
-    const Declaration& decl) {
+                                                    const Declaration& decl) {
   std::string prefix = GetHandlePrefix();
   std::string name = iface.GetID();
   std::string method_name = decl.GetID();
-  std::string code(ReplaceAll(CB_INTERFACE_METHOD_ASYNC_BASE)
-      .Change("<PREFIX>", prefix)
-      .Change("<NAME>", name)
-      .Change("<METHOD_NAME>", method_name)
-      .Change("<METHOD_PARAMS>", GenMethodParams(iface, decl))
-      .Change("<METHOD_PARAMS_CHECK>", GenMethodParamsCheck(iface, decl))
-      .ChangeToUpper("<UPPERCASE_PREFIX>", prefix)
-      .ChangeToUpper("<UPPERCASE_NAME>", name)
-      .ChangeToUpper("<UPPERCASE_METHOD_NAME>", method_name)
-      .Change("<METHOD_UNIT_MAP_WRITE>", GenMethodUnitMapWrite(iface, decl)));
 
-  return code;
+  return ReplaceAll(CB_INTERFACE_METHOD_ASYNC_BASE)
+      .Replace("PREFIX", prefix)
+      .Replace("NAME", name)
+      .Replace("METHOD_NAME", method_name)
+      .Replace("METHOD_PARAMS", GenMethodParams(iface, decl))
+      .Replace("METHOD_PARAMS_CHECK", GenMethodParamsCheck(iface, decl))
+      .ReplaceToUpper("UPPERCASE_PREFIX", prefix)
+      .ReplaceToUpper("UPPERCASE_NAME", name)
+      .ReplaceToUpper("UPPERCASE_METHOD_NAME", method_name)
+      .Replace("METHOD_UNIT_MAP_WRITE", GenMethodUnitMapWrite(iface, decl))
+      .Replace("HASH_METHOD", "[METHOD]"_hash)
+      .ToString();
 }
 
 std::string CGroupBodyGenerator::GenMethodArgs(const Interface& iface,
-    const Declaration& decl) {
+                                               const Declaration& decl) {
   std::string args_code;
   for (const auto& p : decl.GetParameters()) {
     auto& param_type = p->GetParameterType();
-    if (param_type.GetDirection() != ParameterType::Direction::OUT)
-      continue;
+    if (param_type.GetDirection() != ParameterType::Direction::OUT) continue;
 
     auto& type = param_type.GetBaseType();
     args_code += GetReturnTypeString(type) + "new_" + p->GetID() + ";";
@@ -506,11 +378,5 @@ std::string CGroupBodyGenerator::GenMethodArgs(const Interface& iface,
   return args_code;
 }
 
-void CGroupBodyGenerator::GenInterfaceMethodBase(std::ofstream& stream,
-    const Interface& iface, const Declaration& decl) {
-  std::string code = GenMethodAsyncBase(iface, decl);
-  stream << SmartIndent(code);
-}
-
 }  // namespace version2
 }  // namespace tidl
index 113330fd856801dc493128e2f1b5680a7d022dee..914056a7d55b9043abfbfb3385c9e44736957525 100644 (file)
@@ -34,33 +34,14 @@ class CGroupBodyGenerator : public CBodyGeneratorBase {
   void OnInitGen(std::ofstream& stream) override;
   void OnFiniGen(std::ofstream& stream) override;
   std::string GetHandlePrefix() override;
-  void GenIncludeDefaultHeaders(std::ofstream& stream, bool body) override;
 
  private:
-  void GenInterfaceDefinition(std::ofstream& stream);
-  void GenInterfaceBaseDefinition(std::ofstream& stream, const Interface& iface);
-  void GenInterfaceMethodHandlerType(std::ofstream& stream);
-  void GenInterfaceMethodHandlerBase(std::ofstream& stream,
-      const Interface& iface, const Declaration& decl);
   std::string GenMethodHandlerArgsDecl(const Interface& iface,
       const Declaration& decl);
   std::string GenMethodHandlerArgsFree(const Interface& iface,
       const Declaration& decl);
-  void GenInterfaceMethodTable(std::ofstream& stream,
-      const Interface& iface);
   std::string GenMethodHandlerCallbackInvoke(const Declaration& decl);
-  std::string GenMethodHandlerParcelRead(const Interface& iface,
-    const Declaration& decl);
   std::string GenMethodHandlers(const Interface& iface);
-  std::string GenMethodEnums(const Interface& iface);
-  void GenInterfaceEnums(std::ofstream& stream);
-  void GenInterfaceEnum(std::ofstream& stream, const Interface& iface);
-  void GenInterfaces(std::ofstream& stream);
-  void GenInterface(std::ofstream& stream, const Interface& iface);
-  void GenInterfaceBase(std::ofstream& stream, const Interface& iface);
-  void GenInterfaceMethodEnumBase(std::ofstream& stream, const Interface& iface);
-  void GenInterfaceMethodBase(std::ofstream& stream, const Interface& iface,
-      const Declaration& decl);
 
   std::string GenMethodAsyncBase(const Interface& iface, const Declaration& decl);
   std::string GenMethodParams(const Interface& iface, const Declaration& decl);
@@ -73,7 +54,6 @@ class CGroupBodyGenerator : public CBodyGeneratorBase {
       const Interface& iface, const BaseType& type,
       const std::string& arg_name, const std::string& arg);
   std::string GenMethodParamsCheck(const Interface& iface, const Declaration& decl);
-  void GenHelper(std::ofstream& stream);
 };
 
 }  // namespace version2
index a67ff11a585a553cdf5b90d3f1bee33f4ee4c12a..9220562e7407e972ab51fda11c6a3b4229bba741 100644 (file)
 #ifndef IDLC_GEN_C_GROUP_BODY_GENERATOR_CB_HH_
 #define IDLC_GEN_C_GROUP_BODY_GENERATOR_CB_HH_
 
-
-constexpr const char CB_INTERFACE_METHOD_HANDLER_TYPE[] =
+constexpr const char CB_MAIN_GROUP[] =
 R"__c_cb(
+/*
+ * Generated by tidlc <VERSION>.
+ */
+
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+
+#pragma GCC diagnostic ignored "-Warray-bounds"
+
+#include <pthread.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <libgen.h>
+#include <glib.h>
+#include <dlog.h>
+#include <rpc-port.h>
+#include <rpc-port-parcel.h>
+#include <app_event.h>
+#include <dlfcn.h>
+
+<INCLUDE>
+
+#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(__FILE__), __FUNCTION__, __LINE__, ##__VA_ARGS__)
+
+#undef _W
+#define _W(fmt, ...) dlog_print(DLOG_WARN, LOG_TAG, "%s: %s(%d) > "fmt, basename(__FILE__), __FUNCTION__, __LINE__, ##__VA_ARGS__)
+
+#undef _I
+#define _I(fmt, ...) dlog_print(DLOG_INFO, LOG_TAG, "%s: %s(%d) > "fmt, basename(__FILE__), __FUNCTION__, __LINE__, ##__VA_ARGS__)
+
+#undef _D
+#define _D(fmt, ...) dlog_print(DLOG_DEBUG, LOG_TAG, "%s: %s(%d) > "fmt, basename(__FILE__), __FUNCTION__, __LINE__, ##__VA_ARGS__)
+
+#ifndef TIDL_VERSION
+#define TIDL_VERSION "<VERSION>"
+#endif
+
+#ifndef nullptr
+#define nullptr NULL
+#endif
+
+#ifndef ARRAY_SIZE
+#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
+#endif
+
+#ifndef STRING_GET
+#define STRING_GET(x) ((x) ? x : "")
+#endif
+
+#ifndef EXPORT_API
+#define EXPORT_API extern "C" __attribute__ ((visibility("default")))
+#endif
+
+<RPC_PORT_INTERNAL_APIS>
+<UNIT_MAP_DEFINITION>
+
 typedef int (*rpc_port_group_method_handler)(rpc_port_unit_map_h map, void *data);
-)__c_cb";
 
-/**
- * <METHOD_ENUMS> The enumeration declarations of methods.
- * <PREFIX> The prefix of the interface.
- * <NAME> The name of the interface.
- */
-constexpr const char CB_INTERFACE_METHOD_ENUM_BASE[] =
-R"__c_cb(
+<INTERFACE_ENUMS*>
 typedef enum {
-  <METHOD_ENUMS>
+  <ENUM_FIELDS*>
+  <UPPERCASE_PREFIX>_<UPPERCASE_NAME>_METHOD_<UPPERCASE_METHOD_NAME>,
+  </ENUM_FIELDS*>
 } <PREFIX>_<NAME>_method_e;
-)__c_cb";
 
+</INTERFACE_ENUMS*>
 
-/**
- * <UPPERCASE_PREFIX> The uppercase prefix of the interface.
- * <UPPERCASE_NAME> The uppercase name of the interface.
- * <UPPERCASE_METHOD_NAME> The uppercase method name of the interface.
- */
-constexpr const char CB_INTERFACE_METHOD_ENUM[] =
-R"__c_cb(
-<UPPERCASE_PREFIX>_<UPPERCASE_NAME>_METHOD_<UPPERCASE_METHOD_NAME>,
-)__c_cb";
+<STRUCTURE_DEFINITION>
 
-/**
- * <PREFIX> The prefix of the interface.
- * <NAME> The name of the interface.
- */
-constexpr const char CB_INTERFACE_BASE_DEF[] =
-R"__c_cb(
+<INTERFACE_DEFINITIONS*>
 typedef struct <PREFIX>_<NAME>_s {
   <PREFIX>_<NAME>_callback_s callback;
   event_handler_h event_handler;
@@ -60,42 +103,11 @@ typedef struct <PREFIX>_<NAME>_s {
   GRecMutex mutex;
   void *user_data;
 } <PREFIX>_<NAME>_t;
-)__c_cb";
 
-/**
- * <PREFIX> The prefix of the interface.
- * <NAME> The name of the interface.
- * <METHOD_NAME> The method name of the interface.
- * <METHOD_HANDLER_ARGS_DECL> The declarations for arguments of the method.
- * <METHOD_HANDLER_PARCEL_READ> The implementation to read the parameter from the parcel.
- * <METHOD_HANDLER_CALLBACK_INVOKE> The implementation to invoke the callback function of the method.
- * <METHOD_HANDLER_PARCEL_WRITE> The implementation to write the result to the parcel.
- * <METHOD_HANDLER_ARGS_FREE> The implementation to release arguments.
- */
-constexpr const char CB_INTERFACE_METHOD_HANDLER_BASE[] =
-R"__c_cb(
-static int __<PREFIX>_<NAME>_method_<METHOD_NAME>_handler(rpc_port_unit_map_h map_, void *user_data)
-{
-  <PREFIX>_<NAME>_t *h = user_data;
-  int ret_ = RPC_PORT_ERROR_NONE;
+</INTERFACE_DEFINITIONS*>
 
-  <METHOD_HANDLER_ARGS_DECL>
-  if (h == nullptr) {
-    _E("Invalid parameter");
-    ret_ = RPC_PORT_ERROR_INVALID_PARAMETER;
-    goto out;
-  }
-  <METHOD_UNIT_MAP_READ>
-  <METHOD_HANDLER_CALLBACK_INVOKE>
+<UNIT_MAP_BASE>
 
- out:
-  <METHOD_HANDLER_ARGS_FREE>
-  return ret_;
-}
-)__c_cb";
-
-constexpr const char CB_HELPER[] =
-R"__c_cb(
 static rpc_port_parcel_h __get_parcel_from_bundle(bundle *b)
 {
   void *raw = nullptr;
@@ -150,14 +162,35 @@ static char *__get_event_name(const char *appid, bool is_system, const char *ifa
   snprintf(buf, size, "event.%s.tidl_iface_%s", appid, iface_name);
   return buf;
 }
-)__c_cb";
 
-/**
- * <PREFIX> The prefix of the interface.
- * <NAME> The name of the interface.
- */
-constexpr const char CB_INTERFACE_BASE[] =
-R"__c_cb(
+<STRUCTURE>
+<INTERFACES*>
+
+<METHODS*>
+static int __<PREFIX>_<NAME>_method_<METHOD_NAME>_handler(rpc_port_unit_map_h map_, void *user_data)
+{
+  <PREFIX>_<NAME>_t *h = user_data;
+  int ret_ = RPC_PORT_ERROR_NONE;
+
+  <METHOD_HANDLER_ARGS_DECL>
+  if (h == nullptr) {
+    _E("Invalid parameter");
+    ret_ = RPC_PORT_ERROR_INVALID_PARAMETER;
+    goto out;
+  }
+  <METHOD_UNIT_MAP_READ>
+  <METHOD_HANDLER_CALLBACK_INVOKE>
+
+ out:
+  <METHOD_HANDLER_ARGS_FREE>
+  return ret_;
+}
+
+</METHODS*>
+
+static rpc_port_group_method_handler __<NAME>_method_table[] = {
+  <METHOD_HANDLERS>
+};
 
 static void __<NAME>_event_system_cb(const char *event_name, bundle *event_data, void *user_data)
 {
@@ -186,7 +219,7 @@ static void __<NAME>_event_system_cb(const char *event_name, bundle *event_data,
   rpc_port_parcel_read(p, &map->parcelable, map);
   rpc_port_parcel_destroy(p);
 
-  rpc_port_unit_map_read_int(map, "[METHOD]", &cmd);
+  rpc_port_unit_map_read_int(map, <HASH_METHOD> /*[METHOD]*/, &cmd);
 
   if (cmd >= 0 && cmd < ARRAY_SIZE(__<NAME>_method_table)) {
     if (__<NAME>_method_table[cmd])
@@ -203,6 +236,8 @@ int <PREFIX>_<NAME>_create(const char *sender_appid, <PREFIX>_<NAME>_callback_s
   int ret;
   char *ev_name;
 
+  rpc_port_internal_init();
+
   if (sender_appid == nullptr || callback == nullptr || h == nullptr) {
     _E("Invalid parameter");
     return RPC_PORT_ERROR_INVALID_PARAMETER;
@@ -296,8 +331,16 @@ int <PREFIX>_<NAME>_destroy(<PREFIX>_<NAME>_h h)
 
   return RPC_PORT_ERROR_NONE;
 }
+
+<METHODS_BASE*>
+<METHOD_BASE>
+</METHODS_BASE*>
+
+</INTERFACES*>
+
 )__c_cb";
 
+
 /**
  * <PREFIX> The prefix of the interface.
  * <NAME> The name of the interface.
@@ -319,6 +362,7 @@ void <PREFIX>_<NAME>_invoke_<METHOD_NAME>(<PREFIX>_<NAME>_h h<METHOD_PARAMS>)
   int res_;
   bundle* b;
   rpc_port_unit_map_h map_;
+  int method_ = <UPPERCASE_PREFIX>_<UPPERCASE_NAME>_METHOD_<UPPERCASE_METHOD_NAME>;
 
   if (h == nullptr<METHOD_PARAMS_CHECK>) {
     _E("Invalid parameter");
@@ -347,8 +391,7 @@ void <PREFIX>_<NAME>_invoke_<METHOD_NAME>(<PREFIX>_<NAME>_h h<METHOD_PARAMS>)
     return;
   }
 
-  rpc_port_unit_map_write_int(map_, "[METHOD]", <UPPERCASE_PREFIX>_<UPPERCASE_NAME>_METHOD_<UPPERCASE_METHOD_NAME>);
-
+  rpc_port_unit_map_write_int(map_, <HASH_METHOD> /*[METHOD]*/, &method_);
   <METHOD_UNIT_MAP_WRITE>
 
   rpc_port_parcel_write(parcel_, &map_->parcelable, map_);
@@ -378,63 +421,6 @@ void <PREFIX>_<NAME>_invoke_<METHOD_NAME>(<PREFIX>_<NAME>_h h<METHOD_PARAMS>)
 }
 )__c_cb";
 
-/**
- * <ARG> The argument.
- */
-constexpr const char CB_INTERFACE_METHOD_USER_DEFINED_PARCEL_WRITE[] =
-R"__c_cb(
-rpc_port_parcel_write(parcel_, &<ARG>->parcelable, <ARG>);
-)__c_cb";
-
-/**
- * <ARG> The argument.
- */
-constexpr const char CB_INTERFACE_METHOD_BUNDLE_PARCEL_WRITE[] =
-R"__c_cb(
-rpc_port_parcel_write_bundle(parcel_, <ARG>);
-)__c_cb";
-
-/**
- * <ARG> The argument.
- */
-constexpr const char CB_INTERFACE_METHOD_STRING_PARCEL_WRITE[] =
-R"__c_cb(
-rpc_port_parcel_write_string(parcel_, <ARG>);
-)__c_cb";
-
-/**
- * <PARCEL_TYPE> The type of the parcel.
- * <ARG> The argument.
- */
-constexpr const char CB_INTERFACE_METHOD_BASE_PARCEL_WRITE[] =
-R"__c_cb(
-rpc_port_parcel_write_<PARCEL_TYPE>(parcel_, <ARG>);
-)__c_cb";
-
-/**
- * <PREFIX> The prefix of the structure.
- * <NAME> The name of the structure.
- * <ARG> The argument.
- */
-constexpr const char CB_INTERFACE_METHOD_USER_DEFINED_PARCEL_READ[] =
-R"__c_cb(
-<ARG> = nullptr;
-<PREFIX>_<NAME>_create(&<ARG>);
-if (<ARG> == nullptr) {
-  _E("Failed to create handle");
-  ret_ = RPC_PORT_ERROR_OUT_OF_MEMORY;
-  goto out;
-}
-
-rpc_port_parcel_read(parcel, &<ARG>->parcelable, <ARG>);
-if (get_last_result() != RPC_PORT_ERROR_NONE) {
-  _E("Failed to read data");
-  <PREFIX>_<NAME>_destroy(<ARG>);
-  <ARG> = nullptr;
-  ret_ = get_last_result();
-  goto out;
-}
-)__c_cb";
 
 
 /**
@@ -480,27 +466,6 @@ if (h->callback.<METHOD_NAME>)
 )__c_cb";
 
 
-/**
- * <ARG> The argument.
- * <PREFIX> The prefix of the interface.
- * <NAME> The name of the interface
- */
-constexpr const char CB_INTERFACE_METHOD_DELEGATE_PARCEL_READ[] =
-R"__c_cb(
-ret_ = <PREFIX>_<NAME>_create(&<ARG>);
-if (ret_ != RPC_PORT_ERROR_NONE) {
-  _E("Failed to create handle. error(%d)", ret_);
-  goto out;
-}
-
-rpc_port_parcel_read(parcel, &<ARG>->parcelable, <ARG>);
-ret_ = get_last_result();
-if (ret_ != RPC_PORT_ERROR_NONE) {
-  _E("Failed to read data. error(%d)", ret_);
-  goto out;
-}
-)__c_cb";
-
 /**
  * <ARG> The argument.
  */
@@ -510,45 +475,6 @@ if (<ARG>)
   free(<ARG>);
 )__c_cb";
 
-/**
- * <NAME> The name of the interface.
- * <METHOD_HANDLERS> The declarations of method handlers.
- */
-constexpr const char CB_INTERFACE_METHOD_TABLE[] =
-R"__c_cb(
-static rpc_port_group_method_handler __<NAME>_method_table[] = {
-  <METHOD_HANDLERS>
-};
-)__c_cb";
-
-/**
- * <ARG> The argument.
- */
-constexpr const char CB_INTERFACE_METHOD_BUNDLE_PARCEL_READ[] =
-R"__c_cb(
-<ARG> = nullptr;
-rpc_port_parcel_read_bundle(parcel, &<ARG>);
-if (<ARG> == nullptr) {
-  _E("Failed to read data");
-  ret_ = RPC_PORT_ERROR_OUT_OF_MEMORY;
-  goto out;
-
-}
-)__c_cb";
-
-/**
- * <ARG> The argument.
- */
-constexpr const char CB_INTERFACE_METHOD_STRING_PARCEL_READ[] =
-R"__c_cb(
-<ARG> = nullptr;
-rpc_port_parcel_read_string(parcel, &<ARG>);
-if (<ARG> == nullptr) {
-  _E("Failed to read data");
-  ret_ = RPC_PORT_ERROR_OUT_OF_MEMORY;
-  goto out;
-}
-)__c_cb";
 
 /**
  * <TYPE_NAME> The type name of the argument.
@@ -556,7 +482,7 @@ if (<ARG> == nullptr) {
  */
 constexpr const char CB_INTERFACE_METHOD_USER_DEFINED_UNIT_MAP_WRITE[] =
 R"__c_cb(
-rpc_port_unit_map_write_<TYPE_NAME>(map_, "<ARG>", <ARG>);
+rpc_port_unit_map_write_<TYPE_NAME>(map_, <HASH_ARG> /*<ARG>*/, <ARG>);
 )__c_cb";
 
 /**
@@ -564,7 +490,7 @@ rpc_port_unit_map_write_<TYPE_NAME>(map_, "<ARG>", <ARG>);
  */
 constexpr const char CB_INTERFACE_METHOD_BUNDLE_UNIT_MAP_WRITE[] =
 R"__c_cb(
-rpc_port_unit_map_write_bundle(map_, "<ARG>", <ARG>);
+rpc_port_unit_map_write_bundle(map_, <HASH_ARG> /*<ARG>*/, <ARG>);
 )__c_cb";
 
 /**
@@ -572,7 +498,7 @@ rpc_port_unit_map_write_bundle(map_, "<ARG>", <ARG>);
  */
 constexpr const char CB_INTERFACE_METHOD_STRING_UNIT_MAP_WRITE[] =
 R"__c_cb(
-rpc_port_unit_map_write_string(map_, "<ARG>", <ARG>);
+rpc_port_unit_map_write_string(map_, <HASH_ARG> /*<ARG>*/, <ARG>);
 )__c_cb";
 
 /**
@@ -581,7 +507,7 @@ rpc_port_unit_map_write_string(map_, "<ARG>", <ARG>);
  */
 constexpr const char CB_INTERFACE_METHOD_BASE_UNIT_MAP_WRITE[] =
 R"__c_cb(
-rpc_port_unit_map_write_<TYPE_NAME>(map_, "<ARG>", <ARG>);
+rpc_port_unit_map_write_<TYPE_NAME>(map_, <HASH_ARG> /*<ARG>*/, &<ARG>);
 )__c_cb";
 
 /**
@@ -590,7 +516,7 @@ rpc_port_unit_map_write_<TYPE_NAME>(map_, "<ARG>", <ARG>);
  */
 constexpr const char CB_INTERFACE_METHOD_ENUM_UNIT_MAP_WRITE[] =
 R"__c_cb(
-rpc_port_unit_map_write_int(map_, "<ARG_NAME>", (int)<ARG>);
+rpc_port_unit_map_write_int(map_, <HASH_ARG> /*<ARG>*/, (int*)&<ARG>);
 )__c_cb";
 
 /**
@@ -601,7 +527,7 @@ rpc_port_unit_map_write_int(map_, "<ARG_NAME>", (int)<ARG>);
 constexpr const char CB_INTERFACE_METHOD_USER_DEFINED_UNIT_MAP_READ[] =
 R"__c_cb(
 <ARG> = nullptr;
-rpc_port_unit_map_read_<TYPE_NAME>(map_, "<ARG_NAME>", &<ARG>);
+rpc_port_unit_map_read_<TYPE_NAME>(map_, <HASH_ARG_NAME> /*<ARG_NAME>*/, &<ARG>);
 )__c_cb";
 
 /**
@@ -610,7 +536,7 @@ rpc_port_unit_map_read_<TYPE_NAME>(map_, "<ARG_NAME>", &<ARG>);
  */
 constexpr const char CB_INTERFACE_METHOD_EMUM_UNIT_MAP_READ[] =
 R"__c_cb(
-rpc_port_unit_map_read_int(map_, "<ARG_NAME>", (int *)&<ARG>);
+rpc_port_unit_map_read_int(map_, <HASH_ARG_NAME> /*<ARG_NAME>*/, (int *)&<ARG>);
 )__c_cb";
 
 /**
@@ -620,7 +546,7 @@ rpc_port_unit_map_read_int(map_, "<ARG_NAME>", (int *)&<ARG>);
 constexpr const char CB_INTERFACE_METHOD_BUNDLE_UNIT_MAP_READ[] =
 R"__c_cb(
 <ARG> = nullptr;
-rpc_port_unit_map_read_bundle(map_, "<ARG_NAME>", &<ARG>);
+rpc_port_unit_map_read_bundle(map_, <HASH_ARG_NAME> /*<ARG_NAME>*/, &<ARG>);
 )__c_cb";
 
 /**
@@ -630,7 +556,7 @@ rpc_port_unit_map_read_bundle(map_, "<ARG_NAME>", &<ARG>);
 constexpr const char CB_INTERFACE_METHOD_STRING_UNIT_MAP_READ[] =
 R"__c_cb(
 <ARG> = nullptr;
-= rpc_port_unit_map_read_string(map_, "<ARG_NAME>", &<ARG>);
+= rpc_port_unit_map_read_string(map_, <HASH_ARG_NAME> /*<ARG_NAME>*/, &<ARG>);
 )__c_cb";
 
 /**
@@ -640,7 +566,7 @@ R"__c_cb(
  */
 constexpr const char CB_INTERFACE_METHOD_BASE_UNIT_MAP_READ[] =
 R"__c_cb(
-rpc_port_unit_map_read_<TYPE_NAME>(map_, "<ARG_NAME>", &<ARG>);
+rpc_port_unit_map_read_<TYPE_NAME>(map_, <HASH_ARG_NAME> /*<ARG_NAME>*/, &<ARG>);
 )__c_cb";
 
 /**
@@ -652,17 +578,4 @@ R"__c_cb(
 rpc_port_parcel_read_<PARCEL_TYPE>(parcel, &<ARG>);
 )__c_cb";
 
-/**
- * <PARAM> The name of the parameter.
- */
-constexpr const char CB_INTERFACE_METHOD_PARAM_SET[] =
-R"__c_cb(
-*<PARAM> = new_<PARAM>;
-)__c_cb";
-
-constexpr const char CB_INTERFACE_EXTRA_HEADER[] =
-R"__c_cb(
-#include <app_event.h>
-)__c_cb";
-
 #endif  // IDLC_GEN_C_GROUP_BODY_GENERATOR_CB_HH_
index a6c5992e57fa838ec89695441cc587febeb5db88..81a151e22c6185d23998e195170f54acc55afb3c 100644 (file)
@@ -29,7 +29,7 @@ R"__c_cb(
 /**
  * @brief The <PREFIX>_<NAME> handle.
  */
-typedef void *<PREFIX>_<NAME>_h;
+typedef struct <PREFIX>_<NAME>_s *<PREFIX>_<NAME>_h;
 )__c_cb";
 
 /**
index 95b964729f5b8bbea816a973977bbc1fa42d2b0f..76db440770ea99edc96047cf3a5a965b9f30e7c6 100644 (file)
@@ -26,172 +26,175 @@ namespace tidl {
 namespace version2 {
 
 CProxyBodyGenerator::CProxyBodyGenerator(std::shared_ptr<Document> doc,
-    std::shared_ptr<Options> options)
-    : CBodyGeneratorBase(std::move(doc)),
-      options_(std::move(options)) {
-}
+                                         std::shared_ptr<Options> options)
+    : CBodyGeneratorBase(std::move(doc)), options_(std::move(options)) {}
 
 void CProxyBodyGenerator::OnInitGen(std::ofstream& stream) {
-  GenVersion(stream);
-  GenGNUSourceDefinition(stream);
-  GenIncludeDefaultHeaders(stream);
-  GenIncludeLemHeaders(stream);
-  GenIncludeHeader(stream);
-  GenLogTag(stream, std::string("RPC_PORT_PROXY"));
-  GenLogDefinition(stream);
-  GenVersionDefinition(stream);
-  GenBaseDefinition(stream);
-  GenUnitMapDefinition(stream);
-  GenLemDefinition(stream);
-  GenDelegateDefinition(stream);
-  GenInterfaceDelegateCallback(stream);
-  GenStructureDefinition(stream);
-  GenRemoteExceptionDefinition(stream);
-  GenInterfaceDefinition(stream);
-  GenUnitMapBase(stream);
-  GenLemBase(stream);
-  GenDelegateBase(stream);
-  GenPrivateSharingListSet(stream);
-  GenStructure(stream);
-  GenRemoteExceptionBase(stream);
-  GenInterface(stream);
-  GenLemAPI(stream);
-}
+  std::string input = basename(const_cast<char*>(options_->GetInput().c_str()));
+  input = input.substr(0, input.find_last_of("."));
 
-void CProxyBodyGenerator::OnFiniGen(std::ofstream& stream) {
+  auto interfaces = [&](auto& r, const auto& i) {
+    if (i->GetType() != Block::TYPE_INTERFACE) return false;
+
+    const auto& iface = static_cast<const Interface&>(*i);
+    auto interface_delegate_bases = [&](auto& r, const auto& i) {
+      if (i->GetMethodType() != Declaration::MethodType::DELEGATE) return false;
+      std::string enum_value =
+          GetHandlePrefix() + "_" + iface.GetID() + "_DELEGATE_" + i->GetID();
+      bool has_free = false;
+      std::string delegate_args_free =
+          GenDelegateArgsFree(iface, *i, &has_free);
+
+      r.Replace("PREFIX", GetHandlePrefix())
+          .Replace("NAME", iface.GetID())
+          .Replace("DELEGATE_NAME", i->GetID())
+          .ReplaceToUpper("DELEGATE_ENUM_VALUE", enum_value)
+          .Replace("DELEGATE_ARGS_DECL", GenDelegateArgsDecl(iface, *i))
+          .Replace("DELEGATE_UNIT_MAP_READ", GenDelegateUnitMapRead(iface, *i))
+          .Replace("DELEGATE_ARGS_FREE", delegate_args_free)
+          .Replace("DELEGATE_CALLBACK_ARGS", GenDelegateCallbackArgs(*i))
+          .Transform([&](std::string code) { return SmartIndent(code); });
+      return true;
+    };
+
+    int cnt = 1;
+    r.Repeat("ENUM_FIELDS", iface.GetDeclarations(),
+             [&](auto& r, const auto& i) {
+               if (i->GetMethodType() != Declaration::MethodType::DELEGATE)
+                 return false;
+               r.ReplaceToUpper("UPPER_PREFIX", GetHandlePrefix())
+                   .ReplaceToUpper("UPPER_NAME", iface.GetID())
+                   .ReplaceToUpper("UPPER_ID", i->GetID())
+                   .Replace("CNT", std::to_string(cnt++));
+
+               return true;
+             })
+        .Replace("PREFIX", GetHandlePrefix())
+        .Replace("NAME", iface.GetID())
+        .Repeat("INTERFACE_DELEGATE_BASES", iface.GetDeclarations(),
+                interface_delegate_bases)
+        .Replace("INTERFACE_DELEGATE_TABLE", GetInterfaceDelegateTable(iface))
+        .Replace("INTERFACE_METHOD_ENUM_BASE",
+                 GetInterfaceMethodEnumBase(iface))
+        .Replace("DELEGATE_PROCESS", GetDelegateProcess(iface))
+        .Replace("INTERFACE_BASE", GetInterfaceBase(iface))
+        .Repeat("METHODS", iface.GetDeclarations(),
+                [&](auto& r, const auto& i) {
+                  if (i->GetMethodType() == Declaration::MethodType::DELEGATE)
+                    return false;
+                  auto method_type = i->GetMethodType();
+                  bool async = (method_type == Declaration::MethodType::ASYNC);
+                  r.Remove("ASYNC", !async)
+                      .Remove("SYNC", async)
+                      .Replace("PREFIX", GetHandlePrefix())
+                      .Replace("NAME", iface.GetID())
+                      .Replace("METHOD_NAME", i->GetID())
+                      .Replace("METHOD_PARAMS", GenMethodParams(iface, *i))
+                      .Replace("METHOD_PARAMS_CHECK",
+                               GenMethodParamsCheck(iface, *i))
+                      .ReplaceToUpper("UPPERCASE_PREFIX", GetHandlePrefix())
+                      .ReplaceToUpper("UPPERCASE_NAME", iface.GetID())
+                      .ReplaceToUpper("UPPERCASE_METHOD_NAME", i->GetID())
+                      .Replace("METHOD_UNIT_MAP_WRITE",
+                               GenMethodUnitMapWrite(iface, *i))
+                      .Replace("METHOD_DELEGATE_APPEND",
+                               GenMethodDelegateAppend(iface, *i))
+                      .Replace("RETURN_TYPE",
+                               GetReturnTypeString(i->GetType(), iface.GetID()))
+                      .Replace("METHOD_ARGS",
+                               GenMethodArgs(iface, *i, iface.GetID()))
+                      .Replace("ERROR_VALUE", GetErrorValue(i->GetType()))
+                      .Replace("METHOD_UNIT_MAP_READ",
+                               GenMethodUnitMapRead(iface, *i))
+                      .Replace("HASH_METHOD", "[METHOD]"_hash)
+                      .Transform(
+                          [&](std::string code) { return SmartIndent(code); });
+
+                  return true;
+                });
+    return true;
+  };
+
+  auto interface_definitions = [&](auto& r, const auto& i) {
+    if (i->GetType() != Block::TYPE_INTERFACE) return false;
+
+    const auto& iface = static_cast<const Interface&>(*i);
+    r.Repeat("DELEGATE_DEFINITIONS", iface.GetDeclarations(),
+             [&](auto& r, const auto& i) {
+               if (i->GetMethodType() != Declaration::MethodType::DELEGATE)
+                 return false;
+               r.Replace("PREFIX", GetHandlePrefix())
+                   .Replace("NAME", iface.GetID())
+                   .Replace("DELEGATE_NAME", i->GetID());
+               return true;
+             })
+        .Replace("PREFIX", GetHandlePrefix())
+        .Replace("NAME", iface.GetID())
+        .Transform([&](std::string str) { return SmartIndent(str); });
+    return true;
+  };
+
+  ReplaceAll(CB_MAIN_PROXY)
+      .RemoveAll("HAS_DELEGATE", !HasDelegate())
+      .Replace("VERSION", std::string(FULLVER))
+      .Replace("INCLUDE", GetIncludeHeader())
+      .Replace("UNIT_MAP_DEFINITION", GetUnitMapDefinition())
+      .Replace("STRUCTURE_DEFINITION", GetStructureDefinition())
+      .Replace("REMOTE_EXCEPTION_DEFINITION", GetRemoteExceptionDefinition())
+      .Replace("RPC_PORT_INTERNAL_APIS", GetRpcPortInternalAPIs())
+      .Repeat("INTERFACE_DEFINITIONS", GetDocument().GetBlocks(),
+              interface_definitions)
+      .Replace("UNIT_MAP_BASE", GetUnitMapBase())
+      .Replace("LEM_BASE", GetLemBase())
+      .Replace("PRIVATE_SHARING_LIST_SET", GetPrivateSharingListSet())
+      .Replace("STRUCTURE", GetStructure())
+      .Replace("REMOTE_EXCEPTION_BASE", GetRemoteExceptionBase())
+      .Repeat("INTERFACES", GetDocument().GetBlocks(), interfaces)
+      .Repeat(
+          "LEM_APIS", GetDocument().GetBlocks(),
+          [&](auto& r, const auto& i) {
+            if (i->GetType() != Block::TYPE_INTERFACE) return false;
+
+            const auto& iface = static_cast<const Interface&>(*i);
+            r.Replace("INPUT_FILE", input).Replace("IFACE_NAME", iface.GetID());
+
+            return true;
+          })
+      .Out(stream);
 }
 
-void CProxyBodyGenerator::GenLemDefinition(std::ofstream& stream) {
-  stream << SmartIndent(CB_LEM_PROXY_BASE_DEF);
-}
+void CProxyBodyGenerator::OnFiniGen(std::ofstream& stream) {}
 
-void CProxyBodyGenerator::GenLemBase(std::ofstream& stream) {
+std::string CProxyBodyGenerator::GetLemBase() {
   std::string input = basename(const_cast<char*>(options_->GetInput().c_str()));
   input = input.substr(0, input.find_last_of("."));
-  ReplaceAll(CB_LEM_PROXY_BASE)
+  return ReplaceAll(CB_LEM_PROXY_BASE)
       .Change("<INPUT_FILE>", input)
       .Transform([&](std::string code) { return SmartIndent(code); })
-      .Out(stream);
-}
-
-void CProxyBodyGenerator::GenLemAPI(std::ofstream& stream) {
-  std::string input = basename(const_cast<char*>(options_->GetInput().c_str()));
-  input = input.substr(0, input.find_last_of("."));
-  std::string code;
-  for (auto& iter : GetDocument().GetBlocks()) {
-    if (iter->GetType() != Block::TYPE_INTERFACE)
-      continue;
-
-    const auto& iface = static_cast<const Interface&>(*iter);
-    code += ReplaceAll(CB_LEM_PROXY_API)
-        .Change("<INPUT_FILE>", input)
-        .Change("<IFACE_NAME>", iface.GetID());
-  }
-
-  stream << SmartIndent(code);
-}
-
-void CProxyBodyGenerator::GenDelegateDefinition(std::ofstream& stream) {
-  if (HasDelegate())
-    stream << SmartIndent(CB_DELEGATE_DEFS);
-}
-
-void CProxyBodyGenerator::GenDelegateBase(std::ofstream& stream) {
-  if (HasDelegate())
-    stream << SmartIndent(CB_DELEGATE_BASE);
-}
-
-void CProxyBodyGenerator::GenInterfaceDelegateCallback(std::ofstream& stream) {
-  if (HasDelegate())
-    stream << SmartIndent(CB_INTERFACE_DELEGATE_CALLBACK);
-}
-
-void CProxyBodyGenerator::GenInterfaceDefinition(std::ofstream& stream) {
-  for (auto& iter : GetDocument().GetBlocks()) {
-    if (iter->GetType() != Block::TYPE_INTERFACE)
-      continue;
-
-    const auto& iface = static_cast<const Interface&>(*iter);
-    for (const auto& decl : iface.GetDeclarations()) {
-      if (decl->GetMethodType() != Declaration::MethodType::DELEGATE)
-        continue;
-
-      GenInterfaceDelegateDefinition(stream, iface, *decl);
-    }
-
-    GenInterfaceBaseDefinition(stream, iface);
-  }
-}
-
-void CProxyBodyGenerator::GenInterfaceDelegateDefinition(std::ofstream& stream,
-    const Interface& iface, const Declaration& decl) {
-  ReplaceAll(CB_INTERFACE_DELEGATE_DEF)
-      .Change("<PREFIX>", GetHandlePrefix())
-      .Change("<NAME>", iface.GetID())
-      .Change("<DELEGATE_NAME>", decl.GetID())
-      .Transform([&](std::string str) { return SmartIndent(str); })
-      .Out(stream);
-}
-
-void CProxyBodyGenerator::GenInterfaceBaseDefinition(std::ofstream& stream,
-    const Interface& iface) {
-  ReplaceAll(CB_INTERFACE_BASE_DEF)
-      .Change("<PREFIX>", GetHandlePrefix())
-      .Change("<NAME>", iface.GetID())
-      .Transform([&](std::string str) { return SmartIndent(str); })
-      .Out(stream);
-}
-
-void CProxyBodyGenerator::GenInterface(std::ofstream& stream) {
-  for (auto& iter : GetDocument().GetBlocks()) {
-    if (iter->GetType() != Block::TYPE_INTERFACE)
-      continue;
-
-    const auto& iface = static_cast<const Interface&>(*iter);
-    GenInterfaceDelegateEnumBase(stream, iface);
-
-    for (const auto& decl : iface.GetDeclarations()) {
-      if (decl->GetMethodType() != Declaration::MethodType::DELEGATE)
-        continue;
-
-      GenInterfaceDelegateBase(stream, iface, *decl);
-    }
-
-    GenInterfaceDelegateTable(stream, iface);
-    GenInterfaceMethodEnumBase(stream, iface);
-    GenDelegateProcess(stream, iface);
-    GenInterfaceBase(stream, iface);
-
-    for (const auto& decl : iface.GetDeclarations()) {
-      if (decl->GetMethodType() == Declaration::MethodType::DELEGATE)
-        continue;
-
-      GenInterfaceMethodBase(stream, iface, *decl);
-    }
-  }
+      .ToString();
 }
 
 std::string CProxyBodyGenerator::GenMethodParams(const Interface& iface,
-    const Declaration& decl) {
+                                                 const Declaration& decl) {
   std::string params;
   for (const auto& param : decl.GetParameters()) {
     params += ", ";
     auto& param_type = param->GetParameterType();
     auto& type = param_type.GetBaseType();
     params += GetParamTypeString(param_type.GetDirection(), type, iface) +
-        param->GetID();
+              param->GetID();
   }
 
   return params;
 }
 
 std::string CProxyBodyGenerator::GenMethodArgs(const Interface& iface,
-    const Declaration& decl, const std::string& id) {
+                                               const Declaration& decl,
+                                               const std::string& id) {
   std::string code;
   for (const auto& param : decl.GetParameters()) {
     auto& param_type = param->GetParameterType();
-    if (param_type.GetDirection() == ParameterType::Direction::IN)
-      continue;
+    if (param_type.GetDirection() == ParameterType::Direction::IN) continue;
 
     auto& type = param_type.GetBaseType();
     code += GetReturnTypeString(type, id) + "new_" + param->GetID() + ";";
@@ -202,30 +205,27 @@ std::string CProxyBodyGenerator::GenMethodArgs(const Interface& iface,
 }
 
 std::string CProxyBodyGenerator::GenMethodParamsCheck(const Interface& iface,
-    const Declaration& decl) {
+                                                      const Declaration& decl) {
   std::string params_check;
   for (const auto& p : decl.GetParameters()) {
     auto& param_type = p->GetParameterType();
     auto& type = param_type.GetBaseType();
     if (type.GetUserDefinedType() == BaseType::UserType::STRUCTURE ||
         type.GetUserDefinedType() == BaseType::UserType::DELEGATE ||
-        type.GetMetaType() != nullptr ||
-        type.ToString() == "bundle" ||
-        type.ToString() == "string" ||
-        type.ToString() == "file")
+        type.GetMetaType() != nullptr || type.ToString() == "bundle" ||
+        type.ToString() == "string" || type.ToString() == "file")
       params_check += " || " + p->GetID() + " == nullptr";
   }
 
   return params_check;
 }
 
-std::string CProxyBodyGenerator::GenMethodUnitMapWrite(const Interface& iface,
-    const Declaration& decl) {
+std::string CProxyBodyGenerator::GenMethodUnitMapWrite(
+    const Interface& iface, const Declaration& decl) {
   std::string code;
   for (const auto& param : decl.GetParameters()) {
     auto& param_type = param->GetParameterType();
-    if (param_type.GetDirection() == ParameterType::Direction::OUT)
-      continue;
+    if (param_type.GetDirection() == ParameterType::Direction::OUT) continue;
 
     std::string arg = param->GetID();
     if (param_type.GetDirection() == ParameterType::Direction::REF)
@@ -234,51 +234,59 @@ std::string CProxyBodyGenerator::GenMethodUnitMapWrite(const Interface& iface,
     auto& type = param_type.GetBaseType();
     if (type.GetUserDefinedType() == BaseType::UserType::DELEGATE) {
       code += ReplaceAll(CB_INTERFACE_METHOD_DELEGATE_UNIT_MAP_WRITE)
-          .Change("<ARG_NAME>", param->GetID())
-          .Change("<ARG>", arg);
+                  .Replace("ARG_NAME", param->GetID())
+                  .Replace("HASH_ARG_NAME", GetHashCodeStr(param->GetID()))
+                  .Replace("ARG", arg);
     } else if (type.GetUserDefinedType() == BaseType::UserType::ENUM) {
       code += ReplaceAll(CB_INTERFACE_METHOD_ENUM_UNIT_MAP_WRITE)
-          .Change("<ARG_NAME>", param->GetID())
-          .Change("<ARG>", arg);
-    } else if (type.IsUserDefinedType() || type.GetMetaType() != nullptr) {
+                  .Replace("ARG_NAME", param->GetID())
+                  .Replace("HASH_ARG_NAME", GetHashCodeStr(param->GetID()))
+                  .Replace("ARG", arg);
+    } else if (type.IsUserDefinedType() || type.GetMetaType() != nullptr ||
+               type.GetKeyType() != nullptr) {
       code += ReplaceAll(CB_INTERFACE_METHOD_USER_DEFINED_UNIT_MAP_WRITE)
-          .Change("<TYPE_NAME>", GetFullNameFromType(type, iface))
-          .Change("<ARG_NAME>", param->GetID())
-          .Change("<ARG>", arg);
+                  .Replace("TYPE_NAME", GetFullNameFromType(type, iface))
+                  .Replace("ARG_NAME", param->GetID())
+                  .Replace("HASH_ARG_NAME", GetHashCodeStr(param->GetID()))
+                  .Replace("ARG", arg);
       code += GetPrivateSharingString(type, iface, "h->port", param->GetID());
     } else if (type.ToString() == "bundle") {
       code += ReplaceAll(CB_INTERFACE_METHOD_BUNDLE_UNIT_MAP_WRITE)
-          .Change("<ARG_NAME>", param->GetID())
-          .Change("<ARG>", arg);
+                  .Replace("ARG_NAME", param->GetID())
+                  .Replace("HASH_ARG_NAME", GetHashCodeStr(param->GetID()))
+                  .Replace("ARG", arg);
     } else if (type.ToString() == "string") {
       code += ReplaceAll(CB_INTERFACE_METHOD_STRING_UNIT_MAP_WRITE)
-          .Change("<ARG_NAME>", param->GetID())
-          .Change("<ARG>", "STRING_GET(" + arg + ")");
+                  .Replace("ARG_NAME", param->GetID())
+                  .Replace("HASH_ARG_NAME", GetHashCodeStr(param->GetID()))
+                  .Replace("ARG", "STRING_GET(" + arg + ")");
     } else if (type.ToString() == "file") {
-      code += ReplaceAll(CB_INTERFACE_METHOD_STRING_UNIT_MAP_WRITE)
-          .Change("<ARG_NAME>", param->GetID())
-          .Change("<ARG>", arg);
+      code += ReplaceAll(CB_INTERFACE_METHOD_FILE_UNIT_MAP_WRITE)
+                  .Replace("ARG_NAME", param->GetID())
+                  .Replace("HASH_ARG_NAME", GetHashCodeStr(param->GetID()))
+                  .Replace("ARG", arg);
       code += GetPrivateSharingString(type, iface, "h->port", param->GetID());
     } else {
       code += ReplaceAll(CB_INTERFACE_METHOD_BASE_UNIT_MAP_WRITE)
-          .Change("<TYPE_NAME>", GetFullNameFromType(type, iface))
-          .Change("<ARG_NAME>",  param->GetID())
-          .Change("<ARG>", arg);
+                  .Replace("TYPE_NAME", GetFullNameFromType(type, iface))
+                  .Replace("ARG_NAME", param->GetID())
+                  .Replace("HASH_ARG_NAME", GetHashCodeStr(param->GetID()))
+                  .Replace("ARG", arg);
     }
   }
 
   return RemoveLine(code);
 }
 
-std::string CProxyBodyGenerator::GenMethodDelegateAppend(const Interface& iface,
-    const Declaration& decl) {
+std::string CProxyBodyGenerator::GenMethodDelegateAppend(
+    const Interface& iface, const Declaration& decl) {
   std::string code;
   for (const auto& param : decl.GetParameters()) {
     auto& param_type = param->GetParameterType();
     auto& type = param_type.GetBaseType();
     if (IsDelegateType(iface, type)) {
       code += ReplaceAll(CB_INTERFACE_METHOD_DELEGATE_APPEND)
-          .Change("<ARG>", param->GetID());
+                  .Change("<ARG>", param->GetID());
     }
   }
 
@@ -286,93 +294,102 @@ std::string CProxyBodyGenerator::GenMethodDelegateAppend(const Interface& iface,
 }
 
 void CProxyBodyGenerator::GenMethodAsyncBase(std::ofstream& stream,
-    const Interface& iface, const Declaration& decl) {
+                                             const Interface& iface,
+                                             const Declaration& decl) {
   ReplaceAll(CB_INTERFACE_METHOD_ASYNC_BASE)
-      .Change("<PREFIX>", GetHandlePrefix())
-      .Change("<NAME>", iface.GetID())
-      .Change("<METHOD_NAME>", decl.GetID())
-      .Change("<METHOD_PARAMS>", GenMethodParams(iface, decl))
-      .Change("<METHOD_PARAMS_CHECK>", GenMethodParamsCheck(iface, decl))
+      .Replace("PREFIX", GetHandlePrefix())
+      .Replace("NAME", iface.GetID())
+      .Replace("METHOD_NAME", decl.GetID())
+      .Replace("METHOD_PARAMS", GenMethodParams(iface, decl))
+      .Replace("METHOD_PARAMS_CHECK", GenMethodParamsCheck(iface, decl))
       .ChangeToUpper("<UPPERCASE_PREFIX>", GetHandlePrefix())
       .ChangeToUpper("<UPPERCASE_NAME>", iface.GetID())
       .ChangeToUpper("<UPPERCASE_METHOD_NAME>", decl.GetID())
-      .Change("<METHOD_UNIT_MAP_WRITE>", GenMethodUnitMapWrite(iface, decl))
-      .Change("<METHOD_DELEGATE_APPEND>", GenMethodDelegateAppend(iface, decl))
+      .Replace("METHOD_UNIT_MAP_WRITE", GenMethodUnitMapWrite(iface, decl))
+      .Replace("METHOD_DELEGATE_APPEND", GenMethodDelegateAppend(iface, decl))
+      .Replace("HASH_METHOD", "[METHOD]"_hash)
       .Transform([&](std::string code) { return SmartIndent(code); })
       .Out(stream);
 }
 
 std::string CProxyBodyGenerator::GenMethodUnitMapReadBase(
-    const Interface& iface, const BaseType& type,
-    const std::string& arg_name, const std::string& arg) {
+    const Interface& iface, const BaseType& type, const std::string& arg_name,
+    const std::string& arg) {
   std::string code;
   if (type.GetUserDefinedType() == BaseType::UserType::DELEGATE ||
       type.GetUserDefinedType() == BaseType::UserType::STRUCTURE ||
       type.GetMetaType() != nullptr || type.GetKeyType() != nullptr) {
     code = ReplaceAll(CB_INTERFACE_METHOD_USER_DEFINED_UNIT_MAP_READ)
-        .Change("<TYPE_NAME>", GetFullNameFromType(type, iface))
-        .Change("<ARG_NAME>", arg_name)
-        .Change("<ARG>", arg);
+               .Replace("TYPE_NAME", GetFullNameFromType(type, iface))
+               .Replace("ARG_NAME", arg_name)
+               .Replace("HASH_ARG_NAME", GetHashCodeStr(arg_name))
+               .Replace("ARG", arg);
   } else if (type.GetUserDefinedType() == BaseType::UserType::ENUM) {
-     code += ReplaceAll(CB_INTERFACE_METHOD_EMUM_UNIT_MAP_READ)
-        .Change("<ARG_NAME>", arg_name)
-        .Change("<ARG>", arg);
+    code += ReplaceAll(CB_INTERFACE_METHOD_EMUM_UNIT_MAP_READ)
+                .Replace("ARG_NAME", arg_name)
+                .Replace("HASH_ARG_NAME", GetHashCodeStr(arg_name))
+                .Replace("ARG", arg);
   } else if (type.ToString() == "bundle") {
     code = ReplaceAll(CB_INTERFACE_METHOD_BUNDLE_UNIT_MAP_READ)
-        .Change("<ARG_NAME>", arg_name)
-        .Change("<ARG>", arg);
-  } else if (type.ToString() == "string" || type.ToString() == "file") {
+               .Replace("ARG_NAME", arg_name)
+               .Replace("HASH_ARG_NAME", GetHashCodeStr(arg_name))
+               .Replace("ARG", arg);
+  } else if (type.ToString() == "string") {
     code = ReplaceAll(CB_INTERFACE_METHOD_STRING_UNIT_MAP_READ)
-        .Change("<ARG_NAME>", arg_name)
-        .Change("<ARG>", arg);
+               .Replace("ARG_NAME", arg_name)
+               .Replace("HASH_ARG_NAME", GetHashCodeStr(arg_name))
+               .Replace("ARG", arg);
+  } else if (type.ToString() == "file") {
+    code = ReplaceAll(CB_INTERFACE_METHOD_FILE_UNIT_MAP_READ)
+               .Replace("ARG_NAME", arg_name)
+               .Replace("HASH_ARG_NAME", GetHashCodeStr(arg_name))
+               .Replace("ARG", arg);
   } else {
     code = ReplaceAll(CB_INTERFACE_METHOD_BASE_UNIT_MAP_READ)
-        .Change("<TYPE_NAME>", GetFullNameFromType(type, iface))
-        .Change("<ARG_NAME>", arg_name)
-        .Change("<ARG>", arg);
+               .Replace("TYPE_NAME", GetFullNameFromType(type, iface))
+               .Replace("ARG_NAME", arg_name)
+               .Replace("HASH_ARG_NAME", GetHashCodeStr(arg_name))
+               .Replace("ARG", arg);
   }
 
   return code;
 }
 
-std::string CProxyBodyGenerator::GenMethodRefFree(
-    const Interface& iface, const BaseType& type, const std::string& arg) {
+std::string CProxyBodyGenerator::GenMethodRefFree(const Interface& iface,
+                                                  const BaseType& type,
+                                                  const std::string& arg) {
   std::string code;
   if (type.GetUserDefinedType() == BaseType::UserType::DELEGATE ||
       type.GetUserDefinedType() == BaseType::UserType::STRUCTURE ||
       type.GetMetaType() != nullptr || type.GetKeyType() != nullptr) {
     code = ReplaceAll(CB_INTERFACE_METHOD_USER_DEFINED_REF_FREE)
-        .Change("<PREFIX>", GetHandlePrefix())
-        .Change("<NAME>", GetFullNameFromType(type, iface))
-        .Change("<ARG>", arg);
+               .Change("<PREFIX>", GetHandlePrefix())
+               .Change("<NAME>", GetFullNameFromType(type, iface))
+               .Change("<ARG>", arg);
   } else if (type.ToString() == "bundle") {
-    code = ReplaceAll(CB_INTERFACE_METHOD_BUNDLE_REF_FREE)
-        .Change("<ARG>", arg);
+    code = ReplaceAll(CB_INTERFACE_METHOD_BUNDLE_REF_FREE).Change("<ARG>", arg);
   } else if (type.ToString() == "string" || type.ToString() == "file") {
-    code = ReplaceAll(CB_INTERFACE_METHOD_STRING_REF_FREE)
-        .Change("<ARG>", arg);
+    code = ReplaceAll(CB_INTERFACE_METHOD_STRING_REF_FREE).Change("<ARG>", arg);
   }
 
   return code;
 }
 
 std::string CProxyBodyGenerator::GenMethodUnitMapRead(const Interface& iface,
-    const Declaration& decl) {
+                                                      const Declaration& decl) {
   std::string code;
   std::string parcel_read_code;
   for (const auto& p : decl.GetParameters()) {
     auto& param_type = p->GetParameterType();
-    if (param_type.GetDirection() == ParameterType::Direction::IN)
-      continue;
+    if (param_type.GetDirection() == ParameterType::Direction::IN) continue;
 
     auto& type = param_type.GetBaseType();
-    code += GenMethodUnitMapReadBase(iface, type, p->GetID(),
-        "new_" + p->GetID());
+    code +=
+        GenMethodUnitMapReadBase(iface, type, p->GetID(), "new_" + p->GetID());
     if (param_type.GetDirection() == ParameterType::Direction::REF)
       code += GenMethodRefFree(iface, type, p->GetID());
 
-    code += ReplaceAll(CB_INTERFACE_METHOD_PARAM_SET, "<PARAM>",
-        p->GetID());
+    code += ReplaceAll(CB_INTERFACE_METHOD_PARAM_SET, "<PARAM>", p->GetID());
   }
 
   auto& base_type = decl.GetType();
@@ -381,29 +398,32 @@ std::string CProxyBodyGenerator::GenMethodUnitMapRead(const Interface& iface,
 }
 
 void CProxyBodyGenerator::GenMethodBase(std::ofstream& stream,
-    const Interface& iface, const Declaration& decl) {
+                                        const Interface& iface,
+                                        const Declaration& decl) {
   ReplaceAll(CB_INTERFACE_METHOD_BASE)
-      .Change("<RETURN_TYPE>",
-              GetReturnTypeString(decl.GetType(), iface.GetID()))
-      .Change("<PREFIX>", GetHandlePrefix())
-      .Change("<NAME>", iface.GetID())
-      .Change("<METHOD_NAME>", decl.GetID())
-      .Change("<METHOD_PARAMS>", GenMethodParams(iface, decl))
-      .Change("<METHOD_ARGS>", GenMethodArgs(iface, decl, iface.GetID()))
-      .Change("<ERROR_VALUE>", GetErrorValue(decl.GetType()))
-      .Change("<METHOD_PARAMS_CHECK>", GenMethodParamsCheck(iface, decl))
+      .Replace("RETURN_TYPE",
+               GetReturnTypeString(decl.GetType(), iface.GetID()))
+      .Replace("PREFIX", GetHandlePrefix())
+      .Replace("NAME", iface.GetID())
+      .Replace("METHOD_NAME", decl.GetID())
+      .Replace("METHOD_PARAMS", GenMethodParams(iface, decl))
+      .Replace("METHOD_ARGS", GenMethodArgs(iface, decl, iface.GetID()))
+      .Replace("ERROR_VALUE", GetErrorValue(decl.GetType()))
+      .Replace("METHOD_PARAMS_CHECK", GenMethodParamsCheck(iface, decl))
       .ChangeToUpper("<UPPERCASE_PREFIX>", GetHandlePrefix())
       .ChangeToUpper("<UPPERCASE_NAME>", iface.GetID())
       .ChangeToUpper("<UPPERCASE_METHOD_NAME>", decl.GetID())
-      .Change("<METHOD_UNIT_MAP_WRITE>", GenMethodUnitMapWrite(iface, decl))
-      .Change("<METHOD_UNIT_MAP_READ>", GenMethodUnitMapRead(iface, decl))
-      .Change("<METHOD_DELEGATE_APPEND>", GenMethodDelegateAppend(iface, decl))
+      .Replace("METHOD_UNIT_MAP_WRITE", GenMethodUnitMapWrite(iface, decl))
+      .Replace("METHOD_UNIT_MAP_READ", GenMethodUnitMapRead(iface, decl))
+      .Replace("METHOD_DELEGATE_APPEND", GenMethodDelegateAppend(iface, decl))
+      .Replace("HASH_METHOD", "[METHOD]"_hash)
       .Transform([&](std::string code) { return SmartIndent(code); })
       .Out(stream);
 }
 
 void CProxyBodyGenerator::GenInterfaceMethodBase(std::ofstream& stream,
-    const Interface& iface, const Declaration& decl) {
+                                                 const Interface& iface,
+                                                 const Declaration& decl) {
   std::string code;
   auto method_type = decl.GetMethodType();
   if (method_type == Declaration::MethodType::ASYNC)
@@ -412,160 +432,141 @@ void CProxyBodyGenerator::GenInterfaceMethodBase(std::ofstream& stream,
     GenMethodBase(stream, iface, decl);
 }
 
-void CProxyBodyGenerator::GenInterfaceBase(std::ofstream& stream,
-    const Interface& iface) {
+std::string CProxyBodyGenerator::GetInterfaceBase(const Interface& iface) {
   std::string prefix = GetHandlePrefix();
   std::string name = iface.GetID();
   std::string event = HasDelegate() ? CB_INTERFACE_DELEGATE_REGISTER_EVENT : "";
 
-  ReplaceAll(CB_INTERFACE_BASE)
-      .Change("<DELEGATE_REGISTER_EVENT>", event)
-      .Change("<PREFIX>", prefix)
-      .Change("<NAME>", name)
-      .Change("<PREFIX_REVERSE>", GetHandlePrefixReverse())
+  return ReplaceAll(CB_INTERFACE_BASE)
+      .Replace("DELEGATE_REGISTER_EVENT", event)
+      .Replace("PREFIX", prefix)
+      .Replace("NAME", name)
+      .Replace("PREFIX_REVERSE", GetHandlePrefixReverse())
       .ChangeToUpper("<UPPERCASE_PREFIX>", prefix)
       .ChangeToUpper("<UPPERCASE_NAME>", name)
+      .Replace("HASH_METHOD", "[METHOD]"_hash)
+      .Replace("HASH_REMOTE_EXCEPTION", "[REMOTE_EXCEPTION]"_hash)
       .Transform([&](std::string code) { return SmartIndent(code); })
-      .Out(stream);
+      .ToString();
 }
 
-void CProxyBodyGenerator::GenInterfaceMethodEnumBase(std::ofstream& stream,
+std::string CProxyBodyGenerator::GetInterfaceMethodEnumBase(
     const Interface& iface) {
-  std::string enums = GetHandlePrefix() + "_" + iface.GetID() +
-      "_METHOD_RESULT_," + NLine(1);
-  enums += GetHandlePrefix() + "_" + iface.GetID() + "_METHOD_CALLBACK_," +
-      NLine(1);
+  std::string enums =
+      GetHandlePrefix() + "_" + iface.GetID() + "_METHOD_RESULT_," + NLine(1);
+  enums +=
+      GetHandlePrefix() + "_" + iface.GetID() + "_METHOD_CALLBACK_," + NLine(1);
 
   for (const auto& decl : iface.GetDeclarations()) {
-    if (decl->GetMethodType() == Declaration::MethodType::DELEGATE)
-      continue;
+    if (decl->GetMethodType() == Declaration::MethodType::DELEGATE) continue;
 
     enums += GetHandlePrefix() + "_" + iface.GetID() + "_METHOD_" +
-        decl->GetID() + "," + NLine(1);
+             decl->GetID() + "," + NLine(1);
   }
 
-  ReplaceAll(CB_INTERFACE_METHOD_ENUM_BASE)
+  return ReplaceAll(CB_INTERFACE_METHOD_ENUM_BASE)
       .ChangeToUpper("<ENUMS>", enums)
       .Change("<PREFIX>", GetHandlePrefix())
       .Change("<NAME>", iface.GetID())
       .Transform([&](std::string code) { return SmartIndent(code); })
-      .Out(stream);
+      .ToString();
 }
 
-void CProxyBodyGenerator::GenDelegateProcess(std::ofstream& stream,
-    const Interface& iface) {
-  if (!HasDelegate())
-    return;
+std::string CProxyBodyGenerator::GetDelegateProcess(const Interface& iface) {
+  if (!HasDelegate()) return "";
 
   std::string prefix = GetHandlePrefix();
   std::string name = iface.GetID();
 
-  ReplaceAll(CB_INTERFACE_DELEGATE_PROCESS_BASE)
-      .Change("<PREFIX>", prefix)
-      .Change("<NAME>", name)
+  return ReplaceAll(CB_INTERFACE_DELEGATE_PROCESS_BASE)
+      .Replace("PREFIX", prefix)
+      .Replace("NAME", name)
       .ChangeToUpper("<UPPERCASE_PREFIX>", prefix)
       .ChangeToUpper("<UPPERCASE_NAME>", name)
+      .Replace("HASH_DELEGATE", "delegate"_hash)
+      .Replace("HASH_METHOD", "[METHOD]"_hash)
       .Transform([&](std::string code) { return SmartIndent(code); })
-      .Out(stream);
+      .ToString();
 }
 
-void CProxyBodyGenerator::GenInterfaceDelegateTable(std::ofstream& stream,
+std::string CProxyBodyGenerator::GetInterfaceDelegateTable(
     const Interface& iface) {
-  if (!HasDelegate())
-    return;
+  if (!HasDelegate()) return "";
 
   std::string delegate_handlers;
   for (const auto& decl : iface.GetDeclarations()) {
-    if (decl->GetMethodType() != Declaration::MethodType::DELEGATE)
-      continue;
-
-    std::string enum_value = GetHandlePrefix() + "_" + iface.GetID() +
-      "_DELEGATE_" + decl->GetID();
-    delegate_handlers += ReplaceAll(CB_INTERFACE_DELEGATE_TABLE_MEMBER)
-        .ChangeToUpper("<ENUM_VALUE>", enum_value)
-        .Change("<PREFIX>", GetHandlePrefix())
-        .Change("<NAME>", iface.GetID())
-        .Change("<DELEGATE_NAME>", decl->GetID())
-        .Transform([&](std::string code) { return RemoveLine(code); });
+    if (decl->GetMethodType() != Declaration::MethodType::DELEGATE) continue;
+
+    std::string enum_value =
+        GetHandlePrefix() + "_" + iface.GetID() + "_DELEGATE_" + decl->GetID();
+    delegate_handlers +=
+        ReplaceAll(CB_INTERFACE_DELEGATE_TABLE_MEMBER)
+            .ChangeToUpper("<ENUM_VALUE>", enum_value)
+            .Change("<PREFIX>", GetHandlePrefix())
+            .Change("<NAME>", iface.GetID())
+            .Change("<DELEGATE_NAME>", decl->GetID())
+            .Transform([&](std::string code) { return RemoveLine(code); });
   }
 
-  if (delegate_handlers.empty())
-    delegate_handlers = "nullptr," + NLine(1);
+  if (delegate_handlers.empty()) delegate_handlers = "nullptr," + NLine(1);
 
-  ReplaceAll(CB_INTERFACE_DELEGATE_TABLE)
+  return ReplaceAll(CB_INTERFACE_DELEGATE_TABLE)
       .Change("<PREFIX>", GetHandlePrefix())
       .Change("<NAME>", iface.GetID())
       .Change("<DELEGATE_HANDLERS>", delegate_handlers)
       .Transform([&](std::string code) { return SmartIndent(code); })
-      .Out(stream);
-}
-
-void CProxyBodyGenerator::GenInterfaceDelegateBase(std::ofstream& stream,
-    const Interface& iface, const Declaration& decl) {
-  std::string enum_value = GetHandlePrefix() + "_" + iface.GetID() +
-      "_DELEGATE_" + decl.GetID();
-  bool has_free = false;
-  std::string delegate_args_free = GenDelegateArgsFree(iface, decl, &has_free);
-
-  ReplaceAll(CB_INTERFACE_DELEGATE_BASE)
-      .Change("<PREFIX>", GetHandlePrefix())
-      .Change("<NAME>", iface.GetID())
-      .Change("<DELEGATE_NAME>", decl.GetID())
-      .ChangeToUpper("<DELEGATE_ENUM_VALUE>", enum_value)
-      .Change("<DELEGATE_ARGS_DECL>", GenDelegateArgsDecl(iface, decl))
-      .Change("<DELEGATE_UNIT_MAP_READ>", GenDelegateUnitMapRead(iface, decl))
-      .Change("<DELEGATE_ARGS_FREE>", delegate_args_free)
-      .Change("<DELEGATE_CALLBACK_ARGS>", GenDelegateCallbackArgs(decl))
-      .Transform([&](std::string code) { return SmartIndent(code); })
-      .Out(stream);
+      .ToString();
 }
 
 std::string CProxyBodyGenerator::GenDelegateCallbackArgs(
     const Declaration& decl) {
   std::string code;
-  for (const auto& param : decl.GetParameters())
-    code += ", " + param->GetID();
+  for (const auto& param : decl.GetParameters()) code += ", " + param->GetID();
 
   return code;
 }
 
-std::string CProxyBodyGenerator::GenDelegateUnitMapRead(const Interface& iface,
-    const Declaration& decl) {
+std::string CProxyBodyGenerator::GenDelegateUnitMapRead(
+    const Interface& iface, const Declaration& decl) {
   std::string code;
   for (const auto& param : decl.GetParameters()) {
     auto& param_type = param->GetParameterType();
     auto& type = param_type.GetBaseType();
     if (type.GetUserDefinedType() == BaseType::UserType::DELEGATE ||
         type.GetUserDefinedType() == BaseType::UserType::STRUCTURE ||
-        type.ToString() == "list" ||
-        type.ToString() == "array") {
+        type.ToString() == "list" || type.ToString() == "array") {
       code += ReplaceAll(CB_INTERFACE_DELEGATE_USER_DEFINED_UNIT_MAP_READ)
-          .Change("<TYPE_NAME>", GetFullNameFromType(type, iface))
-          .Change("<ARG>", param->GetID());
+                  .Replace("TYPE_NAME", GetFullNameFromType(type, iface))
+                  .Replace("ARG", param->GetID())
+                  .Replace("HASH_ARG", GetHashCodeStr(param->GetID()));
 
     } else if (type.GetUserDefinedType() == BaseType::UserType::ENUM) {
       code += ReplaceAll(CB_INTERFACE_DELEGATE_ENUM_UNIT_MAP_READ)
-          .Change("<ARG_NAME>", param->GetID())
-          .Change("<ARG>", param->GetID());
+                  .Replace("ARG_NAME", param->GetID())
+                  .Replace("ARG", param->GetID())
+                  .Replace("HASH_ARG_NAME", GetHashCodeStr(param->GetID()));
     } else if (type.ToString() == "bundle") {
       code += ReplaceAll(CB_INTERFACE_DELEGATE_BUNDLE_UNIT_MAP_READ)
-          .Change("<ARG>", param->GetID());
+                  .Replace("ARG", param->GetID())
+                  .Replace("HASH_ARG", GetHashCodeStr(param->GetID()));
     } else if (type.ToString() == "string" || type.ToString() == "file") {
       code += ReplaceAll(CB_INTERFACE_DELEGATE_STRING_UNIT_MAP_READ)
-          .Change("<ARG>", param->GetID());
+                  .Replace("ARG", param->GetID())
+                  .Replace("HASH_ARG", GetHashCodeStr(param->GetID()));
     } else {
       code += ReplaceAll(CB_INTERFACE_DELEGATE_BASE_UNIT_MAP_READ)
-          .Change("<TYPE_NAME>", GetFullNameFromType(type, iface))
-          .Change("<ARG_NAME>", param->GetID())
-          .Change("<ARG>", param->GetID());
-     }
+                  .Replace("TYPE_NAME", GetFullNameFromType(type, iface))
+                  .Replace("ARG_NAME", param->GetID())
+                  .Replace("ARG", param->GetID())
+                  .Replace("HASH_ARG_NAME", GetHashCodeStr(param->GetID()));
+    }
   }
 
   return RemoveLine(code);
 }
 
 std::string CProxyBodyGenerator::GenDelegateArgsDecl(const Interface& iface,
-    const Declaration& decl) {
+                                                     const Declaration& decl) {
   std::string code;
   for (const auto& param : decl.GetParameters()) {
     auto& param_type = param->GetParameterType();
@@ -574,34 +575,34 @@ std::string CProxyBodyGenerator::GenDelegateArgsDecl(const Interface& iface,
       code += GetArgTypeString(type, iface) + param->GetID() + ";" + NLine(1);
     else
       code += GetArgTypeString(type, iface) + param->GetID() + " = " +
-          GetErrorValue(param_type.GetBaseType()) + ";" + NLine(1);
+              GetErrorValue(param_type.GetBaseType()) + ";" + NLine(1);
   }
 
   return code;
 }
 
 std::string CProxyBodyGenerator::GenDelegateArgsFree(const Interface& iface,
-    const Declaration& decl, bool* has_free) {
+                                                     const Declaration& decl,
+                                                     bool* has_free) {
   std::string code;
   for (const auto& param : decl.GetParameters()) {
     auto& param_type = param->GetParameterType();
     auto& type = param_type.GetBaseType();
-    if (type.GetUserDefinedType() == BaseType::UserType::STRUCTURE  ||
-        type.GetUserDefinedType() == BaseType::UserType::DELEGATE  ||
-        type.ToString() == "list" ||
-        type.ToString() == "array") {
+    if (type.GetUserDefinedType() == BaseType::UserType::STRUCTURE ||
+        type.GetUserDefinedType() == BaseType::UserType::DELEGATE ||
+        type.ToString() == "list" || type.ToString() == "array") {
       code += ReplaceAll(CB_INTERFACE_DELEGATE_USER_DEFINED_ARG_FREE)
-          .Change("<PREFIX>", GetHandlePrefix())
-          .Change("<NAME>", GetFullNameFromType(type, iface))
-          .Change("<ARG>", param->GetID());
+                  .Change("<PREFIX>", GetHandlePrefix())
+                  .Change("<NAME>", GetFullNameFromType(type, iface))
+                  .Change("<ARG>", param->GetID());
       *has_free = true;
     } else if (type.ToString() == "bundle") {
-      code += ReplaceAll(CB_INTERFACE_DELEGATE_BUNDLE_ARG_FREE,
-          "<ARG>", param->GetID());
+      code += ReplaceAll(CB_INTERFACE_DELEGATE_BUNDLE_ARG_FREE, "<ARG>",
+                         param->GetID());
       *has_free = true;
     } else if (type.ToString() == "string" || type.ToString() == "file") {
-      code += ReplaceAll(CB_INTERFACE_DELEGATE_STRING_ARG_FREE,
-          "<ARG>", param->GetID());
+      code += ReplaceAll(CB_INTERFACE_DELEGATE_STRING_ARG_FREE, "<ARG>",
+                         param->GetID());
       *has_free = true;
     }
   }
@@ -609,30 +610,5 @@ std::string CProxyBodyGenerator::GenDelegateArgsFree(const Interface& iface,
   return RemoveLine(code);
 }
 
-void CProxyBodyGenerator::GenInterfaceDelegateEnumBase(std::ofstream& stream,
-    const Interface& iface) {
-  unsigned int num = 1;
-  std::string enums;
-  for (const auto& decl : iface.GetDeclarations()) {
-    if (decl->GetMethodType() != Declaration::MethodType::DELEGATE)
-      continue;
-
-    enums += GetHandlePrefix() + "_" + iface.GetID() + "_DELEGATE_" +
-        decl->GetID();
-    enums += " = " + std::to_string(num++) + ",";
-    enums += NLine(1);
-  }
-
-  if (enums.empty())
-    return;
-
-  ReplaceAll(CB_INTERFACE_DELEGATE_ENUM_BASE)
-      .ChangeToUpper("<ENUMS>", enums)
-      .Change("<PREFIX>", GetHandlePrefix())
-      .Change("<NAME>", iface.GetID())
-      .Transform([&](std::string code) { return SmartIndent(code); })
-      .Out(stream);
-}
-
 }  // namespace version2
 }  // namespace tidl
index ff26d0842e4f1968541cb09fa20de9f1bfa0994e..ea9e08221350539e1b3146d8cd3f700c107b9354 100644 (file)
@@ -29,24 +29,15 @@ namespace version2 {
 class CProxyBodyGenerator : public CBodyGeneratorBase {
  public:
   explicit CProxyBodyGenerator(std::shared_ptr<Document> doc,
-      std::shared_ptr<Options> options);
+                               std::shared_ptr<Options> options);
   virtual ~CProxyBodyGenerator() = default;
 
   void OnInitGen(std::ofstream& stream) override;
   void OnFiniGen(std::ofstream& stream) override;
 
  private:
-  void GenInterfaceDelegateCallback(std::ofstream& stream);
-  void GenInterfaceDefinition(std::ofstream& stream);
-  void GenInterfaceDelegateDefinition(std::ofstream& stream,
-                                      const Interface& iface,
-                                      const Declaration& decl);
-  void GenInterfaceBaseDefinition(std::ofstream& stream,
-                                  const Interface& iface);
-  void GenInterface(std::ofstream& stream);
   std::string GenMethodParams(const Interface& iface, const Declaration& decl);
-  std::string GenMethodArgs(const Interface& iface,
-                            const Declaration& decl,
+  std::string GenMethodArgs(const Interface& iface, const Declaration& decl,
                             const std::string& id);
   std::string GenMethodParamsCheck(const Interface& iface,
                                    const Declaration& decl);
@@ -68,13 +59,10 @@ class CProxyBodyGenerator : public CBodyGeneratorBase {
                      const Declaration& decl);
   void GenInterfaceMethodBase(std::ofstream& stream, const Interface& iface,
                               const Declaration& decl);
-  void GenInterfaceBase(std::ofstream& stream, const Interface& iface);
-  void GenInterfaceMethodEnumBase(std::ofstream& stream,
-                                  const Interface& iface);
-  void GenInterfaceDelegateTable(std::ofstream& stream, const Interface& iface);
-  void GenInterfaceDelegateBase(std::ofstream& stream, const Interface& iface,
-                                const Declaration& decl);
-  void GenDelegateProcess(std::ofstream& stream, const Interface& iface);
+  std::string GetInterfaceBase(const Interface& iface);
+  std::string GetInterfaceMethodEnumBase(const Interface& iface);
+  std::string GetInterfaceDelegateTable(const Interface& iface);
+  std::string GetDelegateProcess(const Interface& iface);
   std::string GenDelegateCallbackArgs(const Declaration& decl);
   std::string GenDelegateUnitMapRead(const Interface& iface,
                                      const Declaration& decl);
@@ -82,13 +70,7 @@ class CProxyBodyGenerator : public CBodyGeneratorBase {
                                   const Declaration& decl);
   std::string GenDelegateArgsFree(const Interface& iface,
                                   const Declaration& decl, bool* has_free);
-  void GenInterfaceDelegateEnumBase(std::ofstream& stream,
-                                    const Interface& iface);
-  void GenDelegateDefinition(std::ofstream& stream);
-  void GenDelegateBase(std::ofstream& stream);
-  void GenLemDefinition(std::ofstream& stream);
-  void GenLemBase(std::ofstream& stream);
-  void GenLemAPI(std::ofstream& stream);
+  std::string GetLemBase();
 
  private:
   std::shared_ptr<Options> options_;
index ed3a7c3b645d431d91ca564ec8b74784f5679a11..e2df999115beb2ef636ea4dc4911c2bde7ead282 100644 (file)
 namespace tidl {
 namespace version2 {
 
-constexpr const char CB_DELEGATE_DEFS[] =
+constexpr const char CB_MAIN_PROXY[] =
 R"__c_cb(
+/*
+ * Generated by tidlc <VERSION>.
+ */
+
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+
+#pragma GCC diagnostic ignored "-Warray-bounds"
+#pragma GCC diagnostic ignored "-Wunused-function"
+
+#include <pthread.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <libgen.h>
+#include <glib.h>
+#include <dlog.h>
+#include <rpc-port.h>
+#include <rpc-port-parcel.h>
+#include <unistd.h>
+#include <dlfcn.h>
+#include <app_common.h>
+<INCLUDE>
+
+#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(__FILE__), __FUNCTION__, __LINE__, ##__VA_ARGS__)
+
+#undef _W
+#define _W(fmt, ...) dlog_print(DLOG_WARN, LOG_TAG, "%s: %s(%d) > "fmt, basename(__FILE__), __FUNCTION__, __LINE__, ##__VA_ARGS__)
+
+#undef _I
+#define _I(fmt, ...) dlog_print(DLOG_INFO, LOG_TAG, "%s: %s(%d) > "fmt, basename(__FILE__), __FUNCTION__, __LINE__, ##__VA_ARGS__)
+
+#undef _D
+#define _D(fmt, ...) dlog_print(DLOG_DEBUG, LOG_TAG, "%s: %s(%d) > "fmt, basename(__FILE__), __FUNCTION__, __LINE__, ##__VA_ARGS__)
+
+#ifndef TIDL_VERSION
+#define TIDL_VERSION "<VERSION>"
+#endif
+
+#ifndef nullptr
+#define nullptr NULL
+#endif
+
+#ifndef ARRAY_SIZE
+#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
+#endif
+
+#ifndef STRING_GET
+#define STRING_GET(x) ((x) ? x : "")
+#endif
+
+#ifndef EXPORT_API
+#define EXPORT_API extern "C" __attribute__ ((visibility("default")))
+#endif
+
+<RPC_PORT_INTERNAL_APIS>
+<UNIT_MAP_DEFINITION>
+
+typedef int (*rpc_port_stub_lem_connect_func)(void *context, const char *appid, const char *instance, bool sync);
+typedef void (*rpc_port_stub_lem_disconnect_func)(void *context, const char *appid, const char *instance);
+typedef int (*rpc_port_stub_lem_send_func)(void *context, const char *appid, const char *instance, rpc_port_parcel_h h);
+
+typedef void (*rpc_port_proxy_lem_connected_cb)(void *context);
+typedef void (*rpc_port_proxy_lem_disconnected_cb)(void* context);
+typedef void (*rpc_port_proxy_lem_received_cb)(void* context, rpc_port_parcel_h);
+
+typedef struct {
+  rpc_port_proxy_lem_connected_cb connected;
+  rpc_port_proxy_lem_disconnected_cb disconnected;
+  rpc_port_proxy_lem_received_cb received;
+} rpc_port_proxy_lem_event_s;
+
+typedef struct {
+  void *context;
+  rpc_port_proxy_lem_event_s callback;
+  char *port_name;
+  char *instance;
+  rpc_port_stub_lem_connect_func connect_func;
+  rpc_port_stub_lem_disconnect_func disconnect_func;
+  rpc_port_stub_lem_send_func send_func;
+  bool connected;
+  bool connecting;
+  bool loaded;
+  GQueue *result_queue;
+  GQueue *request_queue;
+  GRecMutex mutex;
+  GMainContext *thread_context;
+} rpc_port_proxy_lem_s;
+
+typedef rpc_port_proxy_lem_s *rpc_port_proxy_lem_h;
+
 typedef struct rpc_port_delegate_s {
   rpc_port_parcelable_t parcelable;
   int id;
@@ -31,46 +127,67 @@ typedef struct rpc_port_delegate_s {
 
 typedef rpc_port_delegate_t *rpc_port_delegate_h;
 
+<HAS_DELEGATE?>
 static rpc_port_delegate_h rpc_port_delegate_create();
-)__c_cb";
+</HAS_DELEGATE?>
 
-constexpr const char CB_DELEGATE_BASE[] =
-R"__c_cb(
+typedef void (*rpc_port_proxy_delegate_cb)(GList **delegates, rpc_port_unit_map_h map, rpc_port_delegate_h delegate);
+
+<STRUCTURE_DEFINITION>
+<REMOTE_EXCEPTION_DEFINITION>
+
+<INTERFACE_DEFINITIONS*>
+
+<DELEGATE_DEFINITIONS*>
+typedef struct <PREFIX>_<NAME>_<DELEGATE_NAME>_s {
+  rpc_port_parcelable_t parcelable;
+  int id;
+  int seq_id;
+  bool once;
+  <PREFIX>_<NAME>_<DELEGATE_NAME>_cb callback;
+  void *user_data;
+} <PREFIX>_<NAME>_<DELEGATE_NAME>_t;
+
+</DELEGATE_DEFINITIONS*>
+typedef struct <PREFIX>_<NAME>_s {
+  char *stub_appid;
+  rpc_port_proxy_h proxy;
+  rpc_port_h port;
+  rpc_port_h callback_port;
+  <PREFIX>_<NAME>_callback_s callback;
+  void *user_data;
+  GList *delegates;
+  GRecMutex mutex;
+  rpc_port_proxy_lem_h lem;
+} <PREFIX>_<NAME>_t;
+
+<PREFIX>_<NAME>_h __<PREFIX>_<NAME>_handle;
+
+</INTERFACE_DEFINITIONS*>
+
+<UNIT_MAP_BASE>
+<LEM_BASE>
+
+<HAS_DELEGATE?>
 static void __rpc_port_delegate_to(rpc_port_parcel_h parcel, void *user_data)
 {
   rpc_port_delegate_h delegate = user_data;
-  rpc_port_unit_map_h map;
 
-  map = rpc_port_unit_map_create();
-  if (map == nullptr) {
-    set_last_result(RPC_PORT_ERROR_OUT_OF_MEMORY);
-    return;
-  }
+  rpc_port_parcel_write_int32(parcel, delegate->id);
+  rpc_port_parcel_write_int32(parcel, delegate->seq_id);
+  rpc_port_parcel_write_bool(parcel, delegate->once);
 
-  rpc_port_unit_map_write_int(map, "id", delegate->id);
-  rpc_port_unit_map_write_int(map, "seq_id", delegate->seq_id);
-  rpc_port_unit_map_write_bool(map, "once", delegate->once);
-  rpc_port_parcel_write(parcel, &map->parcelable, map);
-  rpc_port_unit_map_destroy(map);
   set_last_result(RPC_PORT_ERROR_NONE);
 }
 
 static void __rpc_port_delegate_from(rpc_port_parcel_h parcel, void *user_data)
 {
   rpc_port_delegate_h delegate = user_data;
-  rpc_port_unit_map_h map;
 
-  map = rpc_port_unit_map_create();
-  if (map == nullptr) {
-    set_last_result(RPC_PORT_ERROR_OUT_OF_MEMORY);
-    return;
-  }
+  rpc_port_parcel_read_int32(parcel, &delegate->id);
+  rpc_port_parcel_read_int32(parcel, &delegate->seq_id);
+  rpc_port_parcel_read_bool(parcel, &delegate->once);
 
-  rpc_port_parcel_read(parcel, &map->parcelable, map);
-  rpc_port_unit_map_read_int(map, "id", &delegate->id);
-  rpc_port_unit_map_read_int(map, "seq_id", &delegate->seq_id);
-  rpc_port_unit_map_read_bool(map, "once", &delegate->once);
-  rpc_port_unit_map_destroy(map);
   set_last_result(RPC_PORT_ERROR_NONE);
 }
 
@@ -97,59 +214,26 @@ static rpc_port_delegate_h rpc_port_delegate_create()
 
   return delegate;
 }
-)__c_cb";
+</HAS_DELEGATE?>
 
-constexpr const char CB_INTERFACE_DELEGATE_CALLBACK[] =
-R"__c_cb(
-typedef void (*rpc_port_proxy_delegate_cb)(GList **delegates, rpc_port_unit_map_h map, rpc_port_delegate_h delegate);
-)__c_cb";
+<PRIVATE_SHARING_LIST_SET>
+<STRUCTURE>
+<REMOTE_EXCEPTION_BASE>
 
-/**
- * <ENUMS> The enumeration of the interface delegate.
- * <PREFIX> The prefix of the interface.
- * <NAME> The name of the interface.
- */
-constexpr const char CB_INTERFACE_DELEGATE_ENUM_BASE[] =
-R"__c_cb(
+<INTERFACES*>
+
+<HAS_DELEGATE?>
 typedef enum {
-  <ENUMS>
+  <ENUM_FIELDS*>
+  <UPPER_PREFIX>_<UPPER_NAME>_DELEGATE_<UPPER_ID> = <CNT>,
+  </ENUM_FIELDS*>
 } <PREFIX>_<NAME>_delegate_e;
-)__c_cb";
-
-/**
- * <PREFIX> The prefix of the interface.
- * <NAME> The name of the interface.
- * <DELEGATE_NAME> The name of the delegate of the interface.
- */
-constexpr const char CB_INTERFACE_DELEGATE_DEF[] =
-R"__c_cb(
-typedef struct <PREFIX>_<NAME>_<DELEGATE_NAME>_s {
-  rpc_port_parcelable_t parcelable;
-  int id;
-  int seq_id;
-  bool once;
-  <PREFIX>_<NAME>_<DELEGATE_NAME>_cb callback;
-  void *user_data;
-} <PREFIX>_<NAME>_<DELEGATE_NAME>_t;
-)__c_cb";
+</HAS_DELEGATE?>
 
-/**
- * <PREFIX> The prefix of the interface.
- * <NAME> The name of the interface.
- * <DELEGATE_NAME> The name of the delegate of the interface.
- * <DELEGATE_ENUM_VALUE> The enumeration value of the delegate.
- * <DELEGATE_ARGS_DECL> The implementation to declares the arguments.
- * <DELEGATE_PARCEL_READ> The implementation to read the arguments from the parcel.
- * <DELEGATE_ARGS_FREE> The implementation to release the allocated arguments.
- * <DELEGATE_CALLBACK_ARGS> The arguments of the delegate callback.
- * <GOTO_STATEMENT> The statement label.
- */
-constexpr const char CB_INTERFACE_DELEGATE_BASE[] =
-R"__c_cb(
+<INTERFACE_DELEGATE_BASES*>
 static void __<PREFIX>_<NAME>_<DELEGATE_NAME>_to(rpc_port_parcel_h parcel, void *data)
 {
   <PREFIX>_<NAME>_<DELEGATE_NAME>_h h = data;
-  rpc_port_unit_map_h map;
 
   if (parcel == nullptr || h == nullptr) {
     _E("Invalid parameter");
@@ -157,19 +241,9 @@ static void __<PREFIX>_<NAME>_<DELEGATE_NAME>_to(rpc_port_parcel_h parcel, void
     return;
   }
 
-  map = rpc_port_unit_map_create();
-  if (map == nullptr) {
-    _E("Failed to create unit map");
-    set_last_result(RPC_PORT_ERROR_OUT_OF_MEMORY);
-    return;
-  }
-
-  rpc_port_unit_map_write_int(map, "id", h->id);
-  rpc_port_unit_map_write_int(map, "seq_id", h->seq_id);
-  rpc_port_unit_map_write_bool(map, "once", h->once);
-
-  rpc_port_parcel_write(parcel, &map->parcelable, map);
-  rpc_port_unit_map_destroy(map);
+  rpc_port_parcel_write_int32(parcel, h->id);
+  rpc_port_parcel_write_int32(parcel, h->seq_id);
+  rpc_port_parcel_write_bool(parcel, h->once);
 
   _I("id(%d), seq_id(%d), once(%s)", h->id, h->seq_id, h->once ? "true" : "false");
   set_last_result(RPC_PORT_ERROR_NONE);
@@ -178,7 +252,6 @@ static void __<PREFIX>_<NAME>_<DELEGATE_NAME>_to(rpc_port_parcel_h parcel, void
 static void __<PREFIX>_<NAME>_<DELEGATE_NAME>_from(rpc_port_parcel_h parcel, void *data)
 {
   <PREFIX>_<NAME>_<DELEGATE_NAME>_h h = data;
-  rpc_port_unit_map_h map;
 
   if (parcel == nullptr || h == nullptr) {
     _E("Invalid parameter");
@@ -186,19 +259,9 @@ static void __<PREFIX>_<NAME>_<DELEGATE_NAME>_from(rpc_port_parcel_h parcel, voi
     return;
   }
 
-  map = rpc_port_unit_map_create();
-  if (map == nullptr) {
-    _E("Failed to create unit map");
-    set_last_result(RPC_PORT_ERROR_OUT_OF_MEMORY);
-    return;
-  }
-
-  rpc_port_parcel_read(parcel, &map->parcelable, map);
-  rpc_port_unit_map_read_int(map, "id", &h->id);
-  rpc_port_unit_map_read_int(map, "seq_id", &h->seq_id);
-  rpc_port_unit_map_read_bool(map, "once", &h->once);
-
-  rpc_port_unit_map_destroy(map);
+  rpc_port_parcel_read_int32(parcel, &h->id);
+  rpc_port_parcel_read_int32(parcel, &h->seq_id);
+  rpc_port_parcel_read_bool(parcel, &h->once);
 
   _I("id(%d), seq_id(%d), once(%s)", h->id, h->seq_id, h->once ? "true" : "false");
   set_last_result(RPC_PORT_ERROR_NONE);
@@ -247,7 +310,7 @@ int <PREFIX>_<NAME>_<DELEGATE_NAME>_destroy(<PREFIX>_<NAME>_<DELEGATE_NAME>_h h)
 
 int <PREFIX>_<NAME>_<DELEGATE_NAME>_clone(<PREFIX>_<NAME>_<DELEGATE_NAME>_h h, <PREFIX>_<NAME>_<DELEGATE_NAME>_h *clone)
 {
-  rpc_port_unit_map_h map;
+  <PREFIX>_<NAME>_<DELEGATE_NAME>_h handle;
   int ret;
 
   if (h == nullptr || clone == nullptr) {
@@ -255,23 +318,20 @@ int <PREFIX>_<NAME>_<DELEGATE_NAME>_clone(<PREFIX>_<NAME>_<DELEGATE_NAME>_h h, <
     return RPC_PORT_ERROR_INVALID_PARAMETER;
   }
 
-  map = rpc_port_unit_map_create();
-  if (map == nullptr) {
-    _E("Failed to create unit map");
-    return RPC_PORT_ERROR_OUT_OF_MEMORY;
-  }
-
-  ret = rpc_port_unit_map_write_<NAME>_<DELEGATE_NAME>(map, "clone", h);
+  ret = <PREFIX>_<NAME>_<DELEGATE_NAME>_create(&handle);
   if (ret != RPC_PORT_ERROR_NONE) {
-    _E("Failed to write <DELEGATE_NAME>. error(%d)", ret);
-    rpc_port_unit_map_destroy(map);
+    _E("Failed to create handle. error(%d)", ret);
     return ret;
   }
 
-  rpc_port_unit_map_read_<NAME>_<DELEGATE_NAME>(map, "clone", clone);
-  rpc_port_unit_map_destroy(map);
+  handle->id = h->id;
+  handle->seq_id = h->seq_id;
+  handle->once = h->once;
+  handle->callback = h->callback;
+  handle->user_data = h->user_data;
 
-  return ret;
+  *clone = handle;
+  return RPC_PORT_ERROR_NONE;
 }
 
 int <PREFIX>_<NAME>_<DELEGATE_NAME>_set_callback(<PREFIX>_<NAME>_<DELEGATE_NAME>_h h, <PREFIX>_<NAME>_<DELEGATE_NAME>_cb callback, void *user_data)
@@ -416,6 +476,362 @@ static void __<PREFIX>_<NAME>_<DELEGATE_NAME>_delegate_handler(GList **delegates
   <DELEGATE_ARGS_FREE>
   return;
 }
+
+</INTERFACE_DELEGATE_BASES*>
+
+<INTERFACE_DELEGATE_TABLE>
+<INTERFACE_METHOD_ENUM_BASE>
+<DELEGATE_PROCESS>
+<INTERFACE_BASE>
+<METHODS*>
+
+<ASYNC?>
+void <PREFIX>_<NAME>_invoke_<METHOD_NAME>(<PREFIX>_<NAME>_h h<METHOD_PARAMS>)
+{
+  rpc_port_parcel_h parcel_;
+  rpc_port_parcel_header_h header_;
+  rpc_port_unit_map_h map_;
+  int seq_num_ = -1;
+  int res_;
+  int method_ = <UPPERCASE_PREFIX>_<UPPERCASE_NAME>_METHOD_<UPPERCASE_METHOD_NAME>;
+
+  if (h == nullptr<METHOD_PARAMS_CHECK>) {
+    _E("Invalid parameter");
+    set_last_result(RPC_PORT_ERROR_INVALID_PARAMETER);
+    return;
+  }
+
+  if (h->port == nullptr && !rpc_port_proxy_lem_is_connected(h->lem)) {
+    _E("Not connected");
+    set_last_result(RPC_PORT_ERROR_INVALID_PARAMETER);
+    return;
+  }
+
+  res_ = rpc_port_parcel_create(&parcel_);
+  if (res_ != RPC_PORT_ERROR_NONE) {
+    _E("Failed to create parcel handle. error(%d)", res_);
+    set_last_result(res_);
+    return;
+  }
+
+  rpc_port_parcel_get_header(parcel_, &header_);
+  rpc_port_parcel_header_set_tag(header_, TIDL_VERSION);
+  rpc_port_parcel_header_get_seq_num(header_, &seq_num_);
+
+  map_ = rpc_port_unit_map_create();
+  if (map_ == nullptr) {
+    _E("Failed to create unit map");
+    rpc_port_parcel_destroy(parcel_);
+    set_last_result(RPC_PORT_ERROR_OUT_OF_MEMORY);
+    return;
+  }
+
+  rpc_port_unit_map_write_int(map_, <HASH_METHOD> /*[METHOD]*/, &method_);
+  <METHOD_UNIT_MAP_WRITE>
+  <METHOD_DELEGATE_APPEND>
+
+  rpc_port_parcel_write(parcel_, &map_->parcelable, map_);
+  rpc_port_unit_map_destroy(map_);
+
+  g_rec_mutex_lock(&h->mutex);
+  if (rpc_port_proxy_lem_is_connected(h->lem))
+    res_ = rpc_port_proxy_lem_send(h->lem, parcel_, nullptr);
+  else
+    res_ = rpc_port_parcel_send(parcel_, h->port);
+
+  rpc_port_parcel_destroy(parcel_);
+  if (res_ != RPC_PORT_ERROR_NONE)
+    _E("Failed to send parcel. error(%d)", res_);
+
+  g_rec_mutex_unlock(&h->mutex);
+  set_last_result(res_);
+}
+</ASYNC?>
+
+<SYNC?>
+<RETURN_TYPE><PREFIX>_<NAME>_invoke_<METHOD_NAME>(<PREFIX>_<NAME>_h h<METHOD_PARAMS>)
+{
+  rpc_port_parcel_h parcel_;
+  rpc_port_parcel_header_h header_;
+  rpc_port_unit_map_h map_;
+  int seq_num_ = -1;
+  int res_;
+  int method_ = <UPPERCASE_PREFIX>_<UPPERCASE_NAME>_METHOD_<UPPERCASE_METHOD_NAME>;
+  <RETURN_TYPE>ret_ = <ERROR_VALUE>;
+  <METHOD_ARGS>
+
+  if (h == nullptr<METHOD_PARAMS_CHECK>) {
+    _E("Invalid parameter");
+    set_last_result(RPC_PORT_ERROR_INVALID_PARAMETER);
+    return ret_;
+  }
+
+  if (h->port == nullptr && !rpc_port_proxy_lem_is_connected(h->lem)) {
+    _E("Not connected");
+    set_last_result(RPC_PORT_ERROR_INVALID_PARAMETER);
+    return ret_;
+  }
+
+  res_ = rpc_port_parcel_create(&parcel_);
+  if (res_ != RPC_PORT_ERROR_NONE) {
+    _E("Failed to create parcel handle. error(%d)", res_);
+    set_last_result(res_);
+    return ret_;
+  }
+
+  rpc_port_parcel_get_header(parcel_, &header_);
+  rpc_port_parcel_header_set_tag(header_, TIDL_VERSION);
+  rpc_port_parcel_header_get_seq_num(header_, &seq_num_);
+
+  map_ = rpc_port_unit_map_create();
+  if (map_ == nullptr) {
+    _E("Failed to create unit map");
+    rpc_port_parcel_destroy(parcel_);
+    set_last_result(RPC_PORT_ERROR_OUT_OF_MEMORY);
+    return ret_;
+  }
+
+  rpc_port_unit_map_write_int(map_, <HASH_METHOD> /*[METHOD]*/, &method_);
+  <METHOD_UNIT_MAP_WRITE>
+  <METHOD_DELEGATE_APPEND>
+
+  rpc_port_parcel_write(parcel_, &map_->parcelable, map_);
+  rpc_port_unit_map_destroy(map_);
+
+
+  g_rec_mutex_lock(&h->mutex);
+  rpc_port_parcel_h result_parcel_ = nullptr;
+  if (rpc_port_proxy_lem_is_connected(h->lem))
+    res_ = rpc_port_proxy_lem_send(h->lem, parcel_, &result_parcel_);
+  else
+    res_ = rpc_port_parcel_send(parcel_, h->port);
+
+  rpc_port_parcel_destroy(parcel_);
+  if (res_ != RPC_PORT_ERROR_NONE) {
+    _E("Failed to send parcel. error(%d)", res_);
+    set_last_result(res_);
+    g_rec_mutex_unlock(&h->mutex);
+    return ret_;
+  }
+
+  do {
+    map_ = nullptr;
+    if (rpc_port_proxy_lem_is_connected(h->lem)) {
+      map_ = rpc_port_unit_map_create();
+      rpc_port_parcel_read(result_parcel_, &map_->parcelable, map_);
+      rpc_port_parcel_destroy(result_parcel_);
+    } else {
+      __<PREFIX>_<NAME>_consume_command(h->port, seq_num_, &map_);
+    }
+
+    if (map_ == nullptr) {
+      _E("Invalid protocol");
+      res_ = RPC_PORT_ERROR_IO_ERROR;
+      break;
+    }
+
+    <METHOD_UNIT_MAP_READ>
+    rpc_port_unit_map_destroy(map_);
+  } while (0);
+  g_rec_mutex_unlock(&h->mutex);
+  set_last_result(res_);
+
+  return ret_;
+}
+</SYNC?>
+
+</METHODS*>
+</INTERFACES*>
+
+<LEM_APIS*>
+EXPORT_API int rpc_port_proxy_<INPUT_FILE>_lem_<IFACE_NAME>_connect(void *h, bool sync)
+{
+  rpc_port_proxy_lem_h handle = h;
+  GSource* source;
+
+  if (h == nullptr) {
+    _E("Invalid parameter");
+    return RPC_PORT_ERROR_INVALID_PARAMETER;
+  }
+
+  if (sync) {
+    rpc_port_proxy_lem_on_connected(h);
+    return RPC_PORT_ERROR_NONE;
+  }
+
+  source = g_idle_source_new();
+  if (source == nullptr) {
+    _E("Failed to create idle source");
+    return RPC_PORT_ERROR_OUT_OF_MEMORY;
+  }
+
+  g_source_set_callback(source, (GSourceFunc)rpc_port_proxy_lem_on_connected, h, nullptr);
+  g_source_attach(source, handle->thread_context);
+  g_source_unref(source);
+  return RPC_PORT_ERROR_NONE;
+}
+
+EXPORT_API int rpc_port_proxy_<INPUT_FILE>_lem_<IFACE_NAME>_disconnect(void* h)
+{
+  rpc_port_proxy_lem_h handle = h;
+  GSource* source;
+
+  if (h == nullptr) {
+    _E("Invalid parameter");
+    return RPC_PORT_ERROR_INVALID_PARAMETER;
+  }
+
+  source = g_idle_source_new();
+  if (source == nullptr) {
+    _E("Failed to create idle source");
+    return RPC_PORT_ERROR_OUT_OF_MEMORY;
+  }
+
+  g_source_set_callback(source, (GSourceFunc)rpc_port_proxy_lem_on_disconnected, h, nullptr);
+  g_source_attach(source, handle->thread_context);
+  g_source_unref(source);
+  return RPC_PORT_ERROR_NONE;
+}
+
+EXPORT_API int rpc_port_proxy_<INPUT_FILE>_lem_<IFACE_NAME>_invoke_callback(void* h, rpc_port_parcel_h parcel)
+{
+  rpc_port_proxy_lem_h handle = h;
+  rpc_port_parcel_h cloned_parcel;
+  GSource* source;
+
+  if (h == nullptr || parcel == nullptr) {
+    _E("Invalid parameter");
+    return RPC_PORT_ERROR_INVALID_PARAMETER;
+  }
+
+  cloned_parcel = __rpc_port_parcel_clone(parcel);
+  rpc_port_proxy_lem_request_queue_push(handle, cloned_parcel);
+
+  source = g_idle_source_new();
+  if (source == nullptr) {
+    _E("Failed to create idle source");
+    return RPC_PORT_ERROR_OUT_OF_MEMORY;
+  }
+
+  g_source_set_callback(source, (GSourceFunc)rpc_port_proxy_lem_on_received, handle, nullptr);
+  g_source_attach(source, handle->thread_context);
+  g_source_unref(source);
+  return RPC_PORT_ERROR_NONE;
+}
+
+EXPORT_API int rpc_port_proxy_<INPUT_FILE>_lem_<IFACE_NAME>_send_result(void* h, rpc_port_parcel_h parcel)
+{
+  rpc_port_proxy_lem_h handle = h;
+  rpc_port_parcel_h cloned_parcel;
+
+  if (h == nullptr || parcel == nullptr) {
+    _E("Invalid parameter");
+    return RPC_PORT_ERROR_INVALID_PARAMETER;
+  }
+
+  cloned_parcel = __rpc_port_parcel_clone(parcel);
+  rpc_port_proxy_lem_result_queue_push(handle, cloned_parcel);
+  return RPC_PORT_ERROR_NONE;
+}
+</LEM_APIS*>
+
+)__c_cb";
+
+constexpr const char CB_DELEGATE_DEFS[] =
+R"__c_cb(
+typedef struct rpc_port_delegate_s {
+  rpc_port_parcelable_t parcelable;
+  int id;
+  int seq_id;
+  bool once;
+} rpc_port_delegate_t;
+
+typedef rpc_port_delegate_t *rpc_port_delegate_h;
+
+static rpc_port_delegate_h rpc_port_delegate_create();
+)__c_cb";
+
+constexpr const char CB_DELEGATE_BASE[] =
+R"__c_cb(
+static void __rpc_port_delegate_to(rpc_port_parcel_h parcel, void *user_data)
+{
+  rpc_port_delegate_h delegate = user_data;
+
+  rpc_port_parcel_write_int32(parcel, delegate->id);
+  rpc_port_parcel_write_int32(parcel, delegate->seq_id);
+  rpc_port_parcel_write_bool(parcel, delegate->once);
+
+  set_last_result(RPC_PORT_ERROR_NONE);
+}
+
+static void __rpc_port_delegate_from(rpc_port_parcel_h parcel, void *user_data)
+{
+  rpc_port_delegate_h delegate = user_data;
+
+  rpc_port_parcel_read_int32(parcel, &delegate->id);
+  rpc_port_parcel_read_int32(parcel, &delegate->seq_id);
+  rpc_port_parcel_read_bool(parcel, &delegate->once);
+
+  set_last_result(RPC_PORT_ERROR_NONE);
+}
+
+static void rpc_port_delegate_destroy(rpc_port_delegate_h handle)
+{
+  if (handle == nullptr)
+    return;
+
+  free(handle);
+}
+
+static rpc_port_delegate_h rpc_port_delegate_create()
+{
+  rpc_port_delegate_h delegate;
+
+  delegate = calloc(1, sizeof(rpc_port_delegate_t));
+  if (delegate == nullptr) {
+    _E("malloc() is failed");
+    return nullptr;
+  }
+
+  delegate->parcelable.to = __rpc_port_delegate_to;
+  delegate->parcelable.from = __rpc_port_delegate_from;
+
+  return delegate;
+}
+)__c_cb";
+
+constexpr const char CB_INTERFACE_DELEGATE_CALLBACK[] =
+R"__c_cb(
+typedef void (*rpc_port_proxy_delegate_cb)(GList **delegates, rpc_port_unit_map_h map, rpc_port_delegate_h delegate);
+)__c_cb";
+
+/**
+ * <ENUMS> The enumeration of the interface delegate.
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ */
+constexpr const char CB_INTERFACE_DELEGATE_ENUM_BASE[] =
+R"__c_cb(
+typedef enum {
+  <ENUMS>
+} <PREFIX>_<NAME>_delegate_e;
+)__c_cb";
+
+/**
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ * <DELEGATE_NAME> The name of the delegate of the interface.
+ */
+constexpr const char CB_INTERFACE_DELEGATE_DEF[] =
+R"__c_cb(
+typedef struct <PREFIX>_<NAME>_<DELEGATE_NAME>_s {
+  rpc_port_parcelable_t parcelable;
+  int id;
+  int seq_id;
+  bool once;
+  <PREFIX>_<NAME>_<DELEGATE_NAME>_cb callback;
+  void *user_data;
+} <PREFIX>_<NAME>_<DELEGATE_NAME>_t;
 )__c_cb";
 
 /**
@@ -424,7 +840,7 @@ static void __<PREFIX>_<NAME>_<DELEGATE_NAME>_delegate_handler(GList **delegates
  */
 constexpr const char CB_INTERFACE_DELEGATE_USER_DEFINED_UNIT_MAP_READ[] =
 R"__c_cb(
-rpc_port_unit_map_read_<TYPE_NAME>(map, "<ARG>", &<ARG>);
+rpc_port_unit_map_read_<TYPE_NAME>(map, <HASH_ARG> /*<ARG>*/, &<ARG>);
 )__c_cb";
 
 /**
@@ -432,7 +848,7 @@ rpc_port_unit_map_read_<TYPE_NAME>(map, "<ARG>", &<ARG>);
  */
 constexpr const char CB_INTERFACE_DELEGATE_BUNDLE_UNIT_MAP_READ[] =
 R"__c_cb(
-rpc_port_unit_map_read_bundle(map, "<ARG>", &<ARG>);
+rpc_port_unit_map_read_bundle(map, <HASH_ARG> /*<ARG>*/, &<ARG>);
 )__c_cb";
 
 /**
@@ -440,7 +856,7 @@ rpc_port_unit_map_read_bundle(map, "<ARG>", &<ARG>);
  */
 constexpr const char CB_INTERFACE_DELEGATE_STRING_UNIT_MAP_READ[] =
 R"__c_cb(
-rpc_port_unit_map_read_string(map, "<ARG>", &<ARG>);
+rpc_port_unit_map_read_string(map, <HASH_ARG> /*<ARG>*/, &<ARG>);
 )__c_cb";
 
 /**
@@ -449,7 +865,7 @@ rpc_port_unit_map_read_string(map, "<ARG>", &<ARG>);
  */
 constexpr const char CB_INTERFACE_DELEGATE_ENUM_UNIT_MAP_READ[] =
 R"__c_cb(
-rpc_port_unit_map_read_int(map, "<ARG_NAME>", (int *)&<ARG>);
+rpc_port_unit_map_read_int(map, <HASH_ARG_NAME> /*<ARG_NAME>*/, (int *)&<ARG>);
 )__c_cb";
 
 
@@ -459,7 +875,7 @@ rpc_port_unit_map_read_int(map, "<ARG_NAME>", (int *)&<ARG>);
  */
 constexpr const char CB_INTERFACE_DELEGATE_BASE_UNIT_MAP_READ[] =
 R"__c_cb(
-rpc_port_unit_map_read_<TYPE_NAME>(map, "<ARG_NAME>", &<ARG>);
+rpc_port_unit_map_read_<TYPE_NAME>(map, <HASH_ARG_NAME> /*<ARG_NAME>*/, &<ARG>);
 )__c_cb";
 
 /**
@@ -559,7 +975,7 @@ static void __<PREFIX>_<NAME>_process_received_event(GList **delegates, rpc_port
 {
   rpc_port_delegate_h delegate;
 
-  rpc_port_unit_map_read_delegate(map, "delegate", &delegate);
+  rpc_port_unit_map_read_delegate(map, <HASH_DELEGATE> /*delegate*/, &delegate);
 
   _W("id(%d), seq_id(%d)", delegate->id, delegate->seq_id);
 
@@ -587,7 +1003,7 @@ static void __<PREFIX>_<NAME>_lem_received(void *context, rpc_port_parcel_h parc
 
   rpc_port_parcel_read(parcel, &map->parcelable, map);
 
-  rpc_port_unit_map_read_int(map, "[METHOD]", &cmd);
+  rpc_port_unit_map_read_int(map, <HASH_METHOD> /*[METHOD]*/, &cmd);
   if (cmd != <UPPERCASE_PREFIX>_<UPPERCASE_NAME>_METHOD_CALLBACK_) {
     _E("Invalid protocol");
     rpc_port_unit_map_destroy(map);
@@ -623,7 +1039,7 @@ static void __<PREFIX>_<NAME>_received(const char *endpoint, const char *port_na
   rpc_port_parcel_read(parcel, &map->parcelable, map);
   rpc_port_parcel_destroy(parcel);
 
-  rpc_port_unit_map_read_int(map, "[METHOD]", &cmd);
+  rpc_port_unit_map_read_int(map, <HASH_METHOD> /*[METHOD]*/, &cmd);
   if (cmd != <UPPERCASE_PREFIX>_<UPPERCASE_NAME>_METHOD_CALLBACK_) {
     _E("Invalid protocol");
     rpc_port_unit_map_destroy(map);
@@ -694,13 +1110,13 @@ static void __<PREFIX>_<NAME>_consume_command(rpc_port_h port, int seq_num, rpc_
     rpc_port_parcel_read(parcel, &map->parcelable, map);
     rpc_port_parcel_destroy(parcel);
 
-    rpc_port_unit_map_read_int(map, "[METHOD]", &cmd);
+    rpc_port_unit_map_read_int(map, <HASH_METHOD> /*[METHOD]*/, &cmd);
     if (cmd == <UPPERCASE_PREFIX>_<UPPERCASE_NAME>_METHOD_RESULT_) {
       if (__<PREFIX>_remote_exception != nullptr)
         <PREFIX>_remote_exception_destroy(__<PREFIX>_remote_exception);
 
       __<PREFIX>_remote_exception = nullptr;
-      rpc_port_unit_map_read_remote_exception(map, "[REMOTE_EXCEPTION]", &__<PREFIX>_remote_exception);
+      rpc_port_unit_map_read_remote_exception(map, <HASH_REMOTE_EXCEPTION> /*[REMOTE_EXCEPTION]*/, &__<PREFIX>_remote_exception);
 
       *unit_map = map;
       return;
@@ -762,6 +1178,8 @@ int <PREFIX>_<NAME>_create(const char *stub_appid, <PREFIX>_<NAME>_callback_s *c
   rpc_port_proxy_lem_event_s lem_callback = { 0, };
   const char *appid = __get_appid();
 
+  rpc_port_internal_init();
+
   if (stub_appid == nullptr || callback == nullptr || h == nullptr) {
     _E("Invalid parameter");
     return RPC_PORT_ERROR_INVALID_PARAMETER;
@@ -961,6 +1379,7 @@ void <PREFIX>_<NAME>_invoke_<METHOD_NAME>(<PREFIX>_<NAME>_h h<METHOD_PARAMS>)
   rpc_port_unit_map_h map_;
   int seq_num_ = -1;
   int res_;
+  int method = <UPPERCASE_PREFIX>_<UPPERCASE_NAME>_METHOD_<UPPERCASE_METHOD_NAME>;
 
   if (h == nullptr<METHOD_PARAMS_CHECK>) {
     _E("Invalid parameter");
@@ -993,8 +1412,7 @@ void <PREFIX>_<NAME>_invoke_<METHOD_NAME>(<PREFIX>_<NAME>_h h<METHOD_PARAMS>)
     return;
   }
 
-  rpc_port_unit_map_write_int(map_, "[METHOD]", <UPPERCASE_PREFIX>_<UPPERCASE_NAME>_METHOD_<UPPERCASE_METHOD_NAME>);
-
+  rpc_port_unit_map_write_int(map_, <HASH_METHOD> /*[METHOD]*/, &method);
   <METHOD_UNIT_MAP_WRITE>
   <METHOD_DELEGATE_APPEND>
 
@@ -1041,6 +1459,7 @@ R"__c_cb(
   rpc_port_unit_map_h map_;
   int seq_num_ = -1;
   int res_;
+  int method = <UPPERCASE_PREFIX>_<UPPERCASE_NAME>_METHOD_<UPPERCASE_METHOD_NAME>;
   <RETURN_TYPE>ret_ = <ERROR_VALUE>;
   <METHOD_ARGS>
 
@@ -1075,8 +1494,7 @@ R"__c_cb(
     return ret_;
   }
 
-  rpc_port_unit_map_write_int(map_, "[METHOD]", <UPPERCASE_PREFIX>_<UPPERCASE_NAME>_METHOD_<UPPERCASE_METHOD_NAME>);
-
+  rpc_port_unit_map_write_int(map_, <HASH_METHOD> /*[METHOD]*/, &method);
   <METHOD_UNIT_MAP_WRITE>
   <METHOD_DELEGATE_APPEND>
 
@@ -1132,7 +1550,7 @@ R"__c_cb(
  */
 constexpr const char CB_INTERFACE_METHOD_USER_DEFINED_UNIT_MAP_WRITE[] =
 R"__c_cb(
-rpc_port_unit_map_write_<TYPE_NAME>(map_, "<ARG_NAME>", <ARG>);
+rpc_port_unit_map_write_<TYPE_NAME>(map_, <HASH_ARG_NAME> /*<ARG_NAME>*/, <ARG>);
 )__c_cb";
 
 /**
@@ -1141,7 +1559,7 @@ rpc_port_unit_map_write_<TYPE_NAME>(map_, "<ARG_NAME>", <ARG>);
  */
 constexpr const char CB_INTERFACE_METHOD_DELEGATE_UNIT_MAP_WRITE[] =
 R"__c_cb(
-rpc_port_unit_map_write_delegate(map_, "<ARG_NAME>", (rpc_port_delegate_h)<ARG>);
+rpc_port_unit_map_write_delegate(map_, <HASH_ARG_NAME> /*<ARG_NAME>*/, (rpc_port_delegate_h)<ARG>);
 )__c_cb";
 
 /**
@@ -1150,7 +1568,7 @@ rpc_port_unit_map_write_delegate(map_, "<ARG_NAME>", (rpc_port_delegate_h)<ARG>)
  */
 constexpr const char CB_INTERFACE_METHOD_BUNDLE_UNIT_MAP_WRITE[] =
 R"__c_cb(
-rpc_port_unit_map_write_bundle(map_, "<ARG_NAME>", <ARG>);
+rpc_port_unit_map_write_bundle(map_, <HASH_ARG_NAME> /*<ARG_NAME>*/, <ARG>);
 )__c_cb";
 
 /**
@@ -1159,7 +1577,13 @@ rpc_port_unit_map_write_bundle(map_, "<ARG_NAME>", <ARG>);
  */
 constexpr const char CB_INTERFACE_METHOD_STRING_UNIT_MAP_WRITE[] =
 R"__c_cb(
-rpc_port_unit_map_write_string(map_, "<ARG_NAME>", <ARG>);
+rpc_port_unit_map_write_string(map_, <HASH_ARG_NAME> /*<ARG_NAME>*/, <ARG>);
+)__c_cb";
+
+
+constexpr const char CB_INTERFACE_METHOD_FILE_UNIT_MAP_WRITE[] =
+R"__c_cb(
+rpc_port_unit_map_write_file(map_, <HASH_ARG_NAME> /*<ARG_NAME>*/, <ARG>);
 )__c_cb";
 
 /**
@@ -1169,7 +1593,7 @@ rpc_port_unit_map_write_string(map_, "<ARG_NAME>", <ARG>);
  */
 constexpr const char CB_INTERFACE_METHOD_BASE_UNIT_MAP_WRITE[] =
 R"__c_cb(
-rpc_port_unit_map_write_<TYPE_NAME>(map_, "<ARG_NAME>", <ARG>);
+rpc_port_unit_map_write_<TYPE_NAME>(map_, <HASH_ARG_NAME> /*<ARG_NAME>*/, &<ARG>);
 )__c_cb";
 
 /**
@@ -1179,7 +1603,7 @@ rpc_port_unit_map_write_<TYPE_NAME>(map_, "<ARG_NAME>", <ARG>);
  */
 constexpr const char CB_INTERFACE_METHOD_ENUM_UNIT_MAP_WRITE[] =
 R"__c_cb(
-rpc_port_unit_map_write_int(map_, "<ARG_NAME>", (int)<ARG>);
+rpc_port_unit_map_write_int(map_, <HASH_ARG_NAME> /*<ARG_NAME>*/, (int*)&<ARG>);
 )__c_cb";
 
 /**
@@ -1189,7 +1613,7 @@ rpc_port_unit_map_write_int(map_, "<ARG_NAME>", (int)<ARG>);
  */
 constexpr const char CB_INTERFACE_METHOD_USER_DEFINED_UNIT_MAP_READ[] =
 R"__c_cb(
- rpc_port_unit_map_read_<TYPE_NAME>(map_, "<ARG_NAME>", &<ARG>);
+ rpc_port_unit_map_read_<TYPE_NAME>(map_, <HASH_ARG_NAME> /*<ARG_NAME>*/, &<ARG>);
 )__c_cb";
 
 /**
@@ -1198,7 +1622,7 @@ R"__c_cb(
  */
 constexpr const char CB_INTERFACE_METHOD_BUNDLE_UNIT_MAP_READ[] =
 R"__c_cb(
-rpc_port_unit_map_read_bundle(map_, "<ARG_NAME>", &<ARG>);
+rpc_port_unit_map_read_bundle(map_, <HASH_ARG_NAME> /*<ARG_NAME>*/, &<ARG>);
 )__c_cb";
 
 /**
@@ -1207,16 +1631,22 @@ rpc_port_unit_map_read_bundle(map_, "<ARG_NAME>", &<ARG>);
  */
 constexpr const char CB_INTERFACE_METHOD_STRING_UNIT_MAP_READ[] =
 R"__c_cb(
-rpc_port_unit_map_read_string(map_, "<ARG_NAME>", &<ARG>);
+rpc_port_unit_map_read_string(map_, <HASH_ARG_NAME> /*<ARG_NAME>*/, &<ARG>);
 )__c_cb";
 
+constexpr const char CB_INTERFACE_METHOD_FILE_UNIT_MAP_READ[] =
+R"__c_cb(
+rpc_port_unit_map_read_file(map_, <HASH_ARG_NAME> /*<ARG_NAME>*/, &<ARG>);
+)__c_cb";
+
+
 /**
  * <ARG_NAME> The argument name.
  * <ARG> The argument.
  */
 constexpr const char CB_INTERFACE_METHOD_EMUM_UNIT_MAP_READ[] =
 R"__c_cb(
-rpc_port_unit_map_read_int(map_, "<ARG_NAME>", (int *)&<ARG>);
+rpc_port_unit_map_read_int(map_, <HASH_ARG_NAME> /*<ARG_NAME>*/, (int *)&<ARG>);
 )__c_cb";
 
 /**
@@ -1226,7 +1656,7 @@ rpc_port_unit_map_read_int(map_, "<ARG_NAME>", (int *)&<ARG>);
  */
 constexpr const char CB_INTERFACE_METHOD_BASE_UNIT_MAP_READ[] =
 R"__c_cb(
-rpc_port_unit_map_read_<TYPE_NAME>(map_, "<ARG_NAME>", &<ARG>);
+rpc_port_unit_map_read_<TYPE_NAME>(map_, <HASH_ARG_NAME> /*<ARG_NAME>*/, &<ARG>);
 )__c_cb";
 
 /**
index 75b493aa3b1ce4c562f020c14ec1c4dcf2c83ea4..5c140c49ee45b2ae064b1e8e26484ddd993a8c8e 100644 (file)
@@ -26,361 +26,191 @@ namespace tidl {
 namespace version2 {
 
 CStubBodyGenerator::CStubBodyGenerator(std::shared_ptr<Document> doc,
-    std::shared_ptr<Options> options)
-    : CBodyGeneratorBase(doc), options_(options) {
-}
+                                       std::shared_ptr<Options> options)
+    : CBodyGeneratorBase(doc), options_(options) {}
 
 void CStubBodyGenerator::OnInitGen(std::ofstream& stream) {
-  GenVersion(stream);
-  GenGNUSourceDefinition(stream);
-  GenIncludeDefaultHeaders(stream);
-  GenIncludePrivateHeaders(stream);
-  GenIncludeInternalHeaders(stream);
-  GenIncludeLemHeaders(stream);
-  GenIncludeHeader(stream);
-  GenLogTag(stream, std::string("RPC_PORT_STUB"));
-  GenLogDefinition(stream);
-  GenVersionDefinition(stream);
-  GenBaseDefinition(stream);
-  GenThreadEnableDefinition(stream);
-  GenInterfaceEnums(stream);
-  GenUnitMapDefinition(stream);
-  GenLemDefinition(stream);
-  GenInterfaceMethodHandlerType(stream);
-  GenDelegateDefinition(stream);
-  GenStructureDefinition(stream);
-  GenRemoteExceptionDefinition(stream);
-  GenInterfaceDefs(stream);
-  GenLemBase(stream);
-  GenPrivateSharingListSet(stream);
-  GenUnitMapBase(stream);
-  GenDelegateBase(stream);
-  GenStructure(stream);
-  GenRemoteExceptionBase(stream);
-  GenInterfaces(stream);
-  GenLemAPI(stream);
-}
-
-void CStubBodyGenerator::OnFiniGen(std::ofstream& stream) {}
-
-std::string CStubBodyGenerator::GenLemContext() {
-  std::string code;
-  for (auto& b : GetDocument().GetBlocks()) {
-    if (b->GetType() != Block::TYPE_INTERFACE)
-      continue;
-
-    auto& iface = static_cast<const Interface&>(*b);
-    code += ReplaceAll(CB_LEM_CONTEXT)
-        .Change("<IFACE_NAME>", iface.GetID());
-  }
-
-  return RemoveLine(code);
-}
-
-void CStubBodyGenerator::GenLemDefinition(std::ofstream& stream) {
-  ReplaceAll(CB_LEM_BASE_DEF)
-      .Change("<LEM_CONTEXT>", GenLemContext())
-      .Transform([&](std::string code) { return SmartIndent(code); })
-      .Out(stream);
-}
-
-void CStubBodyGenerator::GenLemBase(std::ofstream& stream) {
   std::string input = basename(const_cast<char*>(options_->GetInput().c_str()));
   input = input.substr(0, input.find_last_of("."));
-  ReplaceAll(CB_LEM_BASE)
-      .Change("<INPUT_FILE>", input)
-      .Transform([&](std::string code) { return SmartIndent(code); })
-      .Out(stream);
-}
-
-void CStubBodyGenerator::GenLemAPI(std::ofstream& stream) {
-  std::string input = basename(const_cast<char*>(options_->GetInput().c_str()));
-  input = input.substr(0, input.find_last_of("."));
-  std::string code;
-  for (auto& b : GetDocument().GetBlocks()) {
-    if (b->GetType() != Block::TYPE_INTERFACE)
-      continue;
-
-    auto& iface = static_cast<const Interface&>(*b);
-    code += ReplaceAll(CB_LEM_API)
-        .Change("<IFACE_NAME>", iface.GetID())
-        .Change("<INPUT_FILE>", input);
-  }
-
-  stream << SmartIndent(code);
-}
-
-void CStubBodyGenerator::GenIncludePrivateHeaders(std::ofstream& stream) {
-  stream << CB_PRIVATE_HEADERS;
-}
-
-void CStubBodyGenerator::GenIncludeInternalHeaders(std::ofstream& stream) {
-  if (options_->UseExtension()) stream << CB_INTERNAL_HEADER_INCLUSION;
-}
-
-void CStubBodyGenerator::GenDelegateDefinition(std::ofstream& stream) {
-  if (HasDelegate())
-    stream << SmartIndent(CB_DELEGATE_DEFS);
-}
 
-void CStubBodyGenerator::GenDelegateBase(std::ofstream& stream) {
-  if (HasDelegate())
-    stream << SmartIndent(CB_DELEGATE_BASE);
-}
-
-// @see #CB_THREAD_ENABLE_DEF
-void CStubBodyGenerator::GenThreadEnableDefinition(std::ofstream& stream) {
-  if (!options_->IsThreadEnabled())
-    return;
-
-  stream << std::string(CB_THREAD_ENABLE_DEF);
-}
-
-// @see #CB_INTERFACE_METHOD_HANDLER_TYPE
-void CStubBodyGenerator::GenInterfaceMethodHandlerType(std::ofstream& stream) {
-  stream << SmartIndent(CB_INTERFACE_METHOD_HANDLER_TYPE);
-}
-
-void CStubBodyGenerator::GenInterfaceEnums(std::ofstream& stream) {
-  for (auto& b : GetDocument().GetBlocks()) {
-    if (b->GetType() != Block::TYPE_INTERFACE)
-      continue;
-
-    auto& iface = static_cast<const Interface&>(*b);
-    GenInterfaceEnum(stream, iface);
-  }
-}
-
-void CStubBodyGenerator::GenInterfaceEnum(std::ofstream& stream,
-    const Interface& iface) {
-  GenInterfaceMethodEnumBase(stream, iface);
-  if (HasDelegate())
-    GenInterfaceDelegateEnumBase(stream, iface);
-}
-
-// @see #CB_INTERFACE_METHOD_ENUM
-std::string CStubBodyGenerator::GenMethodEnums(const Interface& iface) {
-  std::string method_enums;
-  method_enums += RemoveLine(
-      std::string(ReplaceAll(CB_INTERFACE_METHOD_ENUM)
-                      .ChangeToUpper("<UPPERCASE_PREFIX>", GetHandlePrefix())
-                      .ChangeToUpper("<UPPERCASE_NAME>", iface.GetID())
-                      .ChangeToUpper("<UPPERCASE_METHOD_NAME>", "RESULT_")));
-  method_enums += RemoveLine(
-      std::string(ReplaceAll(CB_INTERFACE_METHOD_ENUM)
-                      .ChangeToUpper("<UPPERCASE_PREFIX>", GetHandlePrefix())
-                      .ChangeToUpper("<UPPERCASE_NAME>", iface.GetID())
-                      .ChangeToUpper("<UPPERCASE_METHOD_NAME>", "CALLBACK_")));
-
-  for (const auto& d : iface.GetDeclarations()) {
-    if (d->GetMethodType() == Declaration::MethodType::DELEGATE)
-      continue;
-
-    method_enums += RemoveLine(
-        std::string(ReplaceAll(CB_INTERFACE_METHOD_ENUM)
-                        .ChangeToUpper("<UPPERCASE_PREFIX>", GetHandlePrefix())
-                        .ChangeToUpper("<UPPERCASE_NAME>", iface.GetID())
-                        .ChangeToUpper("<UPPERCASE_METHOD_NAME>", d->GetID())));
-  }
-
-  return method_enums;
-}
-
-// @see #CB_INTERFACE_METHOD_ENUM_BASE
-void CStubBodyGenerator::GenInterfaceMethodEnumBase(std::ofstream& stream,
-                                                    const Interface& iface) {
-  ReplaceAll(CB_INTERFACE_METHOD_ENUM_BASE)
-      .Change("<PREFIX>", GetHandlePrefix())
-      .Change("<NAME>", iface.GetID())
-      .Change("<METHOD_ENUMS>", GenMethodEnums(iface))
-      .Transform([&](std::string code) { return SmartIndent(code); })
+  auto enums = [&](auto& r, const auto& i) {
+    if (i->GetType() != Block::TYPE_INTERFACE) return false;
+    auto& iface = static_cast<const Interface&>(*i);
+    int cnt = 1;
+
+    auto method_enum_fields = [&](auto& r, const auto& i) {
+      if (i->GetMethodType() == Declaration::MethodType::DELEGATE) return false;
+      r.ReplaceToUpper("UPPERCASE_METHOD_NAME", i->GetID());
+
+      return true;
+    };
+
+    auto delegate_enum_fields = [&](auto& r, const auto& i) {
+      if (i->GetMethodType() != Declaration::MethodType::DELEGATE) return false;
+      r.ReplaceToUpper("UPPERCASE_ID", i->GetID())
+          .Replace("CNT", std::to_string(cnt++));
+      return true;
+    };
+
+    r.Repeat("METHOD_ENUM_FIELDS", iface.GetDeclarations(), method_enum_fields)
+        .Repeat("DELEGATE_ENUM_FIELDS", iface.GetDeclarations(),
+                delegate_enum_fields)
+        .Replace("PREFIX", GetHandlePrefix())
+        .Replace("NAME", iface.GetID())
+        .ReplaceToUpper("UPPERCASE_PREFIX", GetHandlePrefix())
+        .ReplaceToUpper("UPPERCASE_NAME", iface.GetID());
+
+    return true;
+  };
+
+  auto lem_contexts = [&](auto& r, const auto& i) {
+    if (i->GetType() != Block::TYPE_INTERFACE) return false;
+
+    auto& iface = static_cast<const Interface&>(*i);
+    r.Replace("IFACE_NAME", iface.GetID());
+    return true;
+  };
+
+  auto interface_defs = [&](auto& r, const auto& i) {
+    if (i->GetType() != Block::TYPE_INTERFACE) return false;
+
+    auto& iface = static_cast<const Interface&>(*i);
+    r.Repeat("DELEGATE_DEFINITIONS", iface.GetDeclarations(),
+             [&](auto& r, const auto& i) {
+               if (i->GetMethodType() != Declaration::MethodType::DELEGATE)
+                 return false;
+               r.Replace("PREFIX", GetHandlePrefix())
+                   .Replace("NAME", iface.GetID())
+                   .Replace("DELEGATE_NAME", i->GetID());
+               return true;
+             })
+        .Replace("PREFIX", GetHandlePrefix())
+        .Replace("NAME", iface.GetID());
+
+    return true;
+  };
+
+  auto interfaces = [&](auto& r, const auto& i) {
+    if (i->GetType() != Block::TYPE_INTERFACE) return false;
+
+    auto& iface = static_cast<const Interface&>(*i);
+    r.Replace("INTERFACE", GetInterface(iface));
+    return true;
+  };
+
+  auto lem_apis = [&](auto& r, const auto& i) {
+    if (i->GetType() != Block::TYPE_INTERFACE) return false;
+
+    const auto& iface = static_cast<const Interface&>(*i);
+    r.Replace("INPUT_FILE", input).Replace("IFACE_NAME", iface.GetID());
+
+    return true;
+  };
+
+  ReplaceAll(CB_MAIN_STUB)
+      .RemoveAll("IS_THREAD_ENABLE", !options_->IsThreadEnabled())
+      .RemoveAll("HAS_DELEGATE", !HasDelegate())
+      .Repeat("ENUMS", GetDocument().GetBlocks(), enums)
+      .Repeat("LEM_CONTEXTS", GetDocument().GetBlocks(), lem_contexts)
+      .Repeat("INTERFACE_DEFINITIONS", GetDocument().GetBlocks(),
+              interface_defs)
+      .Repeat("INTERFACES", GetDocument().GetBlocks(), interfaces)
+      .Repeat("LEM_APIS", GetDocument().GetBlocks(), lem_apis)
+      .Replace("VERSION", std::string(FULLVER))
+      .Replace("INCLUDE", GetIncludeHeader())
+      .Replace("UNIT_MAP_DEFINITION", GetUnitMapDefinition())
+      .Replace("STRUCTURE_DEFINITION", GetStructureDefinition())
+      .Replace("REMOTE_EXCEPTION_DEFINITION", GetRemoteExceptionDefinition())
+      .Replace("LEM_BASE", GetLemBase())
+      .Replace("PRIVATE_SHARING_LIST_SET", GetPrivateSharingListSet())
+      .Replace("STRUCTURE", GetStructure())
+      .Replace("UNIT_MAP_BASE", GetUnitMapBase())
+      .Replace("REMOTE_EXCEPTION_BASE", GetRemoteExceptionBase())
+      .Replace("RPC_PORT_INTERNAL_APIS", GetRpcPortInternalAPIs())
+      .Transform([&](std::string str) { return SmartIndent(str); })
       .Out(stream);
 }
 
-// @see #CB_INTERFACE_DELEGATE_ENUM
-std::string CStubBodyGenerator::GenDelegateEnums(const Interface& iface) {
-  unsigned int num = 1;
-  std::string method_enums;
-  for (const auto& d : iface.GetDeclarations()) {
-    if (d->GetMethodType() != Declaration::MethodType::DELEGATE)
-      continue;
-
-    method_enums += RemoveLine(
-        std::string(ReplaceAll(CB_INTERFACE_DELEGATE_ENUM)
-                        .ChangeToUpper("<UPPERCASE_PREFIX>", GetHandlePrefix())
-                        .ChangeToUpper("<UPPERCASE_NAME>", iface.GetID())
-                        .ChangeToUpper("<UPPERCASE_DELEGATE_NAME>", d->GetID())
-                        .ChangeToUpper("<NUMBER>", std::to_string(num++))));
-  }
-
-  return method_enums;
-}
+void CStubBodyGenerator::OnFiniGen(std::ofstream& stream) {}
 
-// @see #CB_INTERFACE_DELEGATE_ENUM_BASE
-void CStubBodyGenerator::GenInterfaceDelegateEnumBase(std::ofstream& stream,
-                                                      const Interface& iface) {
-  std::string delegate_enums = GenDelegateEnums(iface);
-  if (delegate_enums.empty())
-    return;
-
-  ReplaceAll(CB_INTERFACE_DELEGATE_ENUM_BASE)
-      .Change("<PREFIX>", GetHandlePrefix())
-      .Change("<NAME>", iface.GetID())
-      .Change("<DELEGATE_ENUMS>", delegate_enums)
+std::string CStubBodyGenerator::GetLemBase() {
+  std::string input = basename(const_cast<char*>(options_->GetInput().c_str()));
+  input = input.substr(0, input.find_last_of("."));
+  return ReplaceAll(CB_LEM_BASE)
+      .RemoveAll("HAS_DELEGATE", !HasDelegate())
+      .Replace("INPUT_FILE", input)
       .Transform([&](std::string code) { return SmartIndent(code); })
-      .Out(stream);
+      .ToString();
 }
 
-void CStubBodyGenerator::GenInterfaceDefs(std::ofstream& stream) {
-  for (auto& b : GetDocument().GetBlocks()) {
-    if (b->GetType() != Block::TYPE_INTERFACE)
-      continue;
-
-    auto& iface = static_cast<const Interface&>(*b);
-    GenInterfaceDef(stream, iface);
-  }
-}
-
-void CStubBodyGenerator::GenInterfaceDef(std::ofstream& stream,
-                                         const Interface& iface) {
+std::string CStubBodyGenerator::GetInterface(const Interface& iface) {
   bool has_delegate = false;
+  std::string ret;
   for (const auto& d : iface.GetDeclarations()) {
-    if (d->GetMethodType() != Declaration::MethodType::DELEGATE)
-      continue;
+    if (d->GetMethodType() != Declaration::MethodType::DELEGATE) continue;
 
-    GenInterfaceDelegateDef(stream, iface, *d);
+    ret += GetInterfaceDelegateBase(iface, *d);
     has_delegate = true;
   }
 
-  if (has_delegate)
-    GenInterfaceCallbackPortCheckDef(stream, iface);
-
-  GenInterfaceContextDef(stream, iface);
-  GenInterfaceBaseDef(stream, iface);
-}
-
-// @see #CB_INTERFACE_DELEGATE_DEF
-void CStubBodyGenerator::GenInterfaceDelegateDef(std::ofstream& stream,
-                                                 const Interface& iface,
-                                                 const Declaration& decl) {
-  ReplaceAll(CB_INTERFACE_DELEGATE_DEF)
-      .Change("<PREFIX>", GetHandlePrefix())
-      .Change("<NAME>", iface.GetID())
-      .Change("<DELEGATE_NAME>", decl.GetID())
-      .Transform([&](std::string code) { return SmartIndent(code); })
-      .Out(stream);
-}
-
-// @see #CB_INTERFACE_CALLBACK_PORT_CHECK_DEF
-void CStubBodyGenerator::GenInterfaceCallbackPortCheckDef(
-    std::ofstream& stream, const Interface& iface) {
-  ReplaceAll(CB_INTERFACE_CALLBACK_PORT_CHECK_DEF)
-      .Change("<PREFIX>", GetHandlePrefix())
-      .Change("<NAME>", iface.GetID())
-      .Transform([&](std::string code) { return SmartIndent(code); })
-      .Out(stream);
-}
-
-// @see #CB_INTERFACE_CONTEXT_DEF
-void CStubBodyGenerator::GenInterfaceContextDef(std::ofstream& stream,
-                                                const Interface& iface) {
-  ReplaceAll(CB_INTERFACE_CONTEXT_DEF)
-      .Change("<PREFIX>", GetHandlePrefix())
-      .Change("<NAME>", iface.GetID())
-      .Transform([&](std::string code) { return SmartIndent(code); })
-      .Out(stream);
-}
-
-
-// @see #CB_INTERFACE_BASE_DEF
-void CStubBodyGenerator::GenInterfaceBaseDef(std::ofstream& stream,
-                                             const Interface& iface) {
-  ReplaceAll(CB_INTERFACE_BASE_DEF)
-      .Change("<PREFIX>", GetHandlePrefix())
-      .Change("<NAME>", iface.GetID())
-      .Transform([&](std::string code) { return SmartIndent(code); })
-      .Out(stream);
-}
-
-void CStubBodyGenerator::GenInterfaces(std::ofstream& stream) {
-  for (auto& i : GetDocument().GetBlocks()) {
-    if (i->GetType() != Block::TYPE_INTERFACE)
-      continue;
-
-    const Interface &iface = static_cast<const Interface&>(*i);
-    GenInterface(stream, iface);
-  }
-}
-
-void CStubBodyGenerator::GenInterface(std::ofstream& stream,
-    const Interface& iface) {
-  bool has_delegate = false;
   for (const auto& d : iface.GetDeclarations()) {
-    if (d->GetMethodType() != Declaration::MethodType::DELEGATE)
-      continue;
+    if (d->GetMethodType() == Declaration::MethodType::DELEGATE) continue;
 
-    GenInterfaceDelegateBase(stream, iface, *d);
-    has_delegate = true;
+    ret += GetInterfaceMethodPrivilegeCheckerBase(iface, *d);
+    ret += GetInterfaceMethodHandlerBase(iface, *d);
   }
 
-  for (const auto& d : iface.GetDeclarations()) {
-    if (d->GetMethodType() == Declaration::MethodType::DELEGATE)
-      continue;
-
-    GenInterfaceMethodPrivilegeCheckerBase(stream, iface, *d);
-    GenInterfaceMethodHandlerBase(stream, iface, *d);
-  }
+  ret += GetInterfaceMethodPrivilegeCheckerTable(iface);
+  ret += GetInterfaceMethodTable(iface);
+  ret += GetInterfaceContextBase(iface);
+  ret += GetInterfaceContextExtensionBase(iface);
 
-  GenInterfaceMethodPrivilegeCheckerTable(stream, iface);
-  GenInterfaceMethodTable(stream, iface);
-  GenInterfaceContextBase(stream, iface);
-  GenInterfaceContextExtensionBase(stream, iface);
+  if (has_delegate) ret += GetInterfaceCallbackPortCheck(iface);
 
-  if (has_delegate)
-    GenInterfaceCallbackPortCheck(stream, iface);
+  ret += GetInterfaceBase(iface);
+  ret += GetInterfaceExtensionBase(iface);
 
-  GenInterfaceBase(stream, iface);
-  GenInterfaceExtensionBase(stream, iface);
+  return ret;
 }
 
 // @see #CB_INTERFACE_CONTEXT_BASE
-void CStubBodyGenerator::GenInterfaceContextBase(std::ofstream& stream,
+std::string CStubBodyGenerator::GetInterfaceContextBase(
     const Interface& iface) {
-  ReplaceAll(CB_INTERFACE_CONTEXT_BASE)
-      .Change("<PREFIX>", GetHandlePrefix())
-      .Change("<NAME>", iface.GetID())
-      .ChangeToUpper("<UPPERCASE_PREFIX>", GetHandlePrefix())
-      .ChangeToUpper("<UPPERCASE_NAME>", iface.GetID())
+  return ReplaceAll(CB_INTERFACE_CONTEXT_BASE)
+      .Replace("PREFIX", GetHandlePrefix())
+      .Replace("NAME", iface.GetID())
+      .ReplaceToUpper("UPPERCASE_PREFIX", GetHandlePrefix())
+      .ReplaceToUpper("UPPERCASE_NAME", iface.GetID())
+      .Replace("HASH_METHOD", "[METHOD]"_hash)
+      .Replace("HASH_REMOTE_EXCEPTION", "[REMOTE_EXCEPTION]"_hash)
       .Transform([&](std::string code) { return SmartIndent(code); })
-      .Out(stream);
+      .ToString();
 }
 
 std::string CStubBodyGenerator::GenDelegateParams(const Interface& iface,
-    const Declaration& decl) {
+                                                  const Declaration& decl) {
   std::string params;
   for (const auto& p : decl.GetParameters()) {
     params += ", ";
     auto& param_type = p->GetParameterType();
     auto& type = param_type.GetBaseType();
-    params += GetParamTypeString(param_type.GetDirection(), type, iface) +
-        p->GetID();
+    params +=
+        GetParamTypeString(param_type.GetDirection(), type, iface) + p->GetID();
   }
 
   return params;
 }
 
-std::string CStubBodyGenerator::GenDelegateParamsCheck(const Interface& iface,
-    const Declaration& decl) {
+std::string CStubBodyGenerator::GenDelegateParamsCheck(
+    const Interface& iface, const Declaration& decl) {
   std::string params_check;
   for (const auto& p : decl.GetParameters()) {
     auto& param_type = p->GetParameterType();
     auto& type = param_type.GetBaseType();
     if (type.GetUserDefinedType() == BaseType::UserType::STRUCTURE ||
         type.GetUserDefinedType() == BaseType::UserType::DELEGATE ||
-        type.ToString() == "list" ||
-        type.ToString() == "array" ||
-        type.ToString() == "bundle" ||
-        type.ToString() == "string" ||
+        type.ToString() == "list" || type.ToString() == "array" ||
+        type.ToString() == "bundle" || type.ToString() == "string" ||
         type.ToString() == "file")
       params_check += " || " + p->GetID() + " == nullptr";
   }
@@ -389,22 +219,24 @@ std::string CStubBodyGenerator::GenDelegateParamsCheck(const Interface& iface,
 }
 
 // @see #CB_INTERFACE_DELEGATE_BASE
-void CStubBodyGenerator::GenInterfaceDelegateBase(std::ofstream& stream,
+std::string CStubBodyGenerator::GetInterfaceDelegateBase(
     const Interface& iface, const Declaration& decl) {
-  std::string enum_value = GetHandlePrefix() + "_" + iface.GetID() +
-      "_DELEGATE_" + decl.GetID();
-  ReplaceAll(CB_INTERFACE_DELEGATE_BASE)
-      .Change("<PREFIX>", GetHandlePrefix())
-      .Change("<NAME>", iface.GetID())
-      .Change("<DELEGATE_NAME>", decl.GetID())
-      .Change("<DELEGATE_PARAMS>", GenDelegateParams(iface, decl))
-      .Change("<DELEGATE_PARAMS_CHECK>", GenDelegateParamsCheck(iface, decl))
-      .ChangeToUpper("<DELEGATE_ENUM_VALUE>", enum_value)
-      .Change("<DELEGATE_UNIT_MAP_WRITE>", GenDelegateUnitMapWrite(iface, decl))
-      .ChangeToUpper("<UPPERCASE_PREFIX>", GetHandlePrefix())
-      .ChangeToUpper("<UPPERCASE_NAME>", iface.GetID())
+  std::string enum_value =
+      GetHandlePrefix() + "_" + iface.GetID() + "_DELEGATE_" + decl.GetID();
+  return ReplaceAll(CB_INTERFACE_DELEGATE_BASE)
+      .Replace("PREFIX", GetHandlePrefix())
+      .Replace("NAME", iface.GetID())
+      .Replace("DELEGATE_NAME", decl.GetID())
+      .Replace("DELEGATE_PARAMS", GenDelegateParams(iface, decl))
+      .Replace("DELEGATE_PARAMS_CHECK", GenDelegateParamsCheck(iface, decl))
+      .ReplaceToUpper("DELEGATE_ENUM_VALUE", enum_value)
+      .Replace("DELEGATE_UNIT_MAP_WRITE", GenDelegateUnitMapWrite(iface, decl))
+      .ReplaceToUpper("UPPERCASE_PREFIX", GetHandlePrefix())
+      .ReplaceToUpper("UPPERCASE_NAME", iface.GetID())
+      .Replace("HASH_METHOD", "[METHOD]"_hash)
+      .Replace("HASH_DELEGATE", "delegate"_hash)
       .Transform([&](std::string code) { return SmartIndent(code); })
-      .Out(stream);
+      .ToString();
 }
 
 std::string CStubBodyGenerator::GenMethodHandlerArgsDecl(
@@ -442,41 +274,55 @@ std::string CStubBodyGenerator::GenMethodUnitMapRead(const Interface& iface,
   for (const auto& p : decl.GetParameters()) {
     std::string parcel_read_code;
     auto& param_type = p->GetParameterType();
-    if (param_type.GetDirection() == ParameterType::Direction::OUT)
-      continue;
+    if (param_type.GetDirection() == ParameterType::Direction::OUT) continue;
 
     auto& type = param_type.GetBaseType();
     if (type.GetUserDefinedType() == BaseType::UserType::DELEGATE) {
-      parcel_read_code = ReplaceAll(CB_INTERFACE_METHOD_DELEGATE_UNIT_MAP_READ)
-          .Change("<PREFIX>", GetHandlePrefix())
-          .Change("<TYPE_NAME>", GetFullNameFromType(type, iface))
-          .Change("<ARG_NAME>", std::string("delegate"))
-          .Change("<ARG>", p->GetID());
+      parcel_read_code =
+          ReplaceAll(CB_INTERFACE_METHOD_DELEGATE_UNIT_MAP_READ)
+              .Replace("PREFIX", GetHandlePrefix())
+              .Replace("TYPE_NAME", GetFullNameFromType(type, iface))
+              .Replace("ARG_NAME", std::string("delegate"))
+              .Replace("ARG", p->GetID())
+              .Replace("HASH_ARG", GetHashCodeStr(p->GetID()));
     } else if (type.GetUserDefinedType() == BaseType::UserType::ENUM) {
       code += ReplaceAll(CB_INTERFACE_METHOD_EMUM_UNIT_MAP_READ)
-          .Change("<ARG_NAME>", p->GetID())
-          .Change("<ARG>", p->GetID());
+                  .Replace("ARG_NAME", p->GetID())
+                  .Replace("HASH_ARG_NAME", GetHashCodeStr(p->GetID()))
+                  .Replace("ARG", p->GetID());
     } else if (type.GetUserDefinedType() == BaseType::UserType::STRUCTURE ||
-        type.GetMetaType() != nullptr ||
-        type.GetKeyType() != nullptr) {
+               type.GetMetaType() != nullptr || type.GetKeyType() != nullptr) {
       parcel_read_code =
           ReplaceAll(CB_INTERFACE_METHOD_USER_DEFINED_UNIT_MAP_READ)
-              .Change("<TYPE_NAME>", GetFullNameFromType(type, iface))
-              .Change("<ARG_NAME>", p->GetID())
-              .Change("<ARG>", p->GetID());
+              .Replace("TYPE_NAME", GetFullNameFromType(type, iface))
+              .Replace("ARG_NAME", p->GetID())
+              .Replace("HASH_ARG_NAME", GetHashCodeStr(p->GetID()))
+              .Replace("ARG", p->GetID());
     } else if (type.ToString() == "bundle") {
-      parcel_read_code = ReplaceAll(CB_INTERFACE_METHOD_BUNDLE_UNIT_MAP_READ)
-          .Change("<ARG_NAME>", p->GetID())
-          .Change("<ARG>", p->GetID());
-    } else if (type.ToString() == "string" || type.ToString() == "file") {
-      parcel_read_code = ReplaceAll(CB_INTERFACE_METHOD_STRING_UNIT_MAP_READ)
-          .Change("<ARG_NAME>", p->GetID())
-          .Change("<ARG>", p->GetID());
+      parcel_read_code =
+          ReplaceAll(CB_INTERFACE_METHOD_BUNDLE_UNIT_MAP_READ)
+              .Replace("ARG_NAME", p->GetID())
+              .Replace("HASH_ARG_NAME", GetHashCodeStr(p->GetID()))
+              .Replace("ARG", p->GetID());
+    } else if (type.ToString() == "string") {
+      parcel_read_code =
+          ReplaceAll(CB_INTERFACE_METHOD_STRING_UNIT_MAP_READ)
+              .Replace("ARG_NAME", p->GetID())
+              .Replace("HASH_ARG_NAME", GetHashCodeStr(p->GetID()))
+              .Replace("ARG", p->GetID());
+    } else if (type.ToString() == "file") {
+      parcel_read_code =
+          ReplaceAll(CB_INTERFACE_METHOD_FILE_UNIT_MAP_READ)
+              .Replace("ARG_NAME", p->GetID())
+              .Replace("HASH_ARG_NAME", GetHashCodeStr(p->GetID()))
+              .Replace("ARG", p->GetID());
     } else {
-      parcel_read_code = ReplaceAll(CB_INTERFACE_METHOD_BASE_UNIT_MAP_READ)
-          .Change("<TYPE_NAME>", GetFullNameFromType(type, iface))
-          .Change("<ARG_NAME>", p->GetID())
-          .Change("<ARG>", p->GetID());
+      parcel_read_code =
+          ReplaceAll(CB_INTERFACE_METHOD_BASE_UNIT_MAP_READ)
+              .Replace("TYPE_NAME", GetFullNameFromType(type, iface))
+              .Replace("ARG_NAME", p->GetID())
+              .Replace("HASH_ARG_NAME", GetHashCodeStr(p->GetID()))
+              .Replace("ARG", p->GetID());
     }
 
     code += parcel_read_code;
@@ -492,8 +338,7 @@ std::string CStubBodyGenerator::GenMethodHandlerCallbackInvoke(
   for (const auto& p : decl.GetParameters()) {
     args += ", ";
     auto& param_type = p->GetParameterType();
-    if (param_type.GetDirection() != ParameterType::Direction::IN)
-      args += "&";
+    if (param_type.GetDirection() != ParameterType::Direction::IN) args += "&";
 
     args += p->GetID();
   }
@@ -502,11 +347,11 @@ std::string CStubBodyGenerator::GenMethodHandlerCallbackInvoke(
       (decl.GetMethodType() == Declaration::MethodType::SYNC) ? "res_ = " : "";
 
   return RemoveLine(std::string(ReplaceAll(CB_INTERFACE_METHOD_CALLBACK_INVOKE)
-                                    .Change("<METHOD_NAME>", decl.GetID())
-                                    .Change("<PREFIX>", GetHandlePrefix())
-                                    .Change("<NAME>", iface.GetID())
-                                    .Change("<RES_SET>", res_set)
-                                    .Change("<METHOD_ARGS>", args)));
+                                    .Replace("METHOD_NAME", decl.GetID())
+                                    .Replace("PREFIX", GetHandlePrefix())
+                                    .Replace("NAME", iface.GetID())
+                                    .Replace("RES_SET", res_set)
+                                    .Replace("METHOD_ARGS", args)));
 }
 
 std::string CStubBodyGenerator::GenDelegateUnitMapWrite(
@@ -526,45 +371,52 @@ std::string CStubBodyGenerator::GenDelegateUnitMapWrite(
 // @see #CB_INTERFACE_METHOD_STRING_UNIT_MAP_WRITE
 // @see #CB_INTERFACE_METHOD_BASE_UNIT_MAP_WRITE
 std::string CStubBodyGenerator::GenMethodUnitMapWriteBase(
-    const Interface& iface, const BaseType& type,
-    const std::string& arg_name, const std::string& arg) {
+    const Interface& iface, const BaseType& type, const std::string& arg_name,
+    const std::string& arg) {
   std::string parcel_write_code;
 
   if (type.GetUserDefinedType() == BaseType::UserType::DELEGATE) {
     parcel_write_code = ReplaceAll(CB_INTERFACE_METHOD_DELEGATE_UNIT_MAP_WRITE)
-        .Change("<ARG_NAME>", std::string("delegate"))
-        .Change("<ARG>", arg);
+                            .Replace("ARG_NAME", std::string("delegate"))
+                            .Replace("HASH_ARG_NAME", "delegate"_hash)
+                            .Replace("ARG", arg);
   } else if (type.GetUserDefinedType() == BaseType::UserType::ENUM) {
     parcel_write_code = ReplaceAll(CB_INTERFACE_METHOD_ENUM_UNIT_MAP_WRITE)
-        .Change("<ARG_NAME>", arg_name)
-        .Change("<ARG>", arg);
-  } else if (type.IsUserDefinedType() ||
-      type.GetMetaType() != nullptr ||
-      type.GetKeyType() != nullptr) {
+                            .Replace("ARG_NAME", arg_name)
+                            .Replace("HASH_ARG_NAME", GetHashCodeStr(arg_name))
+                            .Replace("ARG", arg);
+  } else if (type.IsUserDefinedType() || type.GetMetaType() != nullptr ||
+             type.GetKeyType() != nullptr) {
     parcel_write_code =
         ReplaceAll(CB_INTERFACE_METHOD_USER_DEFINED_UNIT_MAP_WRITE)
-            .Change("<TYPE_NAME>", GetFullNameFromType(type, iface))
-            .Change("<ARG_NAME>", arg_name)
-            .Change("<ARG>", arg);
+            .Replace("TYPE_NAME", GetFullNameFromType(type, iface))
+            .Replace("ARG_NAME", arg_name)
+            .Replace("HASH_ARG_NAME", GetHashCodeStr(arg_name))
+            .Replace("ARG", arg);
     parcel_write_code += GetPrivateSharingString(type, iface, "port", arg);
   } else if (type.ToString() == "bundle") {
     parcel_write_code = ReplaceAll(CB_INTERFACE_METHOD_BUNDLE_UNIT_MAP_WRITE)
-        .Change("<ARG_NAME>", arg_name)
-        .Change("<ARG>", arg);
+                            .Replace("ARG_NAME", arg_name)
+                            .Replace("HASH_ARG_NAME", GetHashCodeStr(arg_name))
+                            .Replace("ARG", arg);
   } else if (type.ToString() == "string") {
     parcel_write_code = ReplaceAll(CB_INTERFACE_METHOD_STRING_UNIT_MAP_WRITE)
-        .Change("<ARG_NAME>", arg_name)
-        .Change("<ARG>", "STRING_GET(" + arg + ")");
+                            .Replace("ARG_NAME", arg_name)
+                            .Replace("HASH_ARG_NAME", GetHashCodeStr(arg_name))
+                            .Replace("ARG", "STRING_GET(" + arg + ")");
   } else if (type.ToString() == "file") {
-    parcel_write_code = ReplaceAll(CB_INTERFACE_METHOD_STRING_UNIT_MAP_WRITE)
-        .Change("<ARG_NAME>", arg_name)
-        .Change("<ARG>", arg);
+    parcel_write_code = ReplaceAll(CB_INTERFACE_METHOD_FILE_UNIT_MAP_WRITE)
+                            .Replace("ARG_NAME", arg_name)
+                            .Replace("HASH_ARG_NAME", GetHashCodeStr(arg_name))
+                            .Replace("ARG", arg);
     parcel_write_code += GetPrivateSharingString(type, iface, "port", arg_name);
   } else {
-    parcel_write_code = ReplaceAll(CB_INTERFACE_METHOD_BASE_UNIT_MAP_WRITE)
-        .Change("<TYPE_NAME>", GetFullNameFromType(type, iface))
-        .Change("<ARG_NAME>", arg_name)
-        .Change("<ARG>", arg);
+    parcel_write_code =
+        ReplaceAll(CB_INTERFACE_METHOD_BASE_UNIT_MAP_WRITE)
+            .Replace("TYPE_NAME", GetFullNameFromType(type, iface))
+            .Replace("ARG_NAME", arg_name)
+            .Replace("HASH_ARG_NAME", GetHashCodeStr(arg_name))
+            .Replace("ARG", arg);
   }
 
   return parcel_write_code;
@@ -572,20 +424,19 @@ std::string CStubBodyGenerator::GenMethodUnitMapWriteBase(
 // @see #CB_INTERFACE_METHOD_PARCEL_WRITE_PRE
 // @see #CB_INTERFACE_METHOD_PARCEL_WRITE_POST
 std::string CStubBodyGenerator::GenMethodUnitMapWrite(const Interface& iface,
-    const Declaration& decl) {
+                                                      const Declaration& decl) {
   std::string code;
-  if (decl.GetMethodType() != Declaration::MethodType::SYNC)
-    return code;
+  if (decl.GetMethodType() != Declaration::MethodType::SYNC) return code;
 
   code = ReplaceAll(CB_INTERFACE_METHOD_PARCEL_WRITE_PRE)
-      .ChangeToUpper("<UPPERCASE_PREFIX>", GetHandlePrefix())
-      .ChangeToUpper("<UPPERCASE_NAME>", iface.GetID());
+             .ReplaceToUpper("UPPERCASE_PREFIX", GetHandlePrefix())
+             .ReplaceToUpper("UPPERCASE_NAME", iface.GetID())
+             .Replace("HASH_METHOD", "[METHOD]"_hash);
 
   std::string parcel_write_code;
   for (const auto& p : decl.GetParameters()) {
     auto& param_type = p->GetParameterType();
-    if (param_type.GetDirection() == ParameterType::Direction::IN)
-      continue;
+    if (param_type.GetDirection() == ParameterType::Direction::IN) continue;
 
     code += GenMethodUnitMapWriteBase(iface, param_type.GetBaseType(),
                                       p->GetID(), p->GetID());
@@ -594,8 +445,9 @@ std::string CStubBodyGenerator::GenMethodUnitMapWrite(const Interface& iface,
   code += GenMethodUnitMapWriteBase(iface, decl.GetType(), "[RESULT]", "res_");
 
   code += ReplaceAll(CB_INTERFACE_METHOD_PARCEL_WRITE_POST)
-      .Change("<PREFIX>", GetHandlePrefix())
-      .Change("<NAME>", iface.GetID());
+              .Replace("PREFIX", GetHandlePrefix())
+              .Replace("NAME", iface.GetID())
+              .Replace("HASH_REMOTE_EXCEPTION", "[REMOTE_EXCEPTION]"_hash);
 
   return RemoveLine(code);
 }
@@ -603,8 +455,8 @@ std::string CStubBodyGenerator::GenMethodUnitMapWrite(const Interface& iface,
 // @see #CB_INTERFACE_METHOD_USER_DEFINED_FREE
 // @see #CB_INTERFACE_METHOD_BUNDLE_FREE
 // @see #CB_INTERFACE_METHOD_STRING_FREE
-std::string CStubBodyGenerator::GenMethodHandlerArgsFree(const Interface& iface,
-    const Declaration& decl) {
+std::string CStubBodyGenerator::GenMethodHandlerArgsFree(
+    const Interface& iface, const Declaration& decl) {
   std::string code;
   for (const auto& p : decl.GetParameters()) {
     auto& param_type = p->GetParameterType();
@@ -612,15 +464,15 @@ std::string CStubBodyGenerator::GenMethodHandlerArgsFree(const Interface& iface,
     if (type.IsStructureType() || type.IsDelegateType() ||
         type.GetMetaType() != nullptr || type.GetKeyType() != nullptr) {
       code += ReplaceAll(CB_INTERFACE_METHOD_USER_DEFINED_FREE)
-                  .Change("<PREFIX>", GetHandlePrefix())
-                  .Change("<NAME>", GetFullNameFromType(type, iface))
-                  .Change("<ARG>", p->GetID());
+                  .Replace("PREFIX", GetHandlePrefix())
+                  .Replace("NAME", GetFullNameFromType(type, iface))
+                  .Replace("ARG", p->GetID());
     } else if (type.ToString() == "bundle") {
       code += ReplaceAll(CB_INTERFACE_METHOD_BUNDLE_FREE)
-                  .Change("<ARG>", p->GetID());
+                  .Replace("ARG", p->GetID());
     } else if (type.ToString() == "string" || type.ToString() == "file") {
       code += ReplaceAll(CB_INTERFACE_METHOD_STRING_FREE)
-                  .Change("<ARG>", p->GetID());
+                  .Replace("ARG", p->GetID());
     }
   }
 
@@ -630,13 +482,13 @@ std::string CStubBodyGenerator::GenMethodHandlerArgsFree(const Interface& iface,
     if (type.IsStructureType() || type.IsDelegateType() ||
         type.GetMetaType() != nullptr || type.GetKeyType() != nullptr) {
       code += ReplaceAll(CB_INTERFACE_METHOD_USER_DEFINED_FREE)
-                  .Change("<PREFIX>", GetHandlePrefix())
-                  .Change("<NAME>", GetFullNameFromType(type, iface))
-                  .Change("<ARG>", arg);
+                  .Replace("PREFIX", GetHandlePrefix())
+                  .Replace("NAME", GetFullNameFromType(type, iface))
+                  .Replace("ARG", arg);
     } else if (type.ToString() == "bundle") {
-      code += ReplaceAll(CB_INTERFACE_METHOD_BUNDLE_FREE).Change("<ARG>", arg);
+      code += ReplaceAll(CB_INTERFACE_METHOD_BUNDLE_FREE).Replace("ARG", arg);
     } else if (type.ToString() == "string" || type.ToString() == "file") {
-      code += ReplaceAll(CB_INTERFACE_METHOD_STRING_FREE).Change("<ARG>", arg);
+      code += ReplaceAll(CB_INTERFACE_METHOD_STRING_FREE).Replace("ARG", arg);
     }
   }
 
@@ -646,8 +498,7 @@ std::string CStubBodyGenerator::GenMethodHandlerArgsFree(const Interface& iface,
 std::string CStubBodyGenerator::GenPrivileges(const Declaration& decl) {
   std::string code;
   for (const auto& attr : decl.GetAttributes()) {
-    if (attr->GetKey() != "privilege")
-      continue;
+    if (attr->GetKey() != "privilege") continue;
 
     code += "\"" + attr->GetValue() + "\"," + NLine(1);
   }
@@ -659,118 +510,114 @@ std::string CStubBodyGenerator::GenPrivileges(const Declaration& decl) {
 std::string CStubBodyGenerator::GenMethodPrivilegeChecker(
     const Declaration& decl) {
   auto privileges = GenPrivileges(decl);
-  if (privileges.empty())
-    return "return RPC_PORT_ERROR_NONE;" + NLine(1);
+  if (privileges.empty()) return "return RPC_PORT_ERROR_NONE;" + NLine(1);
 
-  std::string sync =
-      (decl.GetMethodType() == Declaration::MethodType::SYNC) ?
-      "true" : "false";
+  std::string sync = (decl.GetMethodType() == Declaration::MethodType::SYNC)
+                         ? "true"
+                         : "false";
   return RemoveLine(
       std::string(ReplaceAll(CB_INTERFACE_METHOD_PRIVILEGE_CHECKER)
-                      .Change("<PRIVILEGES>", privileges)
-                      .Change("<SYNC_TRUE_OR_FALSE>", sync)));
+                      .Replace("PRIVILEGES", privileges)
+                      .Replace("SYNC_TRUE_OR_FALSE", sync)));
 }
 
 // @see #CB_INTERFACE_METHOD_PRIVILEGE_CHECKER_BASE
-void CStubBodyGenerator::GenInterfaceMethodPrivilegeCheckerBase(
-    std::ofstream& stream, const Interface& iface, const Declaration& decl) {
-  ReplaceAll(CB_INTERFACE_METHOD_PRIVILEGE_CHECKER_BASE)
-      .Change("<PREFIX>", GetHandlePrefix())
-      .Change("<NAME>", iface.GetID())
-      .Change("<METHOD_NAME>", decl.GetID())
-      .Change("<METHOD_PRIVILEGE_CHECKER>", GenMethodPrivilegeChecker(decl))
+std::string CStubBodyGenerator::GetInterfaceMethodPrivilegeCheckerBase(
+    const Interface& iface, const Declaration& decl) {
+  return ReplaceAll(CB_INTERFACE_METHOD_PRIVILEGE_CHECKER_BASE)
+      .Replace("PREFIX", GetHandlePrefix())
+      .Replace("NAME", iface.GetID())
+      .Replace("METHOD_NAME", decl.GetID())
+      .Replace("METHOD_PRIVILEGE_CHECKER", GenMethodPrivilegeChecker(decl))
       .Transform([&](std::string code) { return SmartIndent(code); })
-      .Out(stream);
+      .ToString();
 }
 
 // @see #CB_INTERFACE_METHOD_HANDLER_BASE
-void CStubBodyGenerator::GenInterfaceMethodHandlerBase(
-    std::ofstream& stream, const Interface& iface, const Declaration& decl) {
-  ReplaceAll(CB_INTERFACE_METHOD_HANDLER_BASE)
-      .Change("<PREFIX>", GetHandlePrefix())
-      .Change("<NAME>", iface.GetID())
-      .Change("<METHOD_NAME>", decl.GetID())
-      .Change("<METHOD_HANDLER_ARGS_DECL>",
-              GenMethodHandlerArgsDecl(iface, decl))
-      .Change("<METHOD_UNIT_MAP_READ>", GenMethodUnitMapRead(iface, decl))
-      .Change("<METHOD_HANDLER_CALLBACK_INVOKE>",
-              GenMethodHandlerCallbackInvoke(iface, decl))
-      .Change("<METHOD_UNIT_MAP_WRITE>", GenMethodUnitMapWrite(iface, decl))
-      .Change("<METHOD_HANDLER_ARGS_FREE>",
-              GenMethodHandlerArgsFree(iface, decl))
+std::string CStubBodyGenerator::GetInterfaceMethodHandlerBase(
+    const Interface& iface, const Declaration& decl) {
+  return ReplaceAll(CB_INTERFACE_METHOD_HANDLER_BASE)
+      .Replace("PREFIX", GetHandlePrefix())
+      .Replace("NAME", iface.GetID())
+      .Replace("METHOD_NAME", decl.GetID())
+      .Replace("METHOD_HANDLER_ARGS_DECL",
+               GenMethodHandlerArgsDecl(iface, decl))
+      .Replace("METHOD_UNIT_MAP_READ", GenMethodUnitMapRead(iface, decl))
+      .Replace("METHOD_HANDLER_CALLBACK_INVOKE",
+               GenMethodHandlerCallbackInvoke(iface, decl))
+      .Replace("METHOD_UNIT_MAP_WRITE", GenMethodUnitMapWrite(iface, decl))
+      .Replace("METHOD_HANDLER_ARGS_FREE",
+               GenMethodHandlerArgsFree(iface, decl))
       .Transform([&](std::string code) { return SmartIndent(code); })
-      .Out(stream);
+      .ToString();
 }
 
 // @ see #CB_INTERFACE_PRIVILEGE_CHECKER
 std::string CStubBodyGenerator::GenPrivilegeCheckers(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;
 
-    std::string enum_value = GetHandlePrefix() + "_" + iface.GetID() +
-        "_METHOD_" + decl->GetID();
+    std::string enum_value =
+        GetHandlePrefix() + "_" + iface.GetID() + "_METHOD_" + decl->GetID();
     code += ReplaceAll(CB_INTERFACE_PRIVILEGE_CHECKER)
-        .Change("<PREFIX>", GetHandlePrefix())
-        .Change("<NAME>", iface.GetID())
-        .Change("<METHOD_NAME>", decl->GetID())
-        .ChangeToUpper("<ENUM_VALUE>", enum_value)
-        .Transform([&](std::string str) { return RemoveLine(str); });
+                .Replace("PREFIX", GetHandlePrefix())
+                .Replace("NAME", iface.GetID())
+                .Replace("METHOD_NAME", decl->GetID())
+                .ReplaceToUpper("ENUM_VALUE", enum_value)
+                .Transform([&](std::string str) { return RemoveLine(str); });
   }
 
   return code;
 }
 
 // @see #CB_INTERFACE_METHOD_PRIVIELGE_CHECKER_TABLE
-void CStubBodyGenerator::GenInterfaceMethodPrivilegeCheckerTable(
-    std::ofstream& stream, const Interface& iface) {
-  ReplaceAll(CB_INTERFACE_METHOD_PRIVIELGE_CHECKER_TABLE)
-      .Change("<PREFIX>", GetHandlePrefix())
-      .Change("<NAME>", iface.GetID())
-      .Change("<PRIVILEGE_CHECKERS>", GenPrivilegeCheckers(iface))
+std::string CStubBodyGenerator::GetInterfaceMethodPrivilegeCheckerTable(
+    const Interface& iface) {
+  return ReplaceAll(CB_INTERFACE_METHOD_PRIVIELGE_CHECKER_TABLE)
+      .Replace("PREFIX", GetHandlePrefix())
+      .Replace("NAME", iface.GetID())
+      .Replace("PRIVILEGE_CHECKERS", GenPrivilegeCheckers(iface))
       .Transform([&](std::string code) { return SmartIndent(code); })
-      .Out(stream);
+      .ToString();
 }
 
 // @see #CB_INTERFACE_METHOD_HANDLER
 std::string CStubBodyGenerator::GenMethodHandlers(const Interface& iface) {
   std::string code;
   for (const auto& d : iface.GetDeclarations()) {
-    if (d->GetMethodType() == Declaration::MethodType::DELEGATE)
-      continue;
-
-    std::string enum_value = GetHandlePrefix() + "_" + iface.GetID() +
-      "_METHOD_" + d->GetID();
-    code +=
-        RemoveLine(std::string(ReplaceAll(CB_INTERFACE_METHOD_HANDLER)
-                                   .ChangeToUpper("<ENUM_VALUE>", enum_value)
-                                   .Change("<PREFIX>", GetHandlePrefix())
-                                   .Change("<NAME>", iface.GetID())
-                                   .Change("<METHOD_NAME>", d->GetID())));
+    if (d->GetMethodType() == Declaration::MethodType::DELEGATE) continue;
+
+    std::string enum_value =
+        GetHandlePrefix() + "_" + iface.GetID() + "_METHOD_" + d->GetID();
+    code += RemoveLine(std::string(ReplaceAll(CB_INTERFACE_METHOD_HANDLER)
+                                       .ReplaceToUpper("ENUM_VALUE", enum_value)
+                                       .Replace("PREFIX", GetHandlePrefix())
+                                       .Replace("NAME", iface.GetID())
+                                       .Replace("METHOD_NAME", d->GetID())));
   }
 
   return code;
 }
 
 // @see #CB_INTERFACE_METHOD_TABLE
-void CStubBodyGenerator::GenInterfaceMethodTable(std::ofstream& stream,
-                                                 const Interface& iface) {
-  ReplaceAll(CB_INTERFACE_METHOD_TABLE)
-      .Change("<NAME>", iface.GetID())
-      .Change("<METHOD_HANDLERS>", GenMethodHandlers(iface))
+std::string CStubBodyGenerator::GetInterfaceMethodTable(
+    const Interface& iface) {
+  return ReplaceAll(CB_INTERFACE_METHOD_TABLE)
+      .Replace("NAME", iface.GetID())
+      .Replace("METHOD_HANDLERS", GenMethodHandlers(iface))
       .Transform([&](std::string code) { return SmartIndent(code); })
-      .Out(stream);
+      .ToString();
 }
 
 // @see #CB_INTERFACE_CALLBACK_PORT_CHECK
-void CStubBodyGenerator::GenInterfaceCallbackPortCheck(std::ofstream& stream,
-                                                       const Interface& iface) {
-  ReplaceAll(CB_INTERFACE_CALLBACK_PORT_CHECK)
-      .Change("<PREFIX>", GetHandlePrefix())
-      .Change("<NAME>", iface.GetID())
+std::string CStubBodyGenerator::GetInterfaceCallbackPortCheck(
+    const Interface& iface) {
+  return ReplaceAll(CB_INTERFACE_CALLBACK_PORT_CHECK)
+      .Replace("PREFIX", GetHandlePrefix())
+      .Replace("NAME", iface.GetID())
       .Transform([&](std::string code) { return SmartIndent(code); })
-      .Out(stream);
+      .ToString();
 }
 
 // @see #CB_INTERFACE_PRIVILEGE_ADD
@@ -780,11 +627,11 @@ std::string CStubBodyGenerator::GenAccessControlSet(const Interface& iface) {
   for (const auto& attr : iface.GetAttributes()) {
     if (attr->GetKey() == "privilege") {
       code += ReplaceAll(CB_INTERFACE_PRIVILEGE_ADD)
-          .Change("<NAME>", iface.GetID())
-          .Change("<PRIVILEGE>", attr->GetValue());
+                  .Replace("NAME", iface.GetID())
+                  .Replace("PRIVILEGE", attr->GetValue());
     } else if (attr->GetKey() == "trusted" && attr->GetValue() == "true") {
-      code += ReplaceAll(CB_INTERFACE_TRUSTED_SET)
-          .Change("<NAME>", iface.GetID());
+      code +=
+          ReplaceAll(CB_INTERFACE_TRUSTED_SET).Replace("NAME", iface.GetID());
     }
   }
 
@@ -792,39 +639,42 @@ std::string CStubBodyGenerator::GenAccessControlSet(const Interface& iface) {
 }
 
 // @see #CB_INTERFACE_BASE
-void CStubBodyGenerator::GenInterfaceBase(std::ofstream& stream,
-    const Interface& iface) {
-  ReplaceAll(CB_INTERFACE_BASE)
-      .Change("<PREFIX>", GetHandlePrefix())
-      .Change("<PREFIX_REVERSE>", GetHandlePrefixReverse())
-      .Change("<NAME>", iface.GetID())
-      .Change("<ACCESS_CONTROL_SET>", GenAccessControlSet(iface))
+std::string CStubBodyGenerator::GetInterfaceBase(const Interface& iface) {
+  return ReplaceAll(CB_INTERFACE_BASE)
+      .Replace("PREFIX", GetHandlePrefix())
+      .Replace("PREFIX_REVERSE", GetHandlePrefixReverse())
+      .Replace("NAME", iface.GetID())
+      .Replace("ACCESS_CONTROL_SET", GenAccessControlSet(iface))
       .Transform([&](std::string code) { return SmartIndent(code); })
-      .Out(stream);
+      .ToString();
 }
 
 // @see #CB_INTERFACE_EXTENSION_BASE
-void CStubBodyGenerator::GenInterfaceExtensionBase(std::ofstream& stream,
-                                                   const Interface& iface) {
+std::string CStubBodyGenerator::GetInterfaceExtensionBase(
+    const Interface& iface) {
   if (options_->UseExtension()) {
-    ReplaceAll(CB_INTERFACE_EXTENSION_BASE)
-        .Change("<PREFIX>", GetHandlePrefix())
-        .Change("<NAME>", iface.GetID())
+    return ReplaceAll(CB_INTERFACE_EXTENSION_BASE)
+        .Replace("PREFIX", GetHandlePrefix())
+        .Replace("NAME", iface.GetID())
         .Transform([&](std::string code) { return SmartIndent(code); })
-        .Out(stream);
+        .ToString();
   }
+
+  return "";
 }
 
 // @see #CB_INTERFACE_CONTEXT_EXTENSION_BASE
-void CStubBodyGenerator::GenInterfaceContextExtensionBase(
-    std::ofstream& stream, const Interface& iface) {
+std::string CStubBodyGenerator::GetInterfaceContextExtensionBase(
+    const Interface& iface) {
   if (options_->UseExtension()) {
-    ReplaceAll(CB_INTERFACE_CONTEXT_EXTENSION_BASE)
-        .Change("<PREFIX>", GetHandlePrefix())
-        .Change("<NAME>", iface.GetID())
+    return ReplaceAll(CB_INTERFACE_CONTEXT_EXTENSION_BASE)
+        .Replace("PREFIX", GetHandlePrefix())
+        .Replace("NAME", iface.GetID())
         .Transform([&](std::string code) { return SmartIndent(code); })
-        .Out(stream);
+        .ToString();
   }
+
+  return "";
 }
 
 }  // namespace version2
index afd87c640a7dc979ad0d200a31bb033eddcb1950..8eb53c4b90523e1543070c144ca08acced909bbb 100644 (file)
@@ -36,50 +36,20 @@ class CStubBodyGenerator : public CBodyGeneratorBase {
   void OnFiniGen(std::ofstream& stream) override;
 
  private:
-  void GenIncludePrivateHeaders(std::ofstream& stream);
-  void GenIncludeInternalHeaders(std::ofstream& stream);
-  void GenThreadEnableDefinition(std::ofstream& stream);
-  void GenInterfaceMethodHandlerType(std::ofstream& stream);
-  void GenInterfaceEnums(std::ofstream& stream);
-  void GenInterfaceEnum(std::ofstream& stream, const Interface& iface);
-  void GenInterfaceMethodEnumBase(std::ofstream& stream,
-                                  const Interface& iface);
-  void GenInterfaceDelegateEnumBase(std::ofstream& stream,
-                                    const Interface& iface);
-
-  void GenInterfaceDefs(std::ofstream& stream);
-  void GenInterfaceDef(std::ofstream& stream, const Interface& iface);
-  void GenInterfaceContextDef(std::ofstream& stream, const Interface& iface);
-  void GenInterfaceDelegateDef(std::ofstream& stream, const Interface& iface,
-                               const Declaration& decl);
-  void GenInterfaceCallbackPortCheckDef(std::ofstream& stream,
-                                        const Interface& iface);
-  void GenInterfaceBaseDef(std::ofstream& stream, const Interface& iface);
-
-  void GenInterfaces(std::ofstream& stream);
-  void GenInterface(std::ofstream& stream, const Interface& iface);
-  void GenInterfaceContextBase(std::ofstream& stream, const Interface& iface);
-  void GenInterfaceDelegateBase(std::ofstream& stream, const Interface& iface,
-                                const Declaration& decl);
-  void GenInterfaceMethodPrivilegeCheckerBase(std::ofstream& stream,
-                                              const Interface& iface,
-                                              const Declaration& decl);
-  void GenInterfaceMethodPrivilegeCheckerTable(std::ofstream& stream,
-                                               const Interface& iface);
-  void GenInterfaceMethodHandlerBase(std::ofstream& stream,
-                                     const Interface& iface,
-                                     const Declaration& decl);
-  void GenInterfaceMethodTable(std::ofstream& stream, const Interface& iface);
-  void GenInterfaceCallbackPortCheck(std::ofstream& stream,
-                                     const Interface& iface);
-  void GenInterfaceBase(std::ofstream& stream, const Interface& iface);
-  void GenInterfaceExtensionBase(std::ofstream& stream, const Interface& iface);
-  void GenInterfaceContextExtensionBase(std::ofstream& stream,
-                                        const Interface& iface);
-
-  std::string GenMethodEnums(const Interface& iface);
-  std::string GenDelegateEnums(const Interface& iface);
-
+  std::string GetInterface(const Interface& iface);
+  std::string GetInterfaceContextBase(const Interface& iface);
+  std::string GetInterfaceDelegateBase(const Interface& iface,
+                                       const Declaration& decl);
+  std::string GetInterfaceMethodPrivilegeCheckerBase(const Interface& iface,
+                                                     const Declaration& decl);
+  std::string GetInterfaceMethodPrivilegeCheckerTable(const Interface& iface);
+  std::string GetInterfaceMethodHandlerBase(const Interface& iface,
+                                            const Declaration& decl);
+  std::string GetInterfaceMethodTable(const Interface& iface);
+  std::string GetInterfaceCallbackPortCheck(const Interface& iface);
+  std::string GetInterfaceBase(const Interface& iface);
+  std::string GetInterfaceExtensionBase(const Interface& iface);
+  std::string GetInterfaceContextExtensionBase(const Interface& iface);
   std::string GenDelegateParams(const Interface& iface,
                                 const Declaration& decl);
   std::string GenDelegateParamsCheck(const Interface& iface,
@@ -105,12 +75,7 @@ class CStubBodyGenerator : public CBodyGeneratorBase {
                                        const Declaration& decl);
   std::string GenMethodHandlers(const Interface& iface);
   std::string GenAccessControlSet(const Interface& iface);
-  void GenDelegateDefinition(std::ofstream& stream);
-  void GenDelegateBase(std::ofstream& stream);
-  std::string GenLemContext();
-  void GenLemDefinition(std::ofstream& stream);
-  void GenLemBase(std::ofstream& stream);
-  void GenLemAPI(std::ofstream& stream);
+  std::string GetLemBase();
 
  private:
   std::shared_ptr<Options> options_;
index 0748060c597c83bdffcf386f7c227ba7af5d339b..a2df5c865d919c1fe2559ee9d0b67d581f13c457 100644 (file)
 namespace tidl {
 namespace version2 {
 
-constexpr const char CB_PRIVATE_HEADERS[] =
+constexpr const char CB_MAIN_STUB[] =
 R"__c_cb(
+/*
+ * Generated by tidlc <VERSION>.
+ */
+
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+
+#pragma GCC diagnostic ignored "-Warray-bounds"
+#pragma GCC diagnostic ignored "-Wunused-function"
+
+#include <pthread.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <libgen.h>
+#include <glib.h>
+#include <dlog.h>
+#include <rpc-port.h>
+#include <rpc-port-parcel.h>
 #include <app_manager.h>
 #include <package_manager.h>
-)__c_cb";
+#include <unistd.h>
+#include <dlfcn.h>
+#include <app_common.h>
 
-constexpr const char CB_DELEGATE_DEFS[] =
-R"__c_cb(
-#ifndef TIDL_USE_DELEGATE
-#define TIDL_USE_DELEGATE 1
+<INCLUDE>
+
+#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(__FILE__), __FUNCTION__, __LINE__, ##__VA_ARGS__)
+
+#undef _W
+#define _W(fmt, ...) dlog_print(DLOG_WARN, LOG_TAG, "%s: %s(%d) > "fmt, basename(__FILE__), __FUNCTION__, __LINE__, ##__VA_ARGS__)
+
+#undef _I
+#define _I(fmt, ...) dlog_print(DLOG_INFO, LOG_TAG, "%s: %s(%d) > "fmt, basename(__FILE__), __FUNCTION__, __LINE__, ##__VA_ARGS__)
+
+#undef _D
+#define _D(fmt, ...) dlog_print(DLOG_DEBUG, LOG_TAG, "%s: %s(%d) > "fmt, basename(__FILE__), __FUNCTION__, __LINE__, ##__VA_ARGS__)
+
+#ifndef TIDL_VERSION
+#define TIDL_VERSION "<VERSION>"
+#endif
+
+#ifndef nullptr
+#define nullptr NULL
 #endif
 
+#ifndef ARRAY_SIZE
+#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
+#endif
+
+#ifndef STRING_GET
+#define STRING_GET(x) ((x) ? x : "")
+#endif
+
+#ifndef EXPORT_API
+#define EXPORT_API extern "C" __attribute__ ((visibility("default")))
+#endif
+<IS_THREAD_ENABLE?>
+#define TIDL_THREAD_ENABLE 1
+</IS_THREAD_ENABLE?>
+
+<RPC_PORT_INTERNAL_APIS>
+
+<ENUMS*>
+typedef enum {
+  <UPPERCASE_PREFIX>_<UPPERCASE_NAME>_METHOD_RESULT_,
+  <UPPERCASE_PREFIX>_<UPPERCASE_NAME>_METHOD_CALLBACK_,
+  <METHOD_ENUM_FIELDS*>
+  <UPPERCASE_PREFIX>_<UPPERCASE_NAME>_METHOD_<UPPERCASE_METHOD_NAME>,
+  </METHOD_ENUM_FIELDS*>
+} <PREFIX>_<NAME>_method_e;
+
+<HAS_DELEGATE?>
+typedef enum {
+  <DELEGATE_ENUM_FIELDS*>
+  <UPPERCASE_PREFIX>_<UPPERCASE_NAME>_DELEGATE_<UPPERCASE_ID> = <CNT>,
+  </DELEGATE_ENUM_FIELDS*>
+} <PREFIX>_<NAME>_delegate_e;
+</HAS_DELEGATE?>
+
+</ENUMS*>
+
+<UNIT_MAP_DEFINITION>
+
+typedef int (*rpc_port_proxy_lem_connect_func)(void *context, bool sync);
+typedef int (*rpc_port_proxy_lem_disconnect_func)(void *context);
+typedef int (*rpc_port_proxy_lem_send_result_func)(void *context, rpc_port_parcel_h parcel);
+typedef int (*rpc_port_proxy_lem_invoke_callback_func)(void *context, rpc_port_parcel_h parcel);
+
+typedef void (*rpc_port_stub_lem_connected_cb)(void *context, const char *sender, const char *instance, bool sync);
+typedef void (*rpc_port_stub_lem_disconnected_cb)(void *context, const char *sender, const char *instance);
+typedef void (*rpc_port_stub_lem_received_cb)(void *context, const char *sender, const char *instance, rpc_port_parcel_h parcel);
+
+typedef struct {
+  rpc_port_stub_lem_connected_cb connected;
+  rpc_port_stub_lem_disconnected_cb disconnected;
+  rpc_port_stub_lem_received_cb received;
+} rpc_port_stub_lem_event_s;
+
+typedef struct {
+  void *context;
+  char *sender;
+  char *instance;
+  bool sync;
+  rpc_port_parcel_h parcel;
+} rpc_port_stub_lem_data_s;
+
+typedef rpc_port_stub_lem_data_s *rpc_port_stub_lem_data_h;
+
+typedef struct {
+  char *port_name;
+  rpc_port_stub_lem_event_s callback;
+  bool listening;
+  bool loaded;
+  rpc_port_proxy_lem_connect_func connect_func;
+  rpc_port_proxy_lem_disconnect_func disconnect_func;
+  rpc_port_proxy_lem_send_result_func send_result_func;
+  rpc_port_proxy_lem_invoke_callback_func invoke_callback_func;
+  GQueue *connected_queue;
+  GQueue *disconnected_queue;
+  GQueue *received_queue;
+  GRecMutex mutex;
+  GMainContext *context;
+} rpc_port_stub_lem_s;
+
+typedef rpc_port_stub_lem_s *rpc_port_stub_lem_h;
+static char *__stub_appid;
+
+<LEM_CONTEXTS*>
+static rpc_port_stub_lem_h __<IFACE_NAME>_context;
+</LEM_CONTEXTS*>
+
+typedef int (*rpc_port_stub_method_handler)(rpc_port_h port, rpc_port_parcel_h parcel, rpc_port_unit_map_h map, void *data);
+
 typedef struct rpc_port_delegate_s {
   rpc_port_parcelable_t parcelable;
   rpc_port_h port;
@@ -44,46 +173,90 @@ typedef struct rpc_port_delegate_s {
 
 typedef rpc_port_delegate_t *rpc_port_delegate_h;
 
+<HAS_DELEGATE?>
 static rpc_port_delegate_h rpc_port_delegate_create();
-)__c_cb";
+</HAS_DELEGATE?>
 
-constexpr const char CB_DELEGATE_BASE[] =
-R"__c_cb(
+<STRUCTURE_DEFINITION>
+<REMOTE_EXCEPTION_DEFINITION>
+
+<INTERFACE_DEFINITIONS*>
+<DELEGATE_DEFINITIONS*>
+typedef struct <PREFIX>_<NAME>_<DELEGATE_NAME>_s {
+  rpc_port_parcelable_t parcelable;
+  rpc_port_h port;
+  int id;
+  int seq_id;
+  bool once;
+  bool valid;
+  char *lem_instance;
+} <PREFIX>_<NAME>_<DELEGATE_NAME>_t;
+
+</DELEGATE_DEFINITIONS*>
+
+<HAS_DELEGATE?>
+static bool __<PREFIX>_<NAME>_exist_callback_port(rpc_port_h callback_port);
+static <PREFIX>_<NAME>_context_h __<PREFIX>_<NAME>_find_context(const char *instance);
+</HAS_DELEGATE?>
+
+typedef struct <PREFIX>_<NAME>_context_s {
+  char *sender;
+  char *instance;
+  rpc_port_h port;
+  rpc_port_h callback_port;
+  void *tag;
+  <PREFIX>_<NAME>_callback_s callback;
+  void *user_data;
+  app_info_h app_info;
+  GHashTable *privileges;
+  void *lem_context;
+#ifdef TIDL_THREAD_ENABLE
+  GThread *thread;
+  GQueue *queue;
+  GMutex mutex;
+  GCond cond;
+  bool done;
+#endif /* TIDL_THREAD_ENABLE */
+} <PREFIX>_<NAME>_context_t;
+
+typedef int (*<PREFIX>_<NAME>_privilege_checker)(<PREFIX>_<NAME>_context_h h, bool *sync);
+
+typedef struct <PREFIX>_<NAME>_s {
+  rpc_port_stub_h stub;
+  <PREFIX>_<NAME>_callback_s callback;
+  void *user_data;
+  GList* contexts;
+  GList* callback_ports;
+  GRecMutex mutex;
+} <PREFIX>_<NAME>_t;
+
+static <PREFIX>_<NAME>_t __<NAME>;
+
+</INTERFACE_DEFINITIONS*>
+<LEM_BASE>
+<PRIVATE_SHARING_LIST_SET>
+<UNIT_MAP_BASE>
+
+<HAS_DELEGATE?>
 static void __rpc_port_delegate_to(rpc_port_parcel_h parcel, void *user_data)
 {
   rpc_port_delegate_h delegate = user_data;
-  rpc_port_unit_map_h map;
 
-  map = rpc_port_unit_map_create();
-  if (map == nullptr) {
-    set_last_result(RPC_PORT_ERROR_OUT_OF_MEMORY);
-    return;
-  }
+  rpc_port_parcel_write_int32(parcel, delegate->id);
+  rpc_port_parcel_write_int32(parcel, delegate->seq_id);
+  rpc_port_parcel_write_bool(parcel, delegate->once);
 
-  rpc_port_unit_map_write_int(map, "id", delegate->id);
-  rpc_port_unit_map_write_int(map, "seq_id", delegate->seq_id);
-  rpc_port_unit_map_write_bool(map, "once", delegate->once);
-  rpc_port_parcel_write(parcel, &map->parcelable, map);
-  rpc_port_unit_map_destroy(map);
   set_last_result(RPC_PORT_ERROR_NONE);
 }
 
 static void __rpc_port_delegate_from(rpc_port_parcel_h parcel, void *user_data)
 {
   rpc_port_delegate_h delegate = user_data;
-  rpc_port_unit_map_h map;
 
-  map = rpc_port_unit_map_create();
-  if (map == nullptr) {
-    set_last_result(RPC_PORT_ERROR_OUT_OF_MEMORY);
-    return;
-  }
+  rpc_port_parcel_read_int32(parcel, &delegate->id);
+  rpc_port_parcel_read_int32(parcel, &delegate->seq_id);
+  rpc_port_parcel_read_bool(parcel, &delegate->once);
 
-  rpc_port_parcel_read(parcel, &map->parcelable, map);
-  rpc_port_unit_map_read_int(map, "id", &delegate->id);
-  rpc_port_unit_map_read_int(map, "seq_id", &delegate->seq_id);
-  rpc_port_unit_map_read_bool(map, "once", &delegate->once);
-  rpc_port_unit_map_destroy(map);
   set_last_result(RPC_PORT_ERROR_NONE);
 }
 
@@ -102,135 +275,128 @@ static rpc_port_delegate_h rpc_port_delegate_create()
 
   return delegate;
 }
-)__c_cb";
+</HAS_DELEGATE?>
 
-constexpr const char CB_THREAD_ENABLE_DEF[] =
-R"__c_cb(
-#define TIDL_THREAD_ENABLE 1
-)__c_cb";
+<STRUCTURE>
+<REMOTE_EXCEPTION_BASE>
 
-constexpr const char CB_INTERFACE_METHOD_HANDLER_TYPE[] =
-R"__c_cb(
-typedef int (*rpc_port_stub_method_handler)(rpc_port_h port, rpc_port_parcel_h parcel, rpc_port_unit_map_h map, void *data);
-)__c_cb";
+<INTERFACES*>
+<INTERFACE>
+</INTERFACES*>
 
-/**
- * <METHOD_ENUMS> The enumeration declarations of methods.
- * <PREFIX> The prefix of the interface.
- * <NAME> The name of the interface.
- */
-constexpr const char CB_INTERFACE_METHOD_ENUM_BASE[] =
-R"__c_cb(
-typedef enum {
-  <METHOD_ENUMS>
-} <PREFIX>_<NAME>_method_e;
-)__c_cb";
+<LEM_APIS*>
+EXPORT_API int rpc_port_stub_<INPUT_FILE>_lem_<IFACE_NAME>_connect(void *context, const char *sender, const char *instance, bool sync)
+{
+  rpc_port_stub_lem_h handle = __<IFACE_NAME>_context;
+  rpc_port_stub_lem_data_h data;
+  GSource *source;
 
-/**
- * <UPPERCASE_PREFIX> The uppercase prefix of the interface.
- * <UPPERCASE_NAME> The uppercase name of the interface.
- * <UPPERCASE_METHOD_NAME> The uppercase method name of the interface.
- */
-constexpr const char CB_INTERFACE_METHOD_ENUM[] =
-R"__c_cb(
-<UPPERCASE_PREFIX>_<UPPERCASE_NAME>_METHOD_<UPPERCASE_METHOD_NAME>,
-)__c_cb";
+  if (!rpc_port_stub_lem_is_listening(handle)) {
+    _E("Server is not ready");
+    return RPC_PORT_ERROR_IO_ERROR;
+  }
 
-/**
- * <DELEGATE_ENUMS> The enumeration declarations of deleagtes.
- * <PREFIX> The prefix of the interface.
- * <NAME> The name of the interface.
- */
-constexpr const char CB_INTERFACE_DELEGATE_ENUM_BASE[] =
-R"__c_cb(
-typedef enum {
-  <DELEGATE_ENUMS>
-} <PREFIX>_<NAME>_delegate_e;
-)__c_cb";
+  if (gettid() == getpid()) {
+    if (handle->callback.connected)
+      handle->callback.connected(context, sender, instance, sync);
 
-/**
- * <UPPERCASE_PREFIX> The uppercase prefix of the interface.
- * <UPPERCASE_NAME> The uppercase name of the interface.
- * <UPPERCASE_DELEGATE_NAME> The uppercase delegate name of the interface.
- * <NUMBER> The number of the delegate.
- */
-constexpr const char CB_INTERFACE_DELEGATE_ENUM[] =
-R"__c_cb(
-<UPPERCASE_PREFIX>_<UPPERCASE_NAME>_DELEGATE_<UPPERCASE_DELEGATE_NAME> = <NUMBER>,
-)__c_cb";
+    return RPC_PORT_ERROR_NONE;
+  }
 
-/**
- * <PREFIX> The prefix of the interface.
- * <NAME> The name of the interface.
- */
-constexpr const char CB_INTERFACE_BASE_DEF[] =
-R"__c_cb(
-typedef struct <PREFIX>_<NAME>_s {
-  rpc_port_stub_h stub;
-  <PREFIX>_<NAME>_callback_s callback;
-  void *user_data;
-  GList* contexts;
-  GList* callback_ports;
-  GRecMutex mutex;
-} <PREFIX>_<NAME>_t;
+  data = rpc_port_stub_lem_data_create(context, sender, instance, sync);
+  if (data == nullptr) {
+    _E("Ouf of memory");
+    return RPC_PORT_ERROR_OUT_OF_MEMORY;
+  }
 
-static <PREFIX>_<NAME>_t __<NAME>;
-)__c_cb";
+  rpc_port_stub_lem_connected_data_push(handle, data);
+  source = g_idle_source_new();
+  if (source == nullptr) {
+    _E("Failed to create idle source");
+    return RPC_PORT_ERROR_OUT_OF_MEMORY;
+  }
 
-/**
- * <PREFIX> The prefix of the interface.
- * <NAME> The name of the interface.
- */
-constexpr const char CB_INTERFACE_CONTEXT_DEF[] =
-R"__c_cb(
-typedef struct <PREFIX>_<NAME>_context_s {
-  char *sender;
-  char *instance;
-  rpc_port_h port;
-  rpc_port_h callback_port;
-  void *tag;
-  <PREFIX>_<NAME>_callback_s callback;
-  void *user_data;
-  app_info_h app_info;
-  GHashTable *privileges;
-  void *lem_context;
-#ifdef TIDL_THREAD_ENABLE
-  GThread *thread;
-  GQueue *queue;
-  GMutex mutex;
-  GCond cond;
-  bool done;
-#endif /* TIDL_THREAD_ENABLE */
-} <PREFIX>_<NAME>_context_t;
+  g_source_set_callback(source, (GSourceFunc)rpc_port_stub_lem_on_connected, handle, nullptr);
+  g_source_attach(source, handle->context);
+  g_source_unref(source);
+  return RPC_PORT_ERROR_NONE;
+}
 
-typedef int (*<PREFIX>_<NAME>_privilege_checker)(<PREFIX>_<NAME>_context_h h, bool *sync);
-)__c_cb";
+EXPORT_API int rpc_port_stub_<INPUT_FILE>_lem_<IFACE_NAME>_disconnect(void *context, const char *sender, const char *instance)
+{
+  rpc_port_stub_lem_h handle = __<IFACE_NAME>_context;
+  rpc_port_stub_lem_data_h data;
+  GSource *source;
 
-/**
- *
- */
-constexpr const char CB_INTERFACE_CALLBACK_PORT_CHECK_DEF[] =
-R"__c_cb(
-static bool __<PREFIX>_<NAME>_exist_callback_port(rpc_port_h callback_port);
-static <PREFIX>_<NAME>_context_h __<PREFIX>_<NAME>_find_context(const char *instance);
-)__c_cb";
+  if (!rpc_port_stub_lem_is_listening(handle)) {
+    _E("Server is not ready");
+    return RPC_PORT_ERROR_IO_ERROR;
+  }
+
+  if (gettid() == getpid()) {
+    if (handle->callback.disconnected)
+      handle->callback.disconnected(context, sender, instance);
+
+    return RPC_PORT_ERROR_NONE;
+  }
+
+  data = rpc_port_stub_lem_data_create(context, sender, instance, false);
+  if (data == nullptr) {
+    _E("Ouf of memory");
+    return RPC_PORT_ERROR_OUT_OF_MEMORY;
+  }
+
+  rpc_port_stub_lem_disconnected_data_push(handle, data);
+  source = g_idle_source_new();
+  if (source == nullptr) {
+    _E("Failed to create idle source");
+    return RPC_PORT_ERROR_OUT_OF_MEMORY;
+  }
+
+  g_source_set_callback(source, (GSourceFunc)rpc_port_stub_lem_on_disconnected, handle, nullptr);
+  g_source_attach(source, handle->context);
+  g_source_unref(source);
+  return RPC_PORT_ERROR_NONE;
+}
+
+EXPORT_API int rpc_port_stub_<INPUT_FILE>_lem_<IFACE_NAME>_send(void *context, const char* sender, const char *instance, rpc_port_parcel_h parcel)
+{
+  rpc_port_stub_lem_h handle = __<IFACE_NAME>_context;
+  rpc_port_stub_lem_data_h data;
+  GSource *source;
+
+  if (!rpc_port_stub_lem_is_listening(handle)) {
+    _E("Server is not ready");
+    return RPC_PORT_ERROR_IO_ERROR;
+  }
+
+  if (gettid() == getpid()) {
+    if (handle->callback.received)
+      handle->callback.received(context, sender, instance, parcel);
+
+    return RPC_PORT_ERROR_NONE;
+  }
+
+  data = rpc_port_stub_lem_data_create_with_parcel(context, sender, instance, parcel);
+  if (data == nullptr) {
+    _E("Ouf of memory");
+    return RPC_PORT_ERROR_OUT_OF_MEMORY;
+  }
+
+  rpc_port_stub_lem_received_data_push(handle, data);
+  source = g_idle_source_new();
+  if (source == nullptr) {
+    _E("Failed to create idle source");
+    return RPC_PORT_ERROR_OUT_OF_MEMORY;
+  }
+
+  g_source_set_callback(source, (GSourceFunc)rpc_port_stub_lem_on_received, handle, nullptr);
+  g_source_attach(source, handle->context);
+  g_source_unref(source);
+  return RPC_PORT_ERROR_NONE;
+}
+</LEM_APIS*>
 
-/**
- * <PREFIX> The prefix of the interface.
- * <NAME> The name of the interface.
- * <DELEGATE_NAME> The name of the delegate of the interface.
- */
-constexpr const char CB_INTERFACE_DELEGATE_DEF[] =
-R"__c_cb(
-typedef struct <PREFIX>_<NAME>_<DELEGATE_NAME>_s {
-  rpc_port_parcelable_t parcelable;
-  rpc_port_h port;
-  int id;
-  int seq_id;
-  bool once;
-  bool valid;
-  char *lem_instance;
-} <PREFIX>_<NAME>_<DELEGATE_NAME>_t;
 )__c_cb";
 
 /**
@@ -248,6 +414,7 @@ static void __<PREFIX>_<NAME>_throw_remote_exception(rpc_port_h port, rpc_port_p
   rpc_port_parcel_header_h header = nullptr;
   rpc_port_unit_map_h map;
   int seq_num = 0;
+  int method = <UPPERCASE_PREFIX>_<UPPERCASE_NAME>_METHOD_RESULT_;
 
   map = rpc_port_unit_map_create();
   if (map == nullptr) {
@@ -255,12 +422,12 @@ static void __<PREFIX>_<NAME>_throw_remote_exception(rpc_port_h port, rpc_port_p
     return;
   }
 
-  rpc_port_unit_map_write_int(map, "[METHOD]", <UPPERCASE_PREFIX>_<UPPERCASE_NAME>_METHOD_RESULT_);
+  rpc_port_unit_map_write_int(map, <HASH_METHOD> /*[METHOD]*/, &method);
 
   <PREFIX>_remote_exception_create(&remote_exception);
   <PREFIX>_remote_exception_set_cause(remote_exception, cause);
   <PREFIX>_remote_exception_set_message(remote_exception, message);
-  rpc_port_unit_map_write_remote_exception(map, "[REMOTE_EXCEPTION]", remote_exception);
+  rpc_port_unit_map_write_remote_exception(map, <HASH_REMOTE_EXCEPTION> /*[REMOTE_EXCEPTION]*/, remote_exception);
   <PREFIX>_remote_exception_destroy(remote_exception);
 
   if (rpc_port_parcel_create(&result_parcel) != RPC_PORT_ERROR_NONE) {
@@ -301,7 +468,7 @@ static int __<PREFIX>_<NAME>_context_handle_request(<PREFIX>_<NAME>_context_h h,
 
   rpc_port_parcel_read(parcel, &map->parcelable, map);
 
-  rpc_port_unit_map_read_int(map, "[METHOD]", &cmd);
+  rpc_port_unit_map_read_int(map, <HASH_METHOD> /*[METHOD]*/, &cmd);
 
   if (cmd > 1 && cmd < ARRAY_SIZE(__<NAME>_method_table)) {
     if (h->lem_context == nullptr && h->app_info && __<NAME>_privilege_checkers[cmd]) {
@@ -702,7 +869,6 @@ R"__c_cb(
 static void __<PREFIX>_<NAME>_<DELEGATE_NAME>_to(rpc_port_parcel_h parcel, void *user_data)
 {
  <PREFIX>_<NAME>_<DELEGATE_NAME>_h h = user_data;
-  rpc_port_unit_map_h map;
 
   if (parcel == nullptr || h == nullptr) {
     _E("Invalid parameter");
@@ -710,19 +876,9 @@ static void __<PREFIX>_<NAME>_<DELEGATE_NAME>_to(rpc_port_parcel_h parcel, void
     return;
   }
 
-  map = rpc_port_unit_map_create();
-  if (map == nullptr) {
-    _E("Failed to create unit map");
-    set_last_result(RPC_PORT_ERROR_OUT_OF_MEMORY);
-    return;
-  }
-
-  rpc_port_unit_map_write_int(map, "id", h->id);
-  rpc_port_unit_map_write_int(map, "seq_id", h->seq_id);
-  rpc_port_unit_map_write_bool(map, "once", h->once);
-
-  rpc_port_parcel_write(parcel, &map->parcelable, map);
-  rpc_port_unit_map_destroy(map);
+  rpc_port_parcel_write_int32(parcel, h->id);
+  rpc_port_parcel_write_int32(parcel, h->seq_id);
+  rpc_port_parcel_write_bool(parcel, h->once);
 
   _I("id(%d), seq_id(%d), once(%s)", h->id, h->seq_id, h->once ? "true" : "false");
   set_last_result(RPC_PORT_ERROR_NONE);
@@ -731,28 +887,16 @@ static void __<PREFIX>_<NAME>_<DELEGATE_NAME>_to(rpc_port_parcel_h parcel, void
 static void __<PREFIX>_<NAME>_<DELEGATE_NAME>_from(rpc_port_parcel_h parcel, void *user_data)
 {
   <PREFIX>_<NAME>_<DELEGATE_NAME>_h h = user_data;
-  rpc_port_unit_map_h map;
-
-  if (parcel == nullptr || h == nullptr) {
-    _E("Invalid parameter");
-    set_last_result(RPC_PORT_ERROR_INVALID_PARAMETER);
-    return;
-  }
-
-  map = rpc_port_unit_map_create();
-  if (map == nullptr) {
-    _E("Failed to create unit map");
-    set_last_result(RPC_PORT_ERROR_OUT_OF_MEMORY);
+
+  if (parcel == nullptr || h == nullptr) {
+    _E("Invalid parameter");
+    set_last_result(RPC_PORT_ERROR_INVALID_PARAMETER);
     return;
   }
 
-  rpc_port_parcel_read(parcel, &map->parcelable, map);
-
-  rpc_port_unit_map_read_int(map, "id", &h->id);
-  rpc_port_unit_map_read_int(map, "seq_id", &h->seq_id);
-  rpc_port_unit_map_read_bool(map, "once", &h->once);
-
-  rpc_port_unit_map_destroy(map);
+  rpc_port_parcel_read_int32(parcel, &h->id);
+  rpc_port_parcel_read_int32(parcel, &h->seq_id);
+  rpc_port_parcel_read_bool(parcel, &h->once);
 
   _I("id(%d), seq_id(%d), once(%s)", h->id, h->seq_id, h->once ? "true" : "false");
   set_last_result(RPC_PORT_ERROR_NONE);
@@ -806,7 +950,7 @@ int <PREFIX>_<NAME>_<DELEGATE_NAME>_destroy(<PREFIX>_<NAME>_<DELEGATE_NAME>_h h)
 
 int <PREFIX>_<NAME>_<DELEGATE_NAME>_clone(<PREFIX>_<NAME>_<DELEGATE_NAME>_h h, <PREFIX>_<NAME>_<DELEGATE_NAME>_h *clone)
 {
-  rpc_port_unit_map_h map;
+  <PREFIX>_<NAME>_<DELEGATE_NAME>_h handle;
   int ret;
 
   if (h == nullptr || clone == nullptr) {
@@ -814,34 +958,21 @@ int <PREFIX>_<NAME>_<DELEGATE_NAME>_clone(<PREFIX>_<NAME>_<DELEGATE_NAME>_h h, <
     return RPC_PORT_ERROR_INVALID_PARAMETER;
   }
 
-  map = rpc_port_unit_map_create();
-  if (map == nullptr) {
-    _E("Failed to create unit map");
-    return RPC_PORT_ERROR_OUT_OF_MEMORY;
-  }
-
-  ret = rpc_port_unit_map_write_<NAME>_<DELEGATE_NAME>(map, "clone", h);
+  ret = <PREFIX>_<NAME>_<DELEGATE_NAME>_create(&handle);
   if (ret != RPC_PORT_ERROR_NONE) {
-    _E("Failed to write <DELEGATE_NAME>. error(%d)", ret);
-    rpc_port_unit_map_destroy(map);
+    _E("Failed to create handle. error(%d)", ret);
     return ret;
   }
 
-  rpc_port_unit_map_read_<NAME>_<DELEGATE_NAME>(map, "clone", clone);
-  rpc_port_unit_map_destroy(map);
-
-  (*clone)->port = h->port;
-
-  if (h->lem_instance) {
-    (*clone)->lem_instance = strdup(h->lem_instance);
-    if ((*clone)->lem_instance == nullptr) {
-      _E("Out of memory");
-      <PREFIX>_<NAME>_<DELEGATE_NAME>_destroy(*clone);
-      return RPC_PORT_ERROR_OUT_OF_MEMORY;
-    }
-  }
+  handle->port = h->port;
+  handle->id = h->id;
+  handle->seq_id = h->seq_id;
+  handle->once = h->once;
+  handle->valid = h->valid;
+  handle->lem_instance = h->lem_instance ? strdup(h->lem_instance) : nullptr;
 
-  return ret;
+  *clone = handle;
+  return RPC_PORT_ERROR_NONE;
 }
 
 int <PREFIX>_<NAME>_<DELEGATE_NAME>_get_id(<PREFIX>_<NAME>_<DELEGATE_NAME>_h h, int *id)
@@ -939,6 +1070,7 @@ int <PREFIX>_<NAME>_<DELEGATE_NAME>_invoke(<PREFIX>_<NAME>_<DELEGATE_NAME>_h h<D
   int ret_;
   rpc_port_unit_map_h map_;
   <PREFIX>_<NAME>_context_h context = nullptr;
+  int method_ = <UPPERCASE_PREFIX>_<UPPERCASE_NAME>_METHOD_CALLBACK_;
 
   if (h == nullptr <DELEGATE_PARAMS_CHECK>) {
     _E("Invalid parameter");
@@ -982,12 +1114,11 @@ int <PREFIX>_<NAME>_<DELEGATE_NAME>_invoke(<PREFIX>_<NAME>_<DELEGATE_NAME>_h h<D
     return ret_;
   }
 
-  rpc_port_unit_map_write_int(map_, "[METHOD]", <UPPERCASE_PREFIX>_<UPPERCASE_NAME>_METHOD_CALLBACK_);
-
-  rpc_port_unit_map_write_delegate(map_, "delegate", (rpc_port_delegate_h)h);
-
+  rpc_port_unit_map_write_int(map_, <HASH_METHOD> /*[METHOD]*/, &method_);
+  rpc_port_unit_map_write_delegate(map_, <HASH_DELEGATE> /*delegate*/, (rpc_port_delegate_h)h);
   <DELEGATE_UNIT_MAP_WRITE>
   rpc_port_parcel_write(parcel_, &map_->parcelable, map_);
+
   if (context && context->lem_context) {
     rpc_port_stub_lem_invoke_callback(__<NAME>_context, context->lem_context, parcel_);
     ret_ = RPC_PORT_ERROR_NONE;
@@ -1009,7 +1140,7 @@ int <PREFIX>_<NAME>_<DELEGATE_NAME>_invoke(<PREFIX>_<NAME>_<DELEGATE_NAME>_h h<D
  */
 constexpr const char CB_INTERFACE_METHOD_DELEGATE_UNIT_MAP_WRITE[] =
 R"__c_cb(
-rpc_port_unit_map_write_delegate(map_, "<ARG_NAME>", (rpc_port_delegate_h)<ARG>);
+rpc_port_unit_map_write_delegate(map_, <HASH_ARG_NAME> /*<ARG_NAME>*/, (rpc_port_delegate_h)<ARG>);
 )__c_cb";
 
 
@@ -1019,7 +1150,7 @@ rpc_port_unit_map_write_delegate(map_, "<ARG_NAME>", (rpc_port_delegate_h)<ARG>)
  */
 constexpr const char CB_INTERFACE_METHOD_ENUM_UNIT_MAP_WRITE[] =
 R"__c_cb(
-rpc_port_unit_map_write_int(map_, "<ARG_NAME>", (int)<ARG>);
+rpc_port_unit_map_write_int(map_, <HASH_ARG_NAME> /*<ARG_NAME>*/, (int*)&<ARG>);
 )__c_cb";
 
 
@@ -1029,7 +1160,7 @@ rpc_port_unit_map_write_int(map_, "<ARG_NAME>", (int)<ARG>);
  */
 constexpr const char CB_INTERFACE_METHOD_USER_DEFINED_UNIT_MAP_WRITE[] =
 R"__c_cb(
-rpc_port_unit_map_write_<TYPE_NAME>(map_, "<ARG_NAME>", <ARG>);
+rpc_port_unit_map_write_<TYPE_NAME>(map_, <HASH_ARG_NAME> /*<ARG_NAME>*/, <ARG>);
 )__c_cb";
 
 /**
@@ -1037,7 +1168,7 @@ rpc_port_unit_map_write_<TYPE_NAME>(map_, "<ARG_NAME>", <ARG>);
  */
 constexpr const char CB_INTERFACE_METHOD_BUNDLE_UNIT_MAP_WRITE[] =
 R"__c_cb(
-rpc_port_unit_map_write_bundle(map_, "<ARG_NAME>", <ARG>);
+rpc_port_unit_map_write_bundle(map_, <HASH_ARG_NAME> /*<ARG_NAME>*/, <ARG>);
 )__c_cb";
 
 /**
@@ -1045,7 +1176,12 @@ rpc_port_unit_map_write_bundle(map_, "<ARG_NAME>", <ARG>);
  */
 constexpr const char CB_INTERFACE_METHOD_STRING_UNIT_MAP_WRITE[] =
 R"__c_cb(
-rpc_port_unit_map_write_string(map_, "<ARG_NAME>", <ARG>);
+rpc_port_unit_map_write_string(map_, <HASH_ARG_NAME> /*<ARG_NAME>*/, <ARG>);
+)__c_cb";
+
+constexpr const char CB_INTERFACE_METHOD_FILE_UNIT_MAP_WRITE[] =
+R"__c_cb(
+rpc_port_unit_map_write_file(map_, <HASH_ARG_NAME> /*<ARG_NAME>*/, <ARG>);
 )__c_cb";
 
 /**
@@ -1054,7 +1190,7 @@ rpc_port_unit_map_write_string(map_, "<ARG_NAME>", <ARG>);
  */
 constexpr const char CB_INTERFACE_METHOD_BASE_UNIT_MAP_WRITE[] =
 R"__c_cb(
-rpc_port_unit_map_write_<TYPE_NAME>(map_, "<ARG_NAME>", <ARG>);
+rpc_port_unit_map_write_<TYPE_NAME>(map_, <HASH_ARG_NAME> /*<ARG_NAME>*/, &<ARG>);
 )__c_cb";
 
 /**
@@ -1063,7 +1199,7 @@ rpc_port_unit_map_write_<TYPE_NAME>(map_, "<ARG_NAME>", <ARG>);
  */
 constexpr const char CB_INTERFACE_METHOD_EMUM_UNIT_MAP_READ[] =
 R"__c_cb(
-rpc_port_unit_map_read_int(map, "<ARG_NAME>", (int *)&<ARG>);
+rpc_port_unit_map_read_int(map, <HASH_ARG_NAME> /*<ARG_NAME>*/, (int *)&<ARG>);
 )__c_cb";
 
 /**
@@ -1073,7 +1209,7 @@ rpc_port_unit_map_read_int(map, "<ARG_NAME>", (int *)&<ARG>);
  */
 constexpr const char CB_INTERFACE_METHOD_USER_DEFINED_UNIT_MAP_READ[] =
 R"__c_cb(
-rpc_port_unit_map_read_<TYPE_NAME>(map, "<ARG_NAME>", &<ARG>);
+rpc_port_unit_map_read_<TYPE_NAME>(map, <HASH_ARG_NAME> /*<ARG_NAME>*/, &<ARG>);
 )__c_cb";
 
 /**
@@ -1082,7 +1218,7 @@ rpc_port_unit_map_read_<TYPE_NAME>(map, "<ARG_NAME>", &<ARG>);
  */
 constexpr const char CB_INTERFACE_METHOD_BUNDLE_UNIT_MAP_READ[] =
 R"__c_cb(
-rpc_port_unit_map_read_bundle(map, "<ARG_NAME>", &<ARG>);
+rpc_port_unit_map_read_bundle(map, <HASH_ARG_NAME> /*<ARG_NAME>*/, &<ARG>);
 )__c_cb";
 
 /**
@@ -1091,7 +1227,12 @@ rpc_port_unit_map_read_bundle(map, "<ARG_NAME>", &<ARG>);
  */
 constexpr const char CB_INTERFACE_METHOD_STRING_UNIT_MAP_READ[] =
 R"__c_cb(
-rpc_port_unit_map_read_string(map, "<ARG_NAME>", &<ARG>);
+rpc_port_unit_map_read_string(map, <HASH_ARG_NAME> /*<ARG_NAME>*/, &<ARG>);
+)__c_cb";
+
+constexpr const char CB_INTERFACE_METHOD_FILE_UNIT_MAP_READ[] =
+R"__c_cb(
+rpc_port_unit_map_read_file(map, <HASH_ARG_NAME> /*<ARG_NAME>*/, &<ARG>);
 )__c_cb";
 
 /*
@@ -1099,7 +1240,7 @@ rpc_port_unit_map_read_string(map, "<ARG_NAME>", &<ARG>);
  */
 constexpr const char CB_INTERFACE_METHOD_DELEGATE_UNIT_MAP_READ[] =
 R"__c_cb(
-rpc_port_unit_map_read_delegate(map, "<ARG>", (rpc_port_delegate_h *)&<ARG>);
+rpc_port_unit_map_read_delegate(map, <HASH_ARG> /*<ARG>*/, (rpc_port_delegate_h *)&<ARG>);
 
 if (context_->lem_context)
   <PREFIX>_<TYPE_NAME>_set_lem_instance(<ARG>, context_->instance);
@@ -1115,7 +1256,7 @@ else
  */
 constexpr const char CB_INTERFACE_METHOD_BASE_UNIT_MAP_READ[] =
 R"__c_cb(
-rpc_port_unit_map_read_<TYPE_NAME>(map, "<ARG_NAME>", &<ARG>);
+rpc_port_unit_map_read_<TYPE_NAME>(map, <HASH_ARG_NAME> /*<ARG_NAME>*/, &<ARG>);
 )__c_cb";
 
 
@@ -1162,83 +1303,6 @@ out:
 }
 )__c_cb";
 
-/**
- * <ARG> The argument.
- * <PREFIX> The prefix of the interface.
- * <NAME> The name of the interface
- */
-constexpr const char CB_INTERFACE_METHOD_DELEGATE_PARCEL_READ[] =
-R"__c_cb(
-ret_ = <PREFIX>_<NAME>_create(&<ARG>);
-if (ret_ != RPC_PORT_ERROR_NONE) {
-  _E("Failed to create handle. error(%d)", ret_);
-  goto out;
-}
-
-<PREFIX>_<NAME>_set_port(<ARG>, callback_port_);
-rpc_port_parcel_read(parcel, &<ARG>->parcelable, <ARG>);
-ret_ = get_last_result();
-if (ret_ != RPC_PORT_ERROR_NONE) {
-  _E("Failed to read data. error(%d)", ret_);
-  goto out;
-}
-)__c_cb";
-
-/**
- * <ARG> The name of the value.
- * <PREFIX> The prefix of the structure.
- * <NAME> The name of the structure.
- */
-constexpr const char CB_INTERFACE_METHOD_USER_DEFINED_PARCEL_READ[] =
-R"__c_cb(
-ret_ = <PREFIX>_<NAME>_create(&<ARG>);
-if (ret_ != RPC_PORT_ERROR_NONE) {
-  _E("Failed to create handle. error(%d)", ret_);
-  goto out;
-}
-
-rpc_port_parcel_read(parcel, &<ARG>->parcelable, <ARG>);
-ret_ = get_last_result();
-if (ret_ != RPC_PORT_ERROR_NONE) {
-  _E("Failed to read data. error(%d)", ret_);
-  goto out;
-}
-)__c_cb";
-
-/**
- * <ARG> The name of the value.
- */
-constexpr const char CB_INTERFACE_METHOD_BUNDLE_PARCEL_READ[] =
-R"__c_cb(
-rpc_port_parcel_read_bundle(parcel, &<ARG>);
-if (<ARG> == nullptr) {
-  _E("Failed to read data");
-  ret_ = RPC_PORT_ERROR_OUT_OF_MEMORY;
-  goto out;
-}
-)__c_cb";
-
-/**
- * <ARG> The name of the value.
- */
-constexpr const char CB_INTERFACE_METHOD_STRING_PARCEL_READ[] =
-R"__c_cb(
-rpc_port_parcel_read_string(parcel, &<ARG>);
-if (<ARG> == nullptr) {
-  _E("Failed to read data");
-  ret_ = RPC_PORT_ERROR_OUT_OF_MEMORY;
-  goto out;
-}
-)__c_cb";
-
-/**
- * <PARCEL_TYPE> The type of the parcel.
- * <ARG> The name of the value.
- */
-constexpr const char CB_INTERFACE_METHOD_BASE_PARCEL_READ[] =
-R"__c_cb(
-rpc_port_parcel_read_<PARCEL_TYPE>(parcel, &<ARG>);
-)__c_cb";
 
 /**
  * <PREFIX> The prefix of the interface.
@@ -1264,6 +1328,7 @@ if (context_->callback.<METHOD_NAME>)
  */
 constexpr const char CB_INTERFACE_METHOD_PARCEL_WRITE_PRE[] =
 R"__c_cb(
+int method_ = <UPPERCASE_PREFIX>_<UPPERCASE_NAME>_METHOD_RESULT_;
 ret_ = rpc_port_parcel_create(&parcel_);
 if (ret_ != RPC_PORT_ERROR_NONE) {
   _E("Failed to create parcel handle. error(%d)", ret_);
@@ -1282,7 +1347,7 @@ if (map_ == nullptr) {
   goto out;
 }
 
-rpc_port_unit_map_write_int(map_, "[METHOD]",  <UPPERCASE_PREFIX>_<UPPERCASE_NAME>_METHOD_RESULT_);
+rpc_port_unit_map_write_int(map_, <HASH_METHOD> /*[METHOD]*/, &method_);
 )__c_cb";
 
 /**
@@ -1292,7 +1357,7 @@ rpc_port_unit_map_write_int(map_, "[METHOD]",  <UPPERCASE_PREFIX>_<UPPERCASE_NAM
 constexpr const char CB_INTERFACE_METHOD_PARCEL_WRITE_POST[] =
 R"__c_cb(
 if (__<PREFIX>_remote_exception != nullptr)
-  rpc_port_unit_map_write_remote_exception(map_, "[REMOTE_EXCEPTION]", __<PREFIX>_remote_exception);
+  rpc_port_unit_map_write_remote_exception(map_, <HASH_REMOTE_EXCEPTION> /*[REMOTE_EXCEPTION]*/, __<PREFIX>_remote_exception);
 
 rpc_port_parcel_write(parcel_, &map_->parcelable, map_);
 rpc_port_unit_map_destroy(map_);
@@ -1516,6 +1581,8 @@ int <PREFIX>_<NAME>_register(<PREFIX>_<NAME>_callback_s *callback, void *user_da
     return RPC_PORT_ERROR_NONE;
   }
 
+  rpc_port_internal_init();
+
   g_rec_mutex_init(&__<NAME>.mutex);
   __<NAME>.callback = *callback;
   __<NAME>.user_data = user_data;
@@ -1762,66 +1829,6 @@ R"__c_cb(
 [<ENUM_VALUE>] = __<PREFIX>_<NAME>_method_<METHOD_NAME>_privilege_checker,
 )__c_cb";
 
-/**
- * <LEM_CONTEXT> The context of the local execution of the interface.
- */
-constexpr const char CB_LEM_BASE_DEF[] =
-R"__c_cb(
-typedef int (*rpc_port_proxy_lem_connect_func)(void *context, bool sync);
-typedef int (*rpc_port_proxy_lem_disconnect_func)(void *context);
-typedef int (*rpc_port_proxy_lem_send_result_func)(void *context, rpc_port_parcel_h parcel);
-typedef int (*rpc_port_proxy_lem_invoke_callback_func)(void *context, rpc_port_parcel_h parcel);
-
-typedef void (*rpc_port_stub_lem_connected_cb)(void *context, const char *sender, const char *instance, bool sync);
-typedef void (*rpc_port_stub_lem_disconnected_cb)(void *context, const char *sender, const char *instance);
-typedef void (*rpc_port_stub_lem_received_cb)(void *context, const char *sender, const char *instance, rpc_port_parcel_h parcel);
-
-typedef struct {
-  rpc_port_stub_lem_connected_cb connected;
-  rpc_port_stub_lem_disconnected_cb disconnected;
-  rpc_port_stub_lem_received_cb received;
-} rpc_port_stub_lem_event_s;
-
-typedef struct {
-  void *context;
-  char *sender;
-  char *instance;
-  bool sync;
-  rpc_port_parcel_h parcel;
-} rpc_port_stub_lem_data_s;
-
-typedef rpc_port_stub_lem_data_s *rpc_port_stub_lem_data_h;
-
-typedef struct {
-  char *port_name;
-  rpc_port_stub_lem_event_s callback;
-  bool listening;
-  bool loaded;
-  rpc_port_proxy_lem_connect_func connect_func;
-  rpc_port_proxy_lem_disconnect_func disconnect_func;
-  rpc_port_proxy_lem_send_result_func send_result_func;
-  rpc_port_proxy_lem_invoke_callback_func invoke_callback_func;
-  GQueue *connected_queue;
-  GQueue *disconnected_queue;
-  GQueue *received_queue;
-  GRecMutex mutex;
-  GMainContext *context;
-} rpc_port_stub_lem_s;
-
-typedef rpc_port_stub_lem_s *rpc_port_stub_lem_h;
-static char *__stub_appid;
-
-<LEM_CONTEXT>
-)__c_cb";
-
-/**
- * <IFACE_NAME> The interface name.
- */
-constexpr const char CB_LEM_CONTEXT[] =
-R"__c_cb(
-static rpc_port_stub_lem_h __<IFACE_NAME>_context;
-)__c_cb";
-
 /**
  * <INPUT_FILE> The input file name.
  */
@@ -2083,7 +2090,7 @@ static void rpc_port_stub_lem_send_result(rpc_port_stub_lem_h handle, void *cont
     handle->send_result_func(context, parcel);
 }
 
-#ifdef TIDL_USE_DELEGATE
+<HAS_DELEGATE?>
 static void rpc_port_stub_lem_invoke_callback(rpc_port_stub_lem_h handle, void *context, rpc_port_parcel_h parcel)
 {
   if (handle == nullptr || context == nullptr || parcel == nullptr)
@@ -2092,7 +2099,7 @@ static void rpc_port_stub_lem_invoke_callback(rpc_port_stub_lem_h handle, void *
   if (handle->invoke_callback_func)
     handle->invoke_callback_func(context, parcel);
 }
-#endif
+</HAS_DELEGATE?>
 
 static void rpc_port_stub_lem_set_listening(rpc_port_stub_lem_h handle, bool listening)
 {
@@ -2235,128 +2242,6 @@ static gboolean rpc_port_stub_lem_on_received(gpointer user_data)
 }
 )__c_cb";
 
-/**
- * <INPUT_FILE> The input file name.
- * <IFACE_NAME> The interface name.
- */
-constexpr const char CB_LEM_API[] =
-R"__c_cb(
-EXPORT_API int rpc_port_stub_<INPUT_FILE>_lem_<IFACE_NAME>_connect(void *context, const char *sender, const char *instance, bool sync)
-{
-  rpc_port_stub_lem_h handle = __<IFACE_NAME>_context;
-  rpc_port_stub_lem_data_h data;
-  GSource *source;
-
-  if (!rpc_port_stub_lem_is_listening(handle)) {
-    _E("Server is not ready");
-    return RPC_PORT_ERROR_IO_ERROR;
-  }
-
-  if (gettid() == getpid()) {
-    if (handle->callback.connected)
-      handle->callback.connected(context, sender, instance, sync);
-
-    return RPC_PORT_ERROR_NONE;
-  }
-
-  data = rpc_port_stub_lem_data_create(context, sender, instance, sync);
-  if (data == nullptr) {
-    _E("Ouf of memory");
-    return RPC_PORT_ERROR_OUT_OF_MEMORY;
-  }
-
-  rpc_port_stub_lem_connected_data_push(handle, data);
-  source = g_idle_source_new();
-  if (source == nullptr) {
-    _E("Failed to create idle source");
-    return RPC_PORT_ERROR_OUT_OF_MEMORY;
-  }
-
-  g_source_set_callback(source, (GSourceFunc)rpc_port_stub_lem_on_connected, handle, nullptr);
-  g_source_attach(source, handle->context);
-  g_source_unref(source);
-  return RPC_PORT_ERROR_NONE;
-}
-
-EXPORT_API int rpc_port_stub_<INPUT_FILE>_lem_<IFACE_NAME>_disconnect(void *context, const char *sender, const char *instance)
-{
-  rpc_port_stub_lem_h handle = __<IFACE_NAME>_context;
-  rpc_port_stub_lem_data_h data;
-  GSource *source;
-
-  if (!rpc_port_stub_lem_is_listening(handle)) {
-    _E("Server is not ready");
-    return RPC_PORT_ERROR_IO_ERROR;
-  }
-
-  if (gettid() == getpid()) {
-    if (handle->callback.disconnected)
-      handle->callback.disconnected(context, sender, instance);
-
-    return RPC_PORT_ERROR_NONE;
-  }
-
-  data = rpc_port_stub_lem_data_create(context, sender, instance, false);
-  if (data == nullptr) {
-    _E("Ouf of memory");
-    return RPC_PORT_ERROR_OUT_OF_MEMORY;
-  }
-
-  rpc_port_stub_lem_disconnected_data_push(handle, data);
-  source = g_idle_source_new();
-  if (source == nullptr) {
-    _E("Failed to create idle source");
-    return RPC_PORT_ERROR_OUT_OF_MEMORY;
-  }
-
-  g_source_set_callback(source, (GSourceFunc)rpc_port_stub_lem_on_disconnected, handle, nullptr);
-  g_source_attach(source, handle->context);
-  g_source_unref(source);
-  return RPC_PORT_ERROR_NONE;
-}
-
-EXPORT_API int rpc_port_stub_<INPUT_FILE>_lem_<IFACE_NAME>_send(void *context, const char* sender, const char *instance, rpc_port_parcel_h parcel)
-{
-  rpc_port_stub_lem_h handle = __<IFACE_NAME>_context;
-  rpc_port_stub_lem_data_h data;
-  GSource *source;
-
-  if (!rpc_port_stub_lem_is_listening(handle)) {
-    _E("Server is not ready");
-    return RPC_PORT_ERROR_IO_ERROR;
-  }
-
-  if (gettid() == getpid()) {
-    if (handle->callback.received)
-      handle->callback.received(context, sender, instance, parcel);
-
-    return RPC_PORT_ERROR_NONE;
-  }
-
-  data = rpc_port_stub_lem_data_create_with_parcel(context, sender, instance, parcel);
-  if (data == nullptr) {
-    _E("Ouf of memory");
-    return RPC_PORT_ERROR_OUT_OF_MEMORY;
-  }
-
-  rpc_port_stub_lem_received_data_push(handle, data);
-  source = g_idle_source_new();
-  if (source == nullptr) {
-    _E("Failed to create idle source");
-    return RPC_PORT_ERROR_OUT_OF_MEMORY;
-  }
-
-  g_source_set_callback(source, (GSourceFunc)rpc_port_stub_lem_on_received, handle, nullptr);
-  g_source_attach(source, handle->context);
-  g_source_unref(source);
-  return RPC_PORT_ERROR_NONE;
-}
-)__c_cb";
-
-constexpr const char CB_INTERNAL_HEADER_INCLUSION[] =
-R"__c_cb(
-#include <rpc-port-internal.h>
-)__c_cb";
 
 /**
  * <PREFIX> The prefix of the interface.