1- using System ;
21using System . Runtime . InteropServices ;
2+ using System . Text ;
33
44namespace Yggdrasil ;
55
6+
67internal static class FFI
78{
8- private static IntPtr _libHandle ;
9+ private static readonly IntPtr _libHandle ;
910
1011 static FFI ( )
1112 {
1213 _libHandle = NativeLibLoader . LoadNativeLibrary ( ) ;
1314
15+ // standard ygg messages, these require a buffer and return one
16+ check_enabled = LoadMsgCall ( "flat_check_enabled" ) ;
17+ check_variant = LoadMsgCall ( "flat_check_variant" ) ;
18+ define_counter = LoadMsgCall ( "flat_define_counter" ) ;
19+ inc_counter = LoadMsgCall ( "flat_inc_counter" ) ;
20+ define_gauge = LoadMsgCall ( "flat_define_gauge" ) ;
21+ set_gauge = LoadMsgCall ( "flat_set_gauge" ) ;
22+ define_histogram = LoadMsgCall ( "flat_define_histogram" ) ;
23+ observe_histogram = LoadMsgCall ( "flat_observe_histogram" ) ;
24+
1425 new_engine = Marshal . GetDelegateForFunctionPointer < NewEngineDelegate > ( NativeLibLoader . LoadFunctionPointer ( _libHandle , "new_engine" ) ) ;
1526 free_engine = Marshal . GetDelegateForFunctionPointer < FreeEngineDelegate > ( NativeLibLoader . LoadFunctionPointer ( _libHandle , "free_engine" ) ) ;
16- get_metrics = Marshal . GetDelegateForFunctionPointer < GetMetricsDelegate > ( NativeLibLoader . LoadFunctionPointer ( _libHandle , "get_metrics" ) ) ;
17- take_state = Marshal . GetDelegateForFunctionPointer < TakeStateDelegate > ( NativeLibLoader . LoadFunctionPointer ( _libHandle , "take_state" ) ) ;
1827 get_state = Marshal . GetDelegateForFunctionPointer < GetStateDelegate > ( NativeLibLoader . LoadFunctionPointer ( _libHandle , "get_state" ) ) ;
19- check_enabled = Marshal . GetDelegateForFunctionPointer < CheckEnabledDelegate > ( NativeLibLoader . LoadFunctionPointer ( _libHandle , "check_enabled" ) ) ;
20- check_variant = Marshal . GetDelegateForFunctionPointer < CheckVariantDelegate > ( NativeLibLoader . LoadFunctionPointer ( _libHandle , "check_variant" ) ) ;
2128 free_response = Marshal . GetDelegateForFunctionPointer < FreeResponseDelegate > ( NativeLibLoader . LoadFunctionPointer ( _libHandle , "free_response" ) ) ;
22- count_toggle = Marshal . GetDelegateForFunctionPointer < CountToggleDelegate > ( NativeLibLoader . LoadFunctionPointer ( _libHandle , "count_toggle" ) ) ;
23- count_variant = Marshal . GetDelegateForFunctionPointer < CountVariantDelegate > ( NativeLibLoader . LoadFunctionPointer ( _libHandle , "count_variant" ) ) ;
24- should_emit_impression_event = Marshal . GetDelegateForFunctionPointer < ShouldEmitImpressionEventDelegate > ( NativeLibLoader . LoadFunctionPointer ( _libHandle , "should_emit_impression_event" ) ) ;
25- built_in_strategies = Marshal . GetDelegateForFunctionPointer < BuiltInStrategiesDelegate > ( NativeLibLoader . LoadFunctionPointer ( _libHandle , "built_in_strategies" ) ) ;
26- list_known_toggles = Marshal . GetDelegateForFunctionPointer < ListKnownTogglesDelegate > ( NativeLibLoader . LoadFunctionPointer ( _libHandle , "list_known_toggles" ) ) ;
29+
30+ // everything else has some special details to it
31+ // if these get out of hand they'll need some refactor but for now 5 is fine
32+ take_state = Marshal . GetDelegateForFunctionPointer < TakeStateDelegate > (
33+ NativeLibLoader . LoadFunctionPointer ( _libHandle , "flat_take_state" ) ) ;
34+
35+ free_buffer = Marshal . GetDelegateForFunctionPointer < FreeBufferDelegate > (
36+ NativeLibLoader . LoadFunctionPointer ( _libHandle , "flat_buf_free" ) ) ;
37+
38+ list_known_toggles = Marshal . GetDelegateForFunctionPointer < ListKnownTogglesDelegate > (
39+ NativeLibLoader . LoadFunctionPointer ( _libHandle , "flat_list_known_toggles" ) ) ;
40+
41+ built_in_strategies = Marshal . GetDelegateForFunctionPointer < BuiltInStrategiesDelegate > (
42+ NativeLibLoader . LoadFunctionPointer ( _libHandle , "flat_built_in_strategies" ) ) ;
43+
44+ get_metrics = Marshal . GetDelegateForFunctionPointer < GetMetricsDelegate > (
45+ NativeLibLoader . LoadFunctionPointer ( _libHandle , "flat_get_metrics" ) ) ;
2746 }
2847
48+ // one delegate type to rule them all, lets us not have to deal with a ton of delegate types in the higher layers
49+ [ UnmanagedFunctionPointer ( CallingConvention . Cdecl ) ]
50+ private delegate Buf FlatBufferMessageDelegate ( IntPtr enginePtr , byte [ ] message , nuint messageLen ) ;
51+
52+ [ UnmanagedFunctionPointer ( CallingConvention . Cdecl ) ]
53+ private delegate Buf TakeStateDelegate ( IntPtr ptr , byte [ ] json ) ;
54+
55+ [ UnmanagedFunctionPointer ( CallingConvention . Cdecl ) ]
56+ private delegate void FreeBufferDelegate ( Buf buf ) ;
57+
58+ [ UnmanagedFunctionPointer ( CallingConvention . Cdecl ) ]
59+ private delegate Buf ListKnownTogglesDelegate ( IntPtr enginePtr ) ;
60+
61+ [ UnmanagedFunctionPointer ( CallingConvention . Cdecl ) ]
62+ private delegate Buf BuiltInStrategiesDelegate ( ) ;
63+
64+ [ UnmanagedFunctionPointer ( CallingConvention . Cdecl ) ]
65+ private delegate Buf GetMetricsDelegate ( IntPtr enginePtr ) ;
66+
67+ [ UnmanagedFunctionPointer ( CallingConvention . Cdecl ) ]
2968 private delegate IntPtr NewEngineDelegate ( ) ;
69+
70+ [ UnmanagedFunctionPointer ( CallingConvention . Cdecl ) ]
3071 private delegate void FreeEngineDelegate ( IntPtr ptr ) ;
31- private delegate IntPtr GetMetricsDelegate ( IntPtr ptr ) ;
32- private delegate IntPtr TakeStateDelegate ( IntPtr ptr , byte [ ] json ) ;
72+
73+ [ UnmanagedFunctionPointer ( CallingConvention . Cdecl ) ]
3374 private delegate IntPtr GetStateDelegate ( IntPtr ptr ) ;
34- private delegate IntPtr CheckEnabledDelegate ( IntPtr ptr , byte [ ] toggle_name , byte [ ] context , byte [ ] customStrategyResults ) ;
35- private delegate IntPtr CheckVariantDelegate ( IntPtr ptr , byte [ ] toggle_name , byte [ ] context , byte [ ] customStrategyResults ) ;
75+
76+ [ UnmanagedFunctionPointer ( CallingConvention . Cdecl ) ]
3677 private delegate void FreeResponseDelegate ( IntPtr ptr ) ;
37- private delegate IntPtr CountToggleDelegate ( IntPtr ptr , byte [ ] toggle_name , bool enabled ) ;
38- private delegate IntPtr CountVariantDelegate ( IntPtr ptr , byte [ ] toggle_name , byte [ ] variant_name ) ;
39- private delegate IntPtr ShouldEmitImpressionEventDelegate ( IntPtr ptr , byte [ ] toggle_name ) ;
40- private delegate IntPtr BuiltInStrategiesDelegate ( IntPtr ptr ) ;
41- private delegate IntPtr ListKnownTogglesDelegate ( IntPtr ptr ) ;
4278 private static readonly NewEngineDelegate new_engine ;
4379 private static readonly FreeEngineDelegate free_engine ;
44- private static readonly GetMetricsDelegate get_metrics ;
45- private static readonly TakeStateDelegate take_state ;
4680 private static readonly GetStateDelegate get_state ;
47- private static readonly CheckEnabledDelegate check_enabled ;
48- private static readonly CheckVariantDelegate check_variant ;
4981 private static readonly FreeResponseDelegate free_response ;
50- private static readonly CountToggleDelegate count_toggle ;
51- private static readonly CountVariantDelegate count_variant ;
52- private static readonly ShouldEmitImpressionEventDelegate should_emit_impression_event ;
53- private static readonly BuiltInStrategiesDelegate built_in_strategies ;
82+
83+ private static readonly TakeStateDelegate take_state ;
84+ private static readonly FreeBufferDelegate free_buffer ;
85+
86+ private static readonly FlatBufferMessageDelegate check_enabled ;
87+ private static readonly FlatBufferMessageDelegate check_variant ;
88+
89+ private static readonly FlatBufferMessageDelegate define_counter ;
90+ private static readonly FlatBufferMessageDelegate inc_counter ;
91+ private static readonly FlatBufferMessageDelegate define_gauge ;
92+ private static readonly FlatBufferMessageDelegate set_gauge ;
93+ private static readonly FlatBufferMessageDelegate define_histogram ;
94+ private static readonly FlatBufferMessageDelegate observe_histogram ;
95+
5496 private static readonly ListKnownTogglesDelegate list_known_toggles ;
97+ private static readonly BuiltInStrategiesDelegate built_in_strategies ;
98+ private static readonly GetMetricsDelegate get_metrics ;
5599
56- public static IntPtr NewEngine ( )
57- {
58- return new_engine ( ) ;
59- }
100+ internal static Buf TakeState ( IntPtr ptr , string json )
101+ => take_state ( ptr , ToUtf8NullTerminated ( json ) ) ;
60102
61- public static void FreeEngine ( IntPtr ptr )
62- {
63- free_engine ( ptr ) ;
64- }
103+ internal static Buf CheckEnabled ( IntPtr ptr , byte [ ] message )
104+ => check_enabled ( ptr , message , ( nuint ) message . Length ) ;
65105
66- public static IntPtr GetMetrics ( IntPtr ptr )
67- {
68- return get_metrics ( ptr ) ;
69- }
106+ internal static Buf CheckVariant ( IntPtr ptr , byte [ ] message )
107+ => Call ( message , ptr , check_variant ) ;
70108
71- public static IntPtr TakeState ( IntPtr ptr , string json )
72- {
73- return take_state ( ptr , ToUtf8Bytes ( json ) ) ;
74- }
109+ internal static Buf DefineCounter ( IntPtr ptr , byte [ ] message )
110+ => Call ( message , ptr , define_counter ) ;
75111
76- public static IntPtr GetState ( IntPtr ptr )
77- {
78- return get_state ( ptr ) ;
79- }
112+ internal static Buf IncCounter ( IntPtr ptr , byte [ ] message )
113+ => Call ( message , ptr , inc_counter ) ;
80114
81- public static IntPtr CheckEnabled ( IntPtr ptr , string toggle_name , string context , string customStrategyResults )
82- {
83- return check_enabled ( ptr , ToUtf8Bytes ( toggle_name ) , ToUtf8Bytes ( context ) , ToUtf8Bytes ( customStrategyResults ) ) ;
84- }
115+ internal static Buf DefineGauge ( IntPtr ptr , byte [ ] message )
116+ => Call ( message , ptr , define_gauge ) ;
85117
86- public static IntPtr CheckVariant ( IntPtr ptr , string toggle_name , string context , string customStrategyResults )
87- {
88- return check_variant ( ptr , ToUtf8Bytes ( toggle_name ) , ToUtf8Bytes ( context ) , ToUtf8Bytes ( customStrategyResults ) ) ;
89- }
118+ internal static Buf SetGauge ( IntPtr ptr , byte [ ] message )
119+ => Call ( message , ptr , set_gauge ) ;
90120
91- public static void FreeResponse ( IntPtr ptr )
92- {
93- free_response ( ptr ) ;
94- }
121+ internal static Buf DefineHistogram ( IntPtr ptr , byte [ ] message )
122+ => Call ( message , ptr , define_histogram ) ;
123+
124+ internal static Buf ObserveHistogram ( IntPtr ptr , byte [ ] message )
125+ => Call ( message , ptr , observe_histogram ) ;
126+
127+ internal static Buf ListKnownToggles ( IntPtr ptr ) => list_known_toggles ( ptr ) ;
128+
129+ internal static Buf BuiltInStrategies ( ) => built_in_strategies ( ) ;
130+
131+ internal static Buf GetMetrics ( IntPtr ptr ) => get_metrics ( ptr ) ;
132+
133+ internal static void FreeBuf ( Buf buf ) => free_buffer ( buf ) ;
95134
96- public static IntPtr CountToggle ( IntPtr ptr , string toggle_name , bool enabled )
135+ internal static IntPtr NewEngine ( )
97136 {
98- return count_toggle ( ptr , ToUtf8Bytes ( toggle_name ) , enabled ) ;
137+ return new_engine ( ) ;
99138 }
100139
101- public static IntPtr CountVariant ( IntPtr ptr , string toggle_name , string variant_name )
140+ internal static void FreeEngine ( IntPtr ptr )
102141 {
103- return count_variant ( ptr , ToUtf8Bytes ( toggle_name ) , ToUtf8Bytes ( variant_name ) ) ;
142+ free_engine ( ptr ) ;
104143 }
105144
106- public static IntPtr ShouldEmitImpressionEvent ( IntPtr ptr , string toggle_name )
145+ internal static IntPtr GetState ( IntPtr ptr )
107146 {
108- return should_emit_impression_event ( ptr , ToUtf8Bytes ( toggle_name ) ) ;
147+ return get_state ( ptr ) ;
109148 }
110149
111- public static IntPtr BuiltInStrategies ( IntPtr ptr )
150+ internal static void FreeResponse ( IntPtr ptr )
112151 {
113- return built_in_strategies ( ptr ) ;
152+ free_response ( ptr ) ;
114153 }
115154
116- public static IntPtr ListKnownToggles ( IntPtr ptr )
155+ private static FlatBufferMessageDelegate LoadMsgCall ( string symbol )
156+ => Marshal . GetDelegateForFunctionPointer < FlatBufferMessageDelegate > (
157+ NativeLibLoader . LoadFunctionPointer ( _libHandle , symbol ) ) ;
158+
159+ private static Buf Call ( byte [ ] message , IntPtr enginePtr , FlatBufferMessageDelegate nativeCall )
117160 {
118- return list_known_toggles ( ptr ) ;
161+ if ( message is null ) throw new ArgumentNullException ( nameof ( message ) ) ;
162+
163+ return nativeCall ( enginePtr , message , ( nuint ) message . Length ) ;
119164 }
120165
121- private static byte [ ] ToUtf8Bytes ( string input )
166+ private static byte [ ] ToUtf8NullTerminated ( string input )
122167 {
123- byte [ ] utf8Bytes = System . Text . Encoding . UTF8 . GetBytes ( input ) ;
168+ if ( input is null ) throw new ArgumentNullException ( nameof ( input ) ) ;
169+
170+ byte [ ] utf8Bytes = Encoding . UTF8 . GetBytes ( input ) ;
124171 Array . Resize ( ref utf8Bytes , utf8Bytes . Length + 1 ) ;
125172 return utf8Bytes ;
126173 }
127- }
174+ }
0 commit comments