2 # ex: set filetype=python:
4 """Generate code to handle XDR struct types"""
6 from jinja2
import Environment
8 from generators
import SourceGenerator
, kernel_c_type
9 from generators
import create_jinja2_environment
, get_jinja2_template
11 from xdr_ast
import _XdrBasic
, _XdrString
12 from xdr_ast
import _XdrFixedLengthOpaque
, _XdrVariableLengthOpaque
13 from xdr_ast
import _XdrFixedLengthArray
, _XdrVariableLengthArray
14 from xdr_ast
import _XdrOptionalData
, _XdrStruct
, _XdrDeclaration
15 from xdr_ast
import public_apis
, get_header_name
18 def emit_struct_declaration(environment
: Environment
, node
: _XdrStruct
) -> None:
19 """Emit one declaration pair for an XDR struct type"""
20 if node
.name
in public_apis
:
21 template
= get_jinja2_template(environment
, "declaration", "close")
22 print(template
.render(name
=node
.name
))
25 def emit_struct_member_definition(
26 environment
: Environment
, field
: _XdrDeclaration
28 """Emit a definition for one field in an XDR struct"""
29 if isinstance(field
, _XdrBasic
):
30 template
= get_jinja2_template(environment
, "definition", field
.template
)
34 type=kernel_c_type(field
.spec
),
35 classifier
=field
.spec
.c_classifier
,
38 elif isinstance(field
, _XdrFixedLengthOpaque
):
39 template
= get_jinja2_template(environment
, "definition", field
.template
)
46 elif isinstance(field
, _XdrVariableLengthOpaque
):
47 template
= get_jinja2_template(environment
, "definition", field
.template
)
48 print(template
.render(name
=field
.name
))
49 elif isinstance(field
, _XdrString
):
50 template
= get_jinja2_template(environment
, "definition", field
.template
)
51 print(template
.render(name
=field
.name
))
52 elif isinstance(field
, _XdrFixedLengthArray
):
53 template
= get_jinja2_template(environment
, "definition", field
.template
)
57 type=kernel_c_type(field
.spec
),
61 elif isinstance(field
, _XdrVariableLengthArray
):
62 template
= get_jinja2_template(environment
, "definition", field
.template
)
66 type=kernel_c_type(field
.spec
),
67 classifier
=field
.spec
.c_classifier
,
70 elif isinstance(field
, _XdrOptionalData
):
71 template
= get_jinja2_template(environment
, "definition", field
.template
)
75 type=kernel_c_type(field
.spec
),
76 classifier
=field
.spec
.c_classifier
,
81 def emit_struct_definition(environment
: Environment
, node
: _XdrStruct
) -> None:
82 """Emit one definition for an XDR struct type"""
83 template
= get_jinja2_template(environment
, "definition", "open")
84 print(template
.render(name
=node
.name
))
86 for field
in node
.fields
:
87 emit_struct_member_definition(environment
, field
)
89 template
= get_jinja2_template(environment
, "definition", "close")
90 print(template
.render(name
=node
.name
))
93 def emit_struct_member_decoder(
94 environment
: Environment
, field
: _XdrDeclaration
96 """Emit a decoder for one field in an XDR struct"""
97 if isinstance(field
, _XdrBasic
):
98 template
= get_jinja2_template(environment
, "decoder", field
.template
)
102 type=field
.spec
.type_name
,
103 classifier
=field
.spec
.c_classifier
,
106 elif isinstance(field
, _XdrFixedLengthOpaque
):
107 template
= get_jinja2_template(environment
, "decoder", field
.template
)
114 elif isinstance(field
, _XdrVariableLengthOpaque
):
115 template
= get_jinja2_template(environment
, "decoder", field
.template
)
119 maxsize
=field
.maxsize
,
122 elif isinstance(field
, _XdrString
):
123 template
= get_jinja2_template(environment
, "decoder", field
.template
)
127 maxsize
=field
.maxsize
,
130 elif isinstance(field
, _XdrFixedLengthArray
):
131 template
= get_jinja2_template(environment
, "decoder", field
.template
)
135 type=field
.spec
.type_name
,
137 classifier
=field
.spec
.c_classifier
,
140 elif isinstance(field
, _XdrVariableLengthArray
):
141 template
= get_jinja2_template(environment
, "decoder", field
.template
)
145 type=field
.spec
.type_name
,
146 maxsize
=field
.maxsize
,
147 classifier
=field
.spec
.c_classifier
,
150 elif isinstance(field
, _XdrOptionalData
):
151 template
= get_jinja2_template(environment
, "decoder", field
.template
)
155 type=field
.spec
.type_name
,
156 classifier
=field
.spec
.c_classifier
,
161 def emit_struct_decoder(environment
: Environment
, node
: _XdrStruct
) -> None:
162 """Emit one decoder function for an XDR struct type"""
163 template
= get_jinja2_template(environment
, "decoder", "open")
164 print(template
.render(name
=node
.name
))
166 for field
in node
.fields
:
167 emit_struct_member_decoder(environment
, field
)
169 template
= get_jinja2_template(environment
, "decoder", "close")
170 print(template
.render())
173 def emit_struct_member_encoder(
174 environment
: Environment
, field
: _XdrDeclaration
176 """Emit an encoder for one field in an XDR struct"""
177 if isinstance(field
, _XdrBasic
):
178 template
= get_jinja2_template(environment
, "encoder", field
.template
)
182 type=field
.spec
.type_name
,
185 elif isinstance(field
, _XdrFixedLengthOpaque
):
186 template
= get_jinja2_template(environment
, "encoder", field
.template
)
193 elif isinstance(field
, _XdrVariableLengthOpaque
):
194 template
= get_jinja2_template(environment
, "encoder", field
.template
)
198 maxsize
=field
.maxsize
,
201 elif isinstance(field
, _XdrString
):
202 template
= get_jinja2_template(environment
, "encoder", field
.template
)
206 maxsize
=field
.maxsize
,
209 elif isinstance(field
, _XdrFixedLengthArray
):
210 template
= get_jinja2_template(environment
, "encoder", field
.template
)
214 type=field
.spec
.type_name
,
218 elif isinstance(field
, _XdrVariableLengthArray
):
219 template
= get_jinja2_template(environment
, "encoder", field
.template
)
223 type=field
.spec
.type_name
,
224 maxsize
=field
.maxsize
,
227 elif isinstance(field
, _XdrOptionalData
):
228 template
= get_jinja2_template(environment
, "encoder", field
.template
)
232 type=field
.spec
.type_name
,
233 classifier
=field
.spec
.c_classifier
,
238 def emit_struct_encoder(environment
: Environment
, node
: _XdrStruct
) -> None:
239 """Emit one encoder function for an XDR struct type"""
240 template
= get_jinja2_template(environment
, "encoder", "open")
241 print(template
.render(name
=node
.name
))
243 for field
in node
.fields
:
244 emit_struct_member_encoder(environment
, field
)
246 template
= get_jinja2_template(environment
, "encoder", "close")
247 print(template
.render())
250 def emit_struct_maxsize(environment
: Environment
, node
: _XdrStruct
) -> None:
251 """Emit one maxsize macro for an XDR struct type"""
252 macro_name
= get_header_name().upper() + "_" + node
.name
+ "_sz"
253 template
= get_jinja2_template(environment
, "maxsize", "struct")
257 width
=" + ".join(node
.symbolic_width()),
262 class XdrStructGenerator(SourceGenerator
):
263 """Generate source code for XDR structs"""
265 def __init__(self
, language
: str, peer
: str):
266 """Initialize an instance of this class"""
267 self
.environment
= create_jinja2_environment(language
, "struct")
270 def emit_declaration(self
, node
: _XdrStruct
) -> None:
271 """Emit one declaration pair for an XDR struct type"""
272 emit_struct_declaration(self
.environment
, node
)
274 def emit_definition(self
, node
: _XdrStruct
) -> None:
275 """Emit one definition for an XDR struct type"""
276 emit_struct_definition(self
.environment
, node
)
278 def emit_decoder(self
, node
: _XdrStruct
) -> None:
279 """Emit one decoder function for an XDR struct type"""
280 emit_struct_decoder(self
.environment
, node
)
282 def emit_encoder(self
, node
: _XdrStruct
) -> None:
283 """Emit one encoder function for an XDR struct type"""
284 emit_struct_encoder(self
.environment
, node
)
286 def emit_maxsize(self
, node
: _XdrStruct
) -> None:
287 """Emit one maxsize macro for an XDR struct type"""
288 emit_struct_maxsize(self
.environment
, node
)