4
4
//! Define FFI compatible AgentResponse struct
5
5
6
6
use data_pipeline:: trace_exporter:: agent_response:: AgentResponse ;
7
- use std:: ffi:: { c_char, CString } ;
7
+ use std:: {
8
+ ffi:: { c_char, CString } ,
9
+ ptr:: null,
10
+ } ;
8
11
9
12
/// Structure containing the agent response to a trace payload
10
13
/// MUST be freed with `ddog_trace_exporter_response_free`
@@ -35,18 +38,22 @@ impl From<AgentResponse> for ExporterResponse {
35
38
/// `response` is valid.
36
39
#[ no_mangle]
37
40
pub unsafe extern "C" fn ddog_trace_exporter_response_get_body (
38
- response : & ExporterResponse ,
41
+ response : * const ExporterResponse ,
39
42
) -> * const c_char {
40
- response. body . as_ptr ( )
43
+ if response. is_null ( ) {
44
+ null ( )
45
+ } else {
46
+ ( * response) . body . as_ptr ( )
47
+ }
41
48
}
42
49
43
50
/// Free `response` and all its contents. After being called response will not point to a valid
44
51
/// memory address so any further actions on it could lead to undefined behavior.
45
52
#[ no_mangle]
46
- pub unsafe extern "C" fn ddog_trace_exporter_response_free (
47
- response : Option < Box < ExporterResponse > > ,
48
- ) {
49
- drop ( response )
53
+ pub unsafe extern "C" fn ddog_trace_exporter_response_free ( response : * mut ExporterResponse ) {
54
+ if ! response. is_null ( ) {
55
+ drop ( Box :: from_raw ( response ) ) ;
56
+ }
50
57
}
51
58
52
59
#[ cfg( test) ]
@@ -59,20 +66,33 @@ mod tests {
59
66
let agent_response = AgentResponse :: Changed {
60
67
body : "res" . to_string ( ) ,
61
68
} ;
62
- let response = Box :: new ( ExporterResponse :: from ( agent_response) ) ;
69
+ let response = & ExporterResponse :: from ( agent_response) as * const ExporterResponse ;
63
70
let body = unsafe {
64
- CStr :: from_ptr ( ddog_trace_exporter_response_get_body ( & response) ) . to_string_lossy ( )
71
+ CStr :: from_ptr ( ddog_trace_exporter_response_get_body ( response) ) . to_string_lossy ( )
65
72
} ;
66
73
assert_eq ! ( body, "res" . to_string( ) ) ;
67
74
}
68
75
69
76
#[ test]
70
77
fn constructor_test_unchanged ( ) {
71
78
let agent_response = AgentResponse :: Unchanged ;
72
- let response = Box :: new ( ExporterResponse :: from ( agent_response) ) ;
79
+ let response = Box :: into_raw ( Box :: new ( ExporterResponse :: from ( agent_response) ) ) ;
73
80
let body = unsafe {
74
- CStr :: from_ptr ( ddog_trace_exporter_response_get_body ( & response) ) . to_string_lossy ( )
81
+ CStr :: from_ptr ( ddog_trace_exporter_response_get_body ( response) ) . to_string_lossy ( )
75
82
} ;
76
83
assert_eq ! ( body, "" . to_string( ) ) ;
84
+ unsafe {
85
+ ddog_trace_exporter_response_free ( response) ;
86
+ }
87
+ }
88
+
89
+ #[ test]
90
+ fn handle_null_test ( ) {
91
+ unsafe {
92
+ let body = ddog_trace_exporter_response_get_body ( null ( ) ) ;
93
+ assert ! ( body. is_null( ) ) ;
94
+
95
+ ddog_trace_exporter_response_free ( null :: < ExporterResponse > ( ) as * mut ExporterResponse ) ;
96
+ }
77
97
}
78
98
}
0 commit comments