pub struct CSharp;Expand description
The C# backend.
Trait Implementations§
Source§impl CodecTarget for CSharp
impl CodecTarget for CSharp
Source§fn scalar(kind: Scalar) -> Self::Type
fn scalar(kind: Scalar) -> Self::Type
One IDL width, one C# keyword, same signedness.
The two counters are the exception and neither is a wire width.
Scalar::Index is int, which is what a C# array’s Length
is and what new T[n] and a subscript take. Scalar::Size is
long, and that is a correctness decision rather than a
spelling: a sequence’s declared count is a uint, the reader
checks it against ReaderRemaining() before allocating, and an
int there would make 0xFFFFFFFF compare as -1 and pass the
check it exists to fail.
Source§fn handle(kind: Handle) -> Self::Type
fn handle(kind: Handle) -> Self::Type
runtime/csharp publishes each handle as a type of its own in
ZeroDds.Wire, and every reference to one is rooted.
Not decoration. C# resolves a simple name against the global
namespace, where every generated type sits, so a corpus case
declaring enum Status puts its own type in front of the
runtime’s Status and Status.Discarded becomes CS0117 —
measured on enum-sparse-values and its unannotated twin, which
declare exactly that. global:: resolves at the global namespace
and nothing in any scope can capture it, which is the same reason
adapter/csharp.rs roots every path it writes.
Source§fn code_point(value: Self::Expr, _narrow: bool) -> Self::Expr
fn code_point(value: Self::Expr, _narrow: bool) -> Self::Expr
A C# char is one UTF-16 code unit, which is what the runtime’s
WriteChar and WriteWchar take. There is nothing to widen and
nothing to narrow, so the value goes through: the narrowing an
IDL char needs is the runtime’s, which refuses a code unit
above U+00FF rather than keeping its low byte.
Source§fn bit_pattern(source: BitPatternSource, value: Self::Expr) -> Self::Expr
fn bit_pattern(source: BitPatternSource, value: Self::Expr) -> Self::Expr
Statics on the runtime’s writer, rooted like every other runtime
reference — CodecTarget::runtime_static names the reader
for everything but no_dheader, so the default spelling would
call the wrong type.
Source§fn constant(which: Constant) -> Self::Expr
fn constant(which: Constant) -> Self::Expr
runtime/csharp publishes these as enum members, one type per
policy, and every reference is rooted for the reason
CodecTarget::handle gives.
Source§fn unsigned_holder(bits: u16) -> Self::Type
fn unsigned_holder(bits: u16) -> Self::Type
The materialiser’s answer, not a second reading of it.
adapter/csharp.rs::unsigned_holder decides what a
@bit_bound set’s field is declared as, and Table 33’s four
widths all have a C# keyword — which is where this parts from
Java, whose holder can only be int or long.
Source§fn runtime_static(method: &str, args: Vec<Self::Expr>) -> Self::Expr
fn runtime_static(method: &str, args: Vec<Self::Expr>) -> Self::Expr
C# has no free functions; the runtime class’s own static method stands in.
Which class is not a guess: no_dheader is the writer’s and
everything else is the reader’s. A name this table does not know
is written on Reader and csc names it — a compile error that
stops the probe, rather than a call that goes to the wrong class
and cannot.
Source§fn call(callee: &str, args: Vec<Self::Expr>) -> Self::Expr
fn call(callee: &str, args: Vec<Self::Expr>) -> Self::Expr
A free function is a static method of the generated class, so
an unqualified call reaches it from another method of the same
class without naming the class.
strcmp is the walk’s name for a three-way code-unit
comparison; here it is string.CompareOrdinal, which compares
UTF-16 code units — the Java column’s caveat about
supplementary code points applies unchanged.
Source§fn carries_hdds_axes() -> bool
fn carries_hdds_axes() -> bool
runtime/csharp carries the three HDDS axes: BeginPackedElement
and FinishPackedElement on the writer and the reader, the
DHEADER pair for a sequence element’s own length, and
WriteWstringUtf8Octets / ReadWstringUtf8Octets.
Source§fn wide_int(value: i128) -> Self::Expr
fn wide_int(value: i128) -> Self::Expr
The suffix that keeps a literal’s type from being the compiler’s guess.
ECMA-334 §6.4.5.3 gives an unsuffixed decimal the first of
int, uint, long, ulong that holds it, which is already
the right answer for every value — but a long label compared
against a long discriminator wants the width stated, and
16045690984833335998 past long.MaxValue has to be a ulong
where the discriminator is one. The suffix says which, so the
comparison is not decided by the operand the compiler happened
to widen.
Source§fn unsigned_int(value: i128) -> Self::Expr
fn unsigned_int(value: i128) -> Self::Expr
A count, wide enough to hold itself and with no u suffix.
C’s 5u is not a C# token; 5U is, and it is not wanted: a
bound compared against an int counter would force the whole
comparison into long for no reason. The bounds past int get
their L from CodecTarget::wide_int.
Source§fn wide_unsigned(value: u64) -> Self::Expr
fn wide_unsigned(value: u64) -> Self::Expr
A 64-bit mask, as the ulong it is.
Where the Java backend has to write the signed pattern because
Java has no unsigned integer, this is the number with a UL on
it — and ~0xFFFFFFFFFFFFFFFFUL is an unsigned complement
rather than an arithmetic one.
Source§fn wide_signed(value: i128) -> Self::Expr
fn wide_signed(value: i128) -> Self::Expr
A signed 64-bit constant, always suffixed: an enumerator’s
pattern is compared against a long and an unsuffixed literal
there would be widened after the comparison’s type was chosen.
Source§fn count_of(base: &str, fixed: Option<u64>) -> Self::Expr
fn count_of(base: &str, fixed: Option<u64>) -> Self::Expr
(uint)v.Length, or the bound itself where the materialiser
fixed one.
The cast is the crossing and is written out. A C# array’s
Length is an int; a sequence’s count is a uint on the wire
and Writer.WriteU32 takes one, and there is no implicit
int to uint conversion. A backend that let the runtime take
a wider signed type instead would be moving a range check out of
the compiler and into a throw.
Source§fn binary(op: &'static str, lhs: Self::Expr, rhs: Self::Expr) -> Self::Expr
fn binary(op: &'static str, lhs: Self::Expr, rhs: Self::Expr) -> Self::Expr
The operators as given, except a shift’s count: C# takes only an
int there (§12.11 in the C# standard names no ulong form),
and the walk writes the count in the accumulator’s own width —
zd_bits >> 3UL is CS0019. A literal count sheds its suffix,
any other spelling is cast.
Source§fn unary(op: &'static str, value: Self::Expr) -> Self::Expr
fn unary(op: &'static str, value: Self::Expr) -> Self::Expr
The operator as written. C# has a real unary form for !, ~
and -, so none of them needs the 0 <op> a stand-in the Java
backend writes.
Source§fn paren(value: Self::Expr) -> Self::Expr
fn paren(value: Self::Expr) -> Self::Expr
A bracket, written because the walk asked for one.
The renderer adds none of its own, and C#’s precedence is Java’s
where it matters here: & binds looser than !=, so
bits & mask != 0 is a type error rather than the comparison
the walk built.
Source§fn cast(type_: Self::Type, value: Self::Expr) -> Self::Expr
fn cast(type_: Self::Type, value: Self::Expr) -> Self::Expr
A conversion, kept where Java drops it.
Two reasons this column writes more casts than that one. A C#
enum has no implicit conversion to an integer, so the walk’s
(long)v on an enumerator and (ulong)v on a bitmask are
load-bearing. And csc has no redundant-cast diagnostic, so
keeping an identity cast costs nothing where -Xlint:cast -Werror fails the Java build over one.
The one rewrite is the bool discriminator. A union’s labels
arrive as the integers the IDL evaluator gives, and C# has no
conversion from 1 to true; the label is the value it stands
for.
Source§fn bool_less(left: Self::Expr, right: Self::Expr) -> Self::Expr
fn bool_less(left: Self::Expr, right: Self::Expr) -> Self::Expr
false before true, spelled as the conjunction — C#’s <
does not take two booleans (CS0019).
Source§fn handoff(value: Self::Expr, _form: Handoff) -> Self::Expr
fn handoff(value: Self::Expr, _form: Handoff) -> Self::Expr
Nothing to take an address of and no array to decay: both forms hand the value.
Source§fn declare(
type_: Self::Type,
name: &str,
value: Option<Self::Expr>,
) -> Self::Stmt
fn declare( type_: Self::Type, name: &str, value: Option<Self::Expr>, ) -> Self::Stmt
A local, with = default where the walk asked for no value.
The walk declares a header handle before the loop that fills it
— EmHeaderRead zd_h; — and C#’s definite-assignment rules make
a local read before its first assignment a compile error, which
a loop body the compiler cannot prove runs would be. default
on a readonly struct costs nothing and settles it.
Source§fn give_back(value: Option<Self::Expr>) -> Self::Stmt
fn give_back(value: Option<Self::Expr>) -> Self::Stmt
return v; where the walk asked for a bare return.
Only the reader leaves a routine early, and a C# decoder answers
with the sample it has built rather than writing through a
parameter it would have to take by ref. A bare return; would
leave the caller with whatever it had before, which is the
silent-wrong-value shape.
Source§fn mark_used(name: &str) -> Vec<Self::Stmt>
fn mark_used(name: &str) -> Vec<Self::Stmt>
_ = name;, a discard (C# 7.0): a read the language accepts as
a statement, where name; is not one. csc has no unread-parameter
diagnostic, but a local that is assigned and never read is CS0219,
and the probe treats warnings as errors: under OpenDDS’s XCDR1
framing a union writes no sentinel and nothing reads zd_sent
(union-mutable, evolution-union-unselected, 4 matrix cells).
Source§fn drop_value(value: Self::Expr) -> Self::Stmt
fn drop_value(value: Self::Expr) -> Self::Stmt
The call on its own. An invocation is already a C# statement,
and (void) expr; is not one at all.
Source§fn read_call(
callee: &str,
place: Self::Expr,
_form: Handoff,
behaviour: Self::Expr,
) -> Self::Stmt
fn read_call( callee: &str, place: Self::Expr, _form: Handoff, behaviour: Self::Expr, ) -> Self::Stmt
place = zd_dec_T(r, behaviour);
A decoder answers with its value rather than filling a
destination. C# has ref and out, and neither is usable here:
a property cannot be passed as either (CS0206), an array element
of a Nullable<T> member cannot be an out of T, and the
walk’s destinations are expressions rather than variables.
Source§fn read_forward(callee: &str) -> Self::Stmt
fn read_forward(callee: &str) -> Self::Stmt
v = zd_dec_T(r, zd_tc); — a typedef, handed straight on.
Source§fn keep_first(base: &str, count: Self::Expr) -> Vec<Self::Stmt>
fn keep_first(base: &str, count: Self::Expr) -> Vec<Self::Stmt>
A shorter array, because a C# array’s length is fixed at its allocation.
§7.3.1.2.1.12.3’s TRIM. C leaves the elements past the bound in
the buffer and moves the count, and there is no count here to
move; Array.Resize takes a ref and the walk’s base is an
expression, so the shortening is a copy. Written through
System.Linq rather than as three statements with a temporary,
because a temporary would need a name no two calls in one method
could share.
Source§fn count_up(counter: &str, bound: Self::Expr, body: Self::Block) -> Self::Stmt
fn count_up(counter: &str, bound: Self::Expr, body: Self::Block) -> Self::Stmt
for (int i = 0; i < bound; i = i + 1).
The step is written out rather than i++ for the same reason
the C and Java backends write it out: the tree has no increment
node, and one spelling in every backend keeps the columns’
generated source comparable by eye when their octets disagree.
Source§fn make_room(
base: &str,
element: Self::Type,
count: Self::Expr,
assigned_whole: bool,
fill: Vec<Self::Stmt>,
) -> Vec<Self::Stmt>
fn make_room( base: &str, element: Self::Type, count: Self::Expr, assigned_whole: bool, fill: Vec<Self::Stmt>, ) -> Vec<Self::Stmt>
The array, sized — and its slots given something to be where the fill writes into them rather than assigning them.
new T[n] throws rather than returning null when it cannot be
served, so there is no guard and the fill follows
unconditionally. new T[n] takes the count as an int, a
uint, a long or a ulong, so the uint the reader read is
handed over with no cast at all.
new T[n] of a class type is n nulls. A sequence’s element
decoder answers with a value and the slot is assigned outright,
so nothing is needed; a map’s two halves are written into the
entry at v[i], and an entry that was never made is a null
dereference at the first key. That is what assigned_whole
separates.
Source§fn store(place: Self::Expr, type_: Self::Type, value: Self::Expr) -> Self::Stmt
fn store(place: Self::Expr, type_: Self::Type, value: Self::Expr) -> Self::Stmt
The scalar into the place, cast to the place’s own type.
One cast and never two: the walk has already asked for a width
at one site — the element form of a wchar under TAO’s framing
asks for ushort — and a ushort does not convert to a char
on its own. The outer cast is unwrapped and rewritten to the
field’s type, which is the same thing the Java backend does for
its three narrow holders.
A Float128 place takes the value unchanged: it is a generated
struct and a cast to it does not compile.
Source§fn storage(type_: Self::Type, name: &str) -> Self::Stmt
fn storage(type_: Self::Type, name: &str) -> Self::Stmt
<T> name = new <T>(); — a C# local of a class type is a
reference to nothing until one is made.
Source§fn header_field(value: Self::Expr, field: &str) -> Self::Expr
fn header_field(value: Self::Expr, field: &str) -> Self::Expr
runtime/csharp publishes a header’s parts as fields and
properties in .NET’s naming, so the field the walk names is
re-cased here.
A match and not a general re-casing: end is End and
extent is a computed property, so a rule that only capitalised
would name two members that are not there. A name this table
does not know is written as it came, and csc reports it.
Source§fn present(base: &str, field: &str) -> Self::Expr
fn present(base: &str, field: &str) -> Self::Expr
Absence is the value, so presence is a comparison and not a
second field. null works for both halves of the mapping: a
reference type is nullable already and a value type’s T? is a
Nullable<T>, which compares against null.
Source§fn set_present(base: &str, field: &str, present: bool) -> Vec<Self::Stmt>
fn set_present(base: &str, field: &str, present: bool) -> Vec<Self::Stmt>
Nothing on the way in — assigning the member is what makes it
present — and null on the way out.
Source§fn case_member(base: &str, field: &str) -> Self::Expr
fn case_member(base: &str, field: &str) -> Self::Expr
One field per case, directly on the class.
Source§fn entry_half(entry: Self::Expr, key: bool) -> Self::Expr
fn entry_half(entry: Self::Expr, key: bool) -> Self::Expr
Key and Value, which is what fields_of folded the entry
class’s two IDL names to.
Source§fn optional_value(
ast: &Ast,
id: Id<TypeNode>,
base: &str,
field: &str,
) -> Self::Expr
fn optional_value( ast: &Ast, id: Id<TypeNode>, base: &str, field: &str, ) -> Self::Expr
The member, unwrapped where the mapping wrapped it.
A value type’s @optional member is a Nullable<T> and does
not convert to T on its own, so the write side takes
.Value — reached only inside the branch the presence test
guarded, which is where Nullable<T>.Value is defined. A
reference type was never wrapped and is handed over as it is.
Source§fn sequence_element(
base: &str,
index: Self::Expr,
_element: Self::Type,
) -> (Vec<Self::Stmt>, Self::Expr, Vec<Self::Stmt>)
fn sequence_element( base: &str, index: Self::Expr, _element: Self::Type, ) -> (Vec<Self::Stmt>, Self::Expr, Vec<Self::Stmt>)
v[i], and nothing around it: adapter/csharp.rs gives a
sequence a T[], whose elements are real slots at every element
type.
Source§fn optional_destination(
base: &str,
field: &str,
) -> (Vec<Self::Stmt>, Self::Expr)
fn optional_destination( base: &str, field: &str, ) -> (Vec<Self::Stmt>, Self::Expr)
The member itself. Assigning to it is what makes it present, and
a T assigned to a T? is the implicit conversion C# already
has, so there is nothing to do first.
Source§fn materialised(value: Self::Expr) -> Option<Self::Expr>
fn materialised(value: Self::Expr) -> Option<Self::Expr>
!= null, because a string and a T[] are references here.
Source§fn routine(spec: Routine<Self>) -> Option<Self::Decl>
fn routine(spec: Routine<Self>) -> Option<Self::Decl>
private static void EncodeT(Writer w, T v).
A prototype gets None: a C# method may call one declared below
it, so there is nothing to declare ahead. tolerate_unused is
dropped for the same kind of reason — csc does not warn on an
uncalled private method under the settings the probe builds
with, so there is no warning to suppress.
Source§fn value_type(ast: &Ast, id: Id<TypeNode>) -> Self::Type
fn value_type(ast: &Ast, id: Id<TypeNode>) -> Self::Type
The materialiser’s spelling, rooted: global::a.b.Point.
Not CodecTarget::type_name, which is the codec’s tag —
a_b_Point — and names a method rather than a type.
Source§fn type_name(ast: &Ast, id: Id<TypeNode>) -> String
fn type_name(ast: &Ast, id: Id<TypeNode>) -> String
The C# materialiser’s tag for a type.
The fallback carries the arena slot, and that is the point of
it: type_tag’s own answer for an unresolvable type is the bare
word unknown, and two of those in one model would be two types
sharing one codec — a member written by the wrong encoder, with
nothing red anywhere.
Source§fn escape(name: &str) -> String
fn escape(name: &str) -> String
The member fold, and only that.
venue to Venue, with a C# keyword escaped to @venue. Not
an enumerator’s name, which the materialiser leaves verbatim —
CodecTarget::enumerator_constant is that seam.
Source§fn map_entry_name(ast: &Ast, id: Id<TypeNode>) -> String
fn map_entry_name(ast: &Ast, id: Id<TypeNode>) -> String
global::ZdEntry_<key>_<value>.
The entry class is declared at the global scope and every
reference this column writes is rooted, for the reason
adapter/csharp.rs gives: a nested namespace can capture the
first segment of an unrooted path.
Source§fn module_prefix(_ast: &Ast, _id: Id<TypeNode>) -> String
fn module_prefix(_ast: &Ast, _id: Id<TypeNode>) -> String
C# has namespaces, so a module needs no prefix in a name.
Source§fn member_default(
ast: &Ast,
node: &MemberNode,
type_: Id<TypeNode>,
place: Self::Expr,
) -> Result<Vec<Self::Stmt>, EncodeError>
fn member_default( ast: &Ast, node: &MemberNode, type_: Id<TypeNode>, place: Self::Expr, ) -> Result<Vec<Self::Stmt>, EncodeError>
The member’s own @default, or Table 9’s value for its type.
§Errors
Source§fn default_into(
ast: &Ast,
id: Id<TypeNode>,
place: Self::Expr,
) -> Result<Self::Stmt, EncodeError>
fn default_into( ast: &Ast, id: Id<TypeNode>, place: Self::Expr, ) -> Result<Self::Stmt, EncodeError>
place = zd_def_<T>(); — Table 9, through the generated
defaulter.
§Errors
Never here. Whether the type has a C# default is decided where the defaulter is built, and refused there by name.
Source§fn enumerator_constant(
ast: &Ast,
id: Id<TypeNode>,
enumerator: &str,
) -> Self::Expr
fn enumerator_constant( ast: &Ast, id: Id<TypeNode>, enumerator: &str, ) -> Self::Expr
global::<modules>.<Enum>.<LITERAL>.
The materialiser declares a real enum and leaves the
enumerator’s name verbatim; a bare RED names nothing outside
the enum’s own scope, and Self::escape would fold it into a
member name the enum does not have.
Source§fn runtime(receiver: &str, method: &str, args: Vec<Self::Expr>) -> Self::Expr
fn runtime(receiver: &str, method: &str, args: Vec<Self::Expr>) -> Self::Expr
Source§fn member(base: &str, field: &str) -> Self::Expr
fn member(base: &str, field: &str) -> Self::Expr
Source§fn when(
condition: Self::Expr,
then: Self::Block,
otherwise: Option<Self::Block>,
) -> Self::Stmt
fn when( condition: Self::Expr, then: Self::Block, otherwise: Option<Self::Block>, ) -> Self::Stmt
if (cond) { .. } else { .. }Source§fn until(condition: Self::Expr, body: Self::Block) -> Self::Stmt
fn until(condition: Self::Expr, body: Self::Block) -> Self::Stmt
Source§fn elements(base: &str) -> Self::Expr
fn elements(base: &str) -> Self::Expr
Source§fn bulk_octets_write(base: &str, count: Self::Expr) -> Option<Self::Stmt>
fn bulk_octets_write(base: &str, count: Self::Expr) -> Option<Self::Stmt>
count octet elements of base at once, in place of the
element loop of a sequence<octet> or a one-dimensional
octet[N] (and the same over uint8); None, the default, keeps
the loop. The octets are the loop’s: an octet has alignment 1 and
no byte order (XTypes 1.3 §7.4.3.4.1), so a run of them is the same
bytes however it is copied. What a target gains is the per-element
call — measured in the C++ column: sequence<octet, 8192> element
by element cost ~100 µs per roundtrip of four codec passes.Source§fn bulk_octets_read(base: &str, count: Self::Expr) -> Option<Self::Stmt>
fn bulk_octets_read(base: &str, count: Self::Expr) -> Option<Self::Stmt>
Self::bulk_octets_write: count octets into
base, which already holds room for them.Source§fn make_room_of(
_ast: &Ast,
_element_id: Id<TypeNode>,
base: &str,
element: Self::Type,
count: Self::Expr,
assigned_whole: bool,
fill: Vec<Self::Stmt>,
) -> Vec<Self::Stmt>
fn make_room_of( _ast: &Ast, _element_id: Id<TypeNode>, base: &str, element: Self::Type, count: Self::Expr, assigned_whole: bool, fill: Vec<Self::Stmt>, ) -> Vec<Self::Stmt>
CodecTarget::make_room for a sequence whose element is
element_id. A target that cannot spell a slot’s start value from
element alone overrides it: Kotlin’s Array(n) { T() } has no
constructor to call where T is a typealias of Int.Source§fn clear_union_cases(base: &str, fields: &[String]) -> Vec<Self::Stmt>
fn clear_union_cases(base: &str, fields: &[String]) -> Vec<Self::Stmt>
Source§fn open_array(base: &str, lengths: &[i128]) -> Vec<Self::Stmt>
fn open_array(base: &str, lengths: &[i128]) -> Vec<Self::Stmt>
lengths are its dimensions,
outermost first. Read moreSource§fn close_array(base: &str, lengths: &[i128]) -> Vec<Self::Stmt>
fn close_array(base: &str, lengths: &[i128]) -> Vec<Self::Stmt>
CodecTarget::open_array.Source§fn enumerator_ordinal(
ast: &Ast,
id: Id<TypeNode>,
value: Self::Expr,
) -> Self::Expr
fn enumerator_ordinal( ast: &Ast, id: Id<TypeNode>, value: Self::Expr, ) -> Self::Expr
Source§fn case_label(ast: &Ast, discriminator: Id<TypeNode>, value: i128) -> Self::Expr
fn case_label(ast: &Ast, discriminator: Id<TypeNode>, value: i128) -> Self::Expr
Source§fn behind_indirection(
ast: &Ast,
id: Id<TypeNode>,
place: Self::Expr,
) -> Self::Expr
fn behind_indirection( ast: &Ast, id: Id<TypeNode>, place: Self::Expr, ) -> Self::Expr
Source§fn make_indirection(
ast: &Ast,
id: Id<TypeNode>,
place: Self::Expr,
) -> (Vec<Self::Stmt>, Self::Expr)
fn make_indirection( ast: &Ast, id: Id<TypeNode>, place: Self::Expr, ) -> (Vec<Self::Stmt>, Self::Expr)
CodecTarget::behind_indirection:
the same place, and what has to happen before a reader can write
through it. Read moreSource§fn holds_by_reference(
ast: &Ast,
aggregate: Id<TypeNode>,
member_type: Id<TypeNode>,
optional: bool,
external: bool,
) -> bool
fn holds_by_reference( ast: &Ast, aggregate: Id<TypeNode>, member_type: Id<TypeNode>, optional: bool, external: bool, ) -> bool
@optional or @external member of
aggregate, of type member_type, behind a reference of its own
— where the shared walk would reach it through
CodecTarget::present, CodecTarget::optional_value and
their external_ counterparts. A member this answers for goes
through CodecTarget::reference_present,
CodecTarget::reference_value,
CodecTarget::reference_destination and
CodecTarget::reference_absent instead. Read moreSource§fn reference_present(base: &str, field: &str) -> Self::Expr
fn reference_present(base: &str, field: &str) -> Self::Expr
CodecTarget::holds_by_reference answers for
is present. Reached only where that answered true.Source§fn reference_value(
ast: &Ast,
id: Id<TypeNode>,
base: &str,
field: &str,
) -> Self::Expr
fn reference_value( ast: &Ast, id: Id<TypeNode>, base: &str, field: &str, ) -> Self::Expr
Source§fn reference_destination(
ast: &Ast,
id: Id<TypeNode>,
base: &str,
field: &str,
) -> (Vec<Self::Stmt>, Self::Expr)
fn reference_destination( ast: &Ast, id: Id<TypeNode>, base: &str, field: &str, ) -> (Vec<Self::Stmt>, Self::Expr)
id is the member’s type.Source§fn reference_absent(base: &str, field: &str) -> Vec<Self::Stmt>
fn reference_absent(base: &str, field: &str) -> Vec<Self::Stmt>
Source§fn holds_a_cycle_externally() -> bool
fn holds_a_cycle_externally() -> bool
@external one — through the external_ seams
below, whether or not the member carries the annotation. Read moreSource§fn externals_are_pointers() -> bool
fn externals_are_pointers() -> bool
@external member behind a pointer
of its own, where the member’s value is not a pointer already. Read moreSource§fn optionals_are_pointers() -> bool
fn optionals_are_pointers() -> bool
@optional member behind a pointer
of its own, where the member’s value is not a pointer already. Read moreSource§fn value_is_pointer(ast: &Ast, id: Id<TypeNode>) -> bool
fn value_is_pointer(ast: &Ast, id: Id<TypeNode>) -> bool
id is a pointer already, so that
an @external or @optional member of that type needs no pointer
of its own. C’s string, wstring and fixed are
const char * (XTypes 1.3 §7.5.1.2.3.1); a C++ std::string is
a value.Source§fn refuse_unset_external(present: Self::Expr) -> Vec<Self::Stmt>
fn refuse_unset_external(present: Self::Expr) -> Vec<Self::Stmt>
@external
member that is not @optional has no value at the time of the
write. Read moreSource§fn external_value(
ast: &Ast,
id: Id<TypeNode>,
base: &str,
field: &str,
optional: bool,
) -> Self::Expr
fn external_value( ast: &Ast, id: Id<TypeNode>, base: &str, field: &str, optional: bool, ) -> Self::Expr
@external member, as the member’s codec takes
it. Read moreSource§fn external_destination(
base: &str,
field: &str,
optional: bool,
) -> (Vec<Self::Stmt>, Self::Expr)
fn external_destination( base: &str, field: &str, optional: bool, ) -> (Vec<Self::Stmt>, Self::Expr)
@external member’s value, and what it
takes to have somewhere to put it. The reading counterpart of
CodecTarget::external_value, shaped like
CodecTarget::optional_destination and for the same reason: a
column whose member is an indirection has to make storage before
there is a value to write into. The default is the walk’s old
answer for both combinations.Source§fn external_present(base: &str, field: &str) -> Self::Expr
fn external_present(base: &str, field: &str) -> Self::Expr
@optional @external member is present. Read moreSource§fn external_set_present(
base: &str,
field: &str,
present: bool,
) -> Vec<Self::Stmt>
fn external_set_present( base: &str, field: &str, present: bool, ) -> Vec<Self::Stmt>
@optional @external member is present, or is not.
The counterpart of CodecTarget::set_present, split for the
reason CodecTarget::external_present gives.Source§fn external_case_value(
ast: &Ast,
id: Id<TypeNode>,
base: &str,
field: &str,
) -> Self::Expr
fn external_case_value( ast: &Ast, id: Id<TypeNode>, base: &str, field: &str, ) -> Self::Expr
@external union branch, as the branch’s codec
takes it. The union counterpart of
CodecTarget::external_value, reached through
CodecTarget::case_member because that is the accessor a
branch has; there is no optional parameter because no union
member is @optional (DDS-XTypes 1.3 §7.2.2.4.4.4.7). The
default is the accessor itself — the columns that keep the value
inline — and a column that keeps an indirection answers with the
dereference, exactly as it does for a structure member.Source§fn external_case_destination(
base: &str,
field: &str,
) -> (Vec<Self::Stmt>, Self::Expr)
fn external_case_destination( base: &str, field: &str, ) -> (Vec<Self::Stmt>, Self::Expr)
@external union branch’s value, and
what it takes to have somewhere to put it. The union counterpart
of CodecTarget::external_destination, shaped the same way
and defaulted the same way.Source§fn published_name(name: String) -> String
fn published_name(name: String) -> String
Source§fn initialized_reader(
_spec: Routine<Self>,
_initializer: Self::Stmt,
) -> Option<Self::Decl>
fn initialized_reader( _spec: Routine<Self>, _initializer: Self::Stmt, ) -> Option<Self::Decl>
Source§fn bitmask_value(ast: &Ast, id: Id<TypeNode>, value: Self::Expr) -> Self::Expr
fn bitmask_value(ast: &Ast, id: Id<TypeNode>, value: Self::Expr) -> Self::Expr
Source§fn inherited_path(depth: usize) -> Option<String>
fn inherited_path(depth: usize) -> Option<String>
depth levels up,
for a column that binds inheritance as a first member parent
(XTypes 1.3 §7.5.1.4.1.3), ending in the separator: parent. for the
base, parent.parent. for its base. None, the default, is a column
that declares the base’s members in the derived structure.