// Generated from executable documentation examples. Edit the source region, then regenerate. using System; using System.IO; using System.IO.Pipelines; using System.Linq; using System.Buffers; using System.Collections.Generic; using System.Dynamic; using System.Globalization; using System.Numerics; using System.Runtime.CompilerServices; using System.Threading; using System.Threading.Tasks; using CStructSharp; using CStructSharp.Codecs; using CStructSharp.Diagnostics; using CStructSharp.Introspection; using CStructSharp.Values; internal static partial class Program { public static void Main() { LayoutIntrospection(); Console.WriteLine("PASS layout-introspection"); } private static void LayoutIntrospection() { // `Layout` describes the compiled declarations with sizes, offsets, and members; `ToDefinition` renders // them back; `WithEndianness` compiles the sibling layout a byte-order-switching format needs. var layout = new CStruct("enum kind : uint8 { NONE, DATA = 2 }; struct root { kind type; uint16 length; char name[4]; };"); LayoutDeclarationInfo root = layout.Layout.Declarations.Single(item => item.Name == "root"); Equal(7, root.Size!.Value); Equal(1, root.Fields[1].Offset!.Value); Equal("uint16", root.Fields[1].TypeName); Equal(LayoutArrayKind.Fixed, root.Fields[2].ArrayKind); LayoutDeclarationInfo kind = layout.Layout.Declarations.Single(item => item.Name == "kind"); Equal(new BigInteger(2), kind.Members[1].Value); string definition = layout.ToDefinition(); True(definition.Contains("enum kind : uint8 {", StringComparison.Ordinal), "the rendered definition names the enum"); Equal(7, new CStruct(definition).GetStructSizeInBytes("root")); byte[] bigEndian = [2, 0x01, 0x02, (byte)'a', (byte)'b', 0, 0]; Equal((ushort)0x0102, layout.WithEndianness(isLittleEndian: false).Parse(bigEndian, "root").Get("length")); True(ReferenceEquals(layout, layout.WithEndianness(isLittleEndian: true)), "the same byte order returns the same instance"); } private static void Equal(T expected, T actual) { if (!EqualityComparer.Default.Equals(expected, actual)) { throw new InvalidOperationException($"Expected '{expected}', received '{actual}'."); } } private static void True(bool condition, string message) { if (!condition) { throw new InvalidOperationException(message); } } }