Skip to content

Commit 336b70e

Browse files
committed
Support binary with exact len
IPv6 are expressed as binary with exact len. This patch adds support for that. Signed-off-by: Zibo Gong <gongzib@outlook.com>
1 parent cef2695 commit 336b70e

File tree

1 file changed

+41
-1
lines changed

1 file changed

+41
-1
lines changed

ynl-gen-cpp.py

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -694,16 +694,28 @@ def presence_type(self):
694694
def _complex_member_type(self, ri):
695695
if "sub-type" not in self.attr or self.attr["sub-type"] == "nest":
696696
return self.nested_struct_type
697+
elif self.attr["sub-type"] == "binary" and "exact-len" in self.checks:
698+
return None # use arg_member()
697699
elif self.attr["sub-type"] in scalars:
698700
scalar_pfx = "__" if ri.ku_space == "user" else ""
699701
return scalar_pfx + self.attr["sub-type"]
700702
else:
701703
raise Exception(f"Sub-type {self.attr['sub-type']} not supported yet")
702704

705+
def arg_member(self, ri):
706+
if self.attr["sub-type"] == "binary" and "exact-len" in self.checks:
707+
return [
708+
f'std::vector<std::array<__u8, {self.checks["exact-len"]}>> {self.c_name}'
709+
]
710+
return super().arg_member(ri)
711+
703712
def _attr_typol(self):
704713
if self.attr["sub-type"] in scalars:
705714
return {"type": f"YNL_PT_U{c_upper(self.attr['sub-type'][1:])}"}
706-
return {"type": "YNL_PT_NEST", "nest": f"&{self.nested_render_name}_nest"}
715+
elif self.attr["sub-type"] == "binary" and "exact-len" in self.checks:
716+
return {"type": "YNL_PT_BINARY", "len": f'{self.checks["exact-len"]}'}
717+
else:
718+
return {"type": "YNL_PT_NEST", "nest": f"&{self.nested_render_name}_nest"}
707719

708720
def _attr_get(self, ri, var):
709721
local_vars = ["const struct nlattr *attr2;"]
@@ -712,6 +724,29 @@ def _attr_get(self, ri, var):
712724
]
713725
return get_lines, None, local_vars
714726

727+
def attr_put(self, ri, var):
728+
ri.cw.p(f"array = ynl_attr_nest_start(nlh, {self.enum_name});")
729+
if self.sub_type in scalars:
730+
put_type = self.sub_type
731+
ri.cw.block_start(
732+
line=f"for (unsigned int i = 0; i < {var}.{self.c_name}.size(); i++)"
733+
)
734+
ri.cw.p(f"ynl_attr_put_{put_type}(nlh, i, {var}.{self.c_name}[i]);")
735+
ri.cw.block_end()
736+
elif self.sub_type == "binary" and "exact-len" in self.checks:
737+
ri.cw.p(f"for (unsigned int i = 0; i < {var}.{self.c_name}.size(); i++)")
738+
ri.cw.p(
739+
f"ynl_attr_put(nlh, i, &{var}.{self.c_name}[i], {self.checks['exact-len']});"
740+
)
741+
elif self.sub_type == "nest":
742+
ri.cw.p(f"for (unsigned int i = 0; i < {var}.{self.c_name}.size(); i++)")
743+
ri.cw.p(f"{self.nested_render_name}_put(nlh, i, {var}.{self.c_name}[i]);")
744+
else:
745+
raise Exception(
746+
f"Put for ArrayNest sub-type {self.attr['sub-type']} not supported, yet"
747+
)
748+
ri.cw.p("ynl_attr_nest_end(nlh, array);")
749+
715750

716751
class TypeNestTypeValue(Type):
717752
def _complex_member_type(self, ri):
@@ -1842,6 +1877,11 @@ def _multi_parse(ri, struct, init_lines, local_vars):
18421877
ri.cw.p("return YNL_PARSE_CB_ERROR;")
18431878
elif aspec.sub_type in scalars:
18441879
ri.cw.p(f"dst->{aspec.c_name}[i] = ynl_attr_get_{aspec.sub_type}(attr);")
1880+
elif aspec.sub_type == "binary" and "exact-len" in aspec.checks:
1881+
# Length is validated by typol
1882+
ri.cw.p(
1883+
f'memcpy(dst->{aspec.c_name}[i].data(), ynl_attr_data(attr), {aspec.checks["exact-len"]});'
1884+
)
18451885
else:
18461886
raise Exception(f"Nest parsing type not supported in {aspec['name']}")
18471887
ri.cw.p("i++;")

0 commit comments

Comments
 (0)