@@ -25,21 +25,23 @@ extern "C" {
2525 pub static __CFConstantStringClassReference: Class ;
2626}
2727
28- // From `CFString.c`:
29- // https://github.com/apple-oss-distributions/CF/blob/CF-1153.18/CFString.c#L184-L212
30- // > !!! Note: Constant CFStrings use the bit patterns:
31- // > C8 (11001000 = default allocator, not inline, not freed contents; 8-bit; has NULL byte; doesn't have length; is immutable)
32- // > D0 (11010000 = default allocator, not inline, not freed contents; Unicode; is immutable)
33- // > The bit usages should not be modified in a way that would effect these bit patterns.
34- //
35- // The 7 byte is the `CFTypeID` of `CFStringRef`.
36- const FLAGS_ASCII : usize = 0x07_C8 ;
37- const FLAGS_UTF16 : usize = 0x07_D0 ;
38-
28+ /// Structure used to describe a constant `CFString`.
29+ ///
30+ /// This struct is the same as [`CF_CONST_STRING`], which contains
31+ /// [`CFRuntimeBase`]. While the documentation clearly says that the ABI of
32+ /// `CFRuntimeBase` should not be relied on, we can rely on it as long as we
33+ /// only do it with regards to `CFString` (because `clang` does this as well).
34+ ///
35+ /// [`CFRuntimeBase`]: <https://github.com/apple-oss-distributions/CF/blob/CF-1153.18/CFRuntime.h#L216-L228>
36+ /// [`CF_CONST_STRING`]: <https://github.com/apple-oss-distributions/CF/blob/CF-1153.18/CFInternal.h#L332-L336>
3937#[ repr( C ) ]
4038pub struct CFConstString {
4139 isa : & ' static Class ,
42- flags : usize ,
40+ // Important that we don't just use `usize` here, since that would be
41+ // wrong on big-endian systems!
42+ cfinfo : u32 ,
43+ #[ cfg( target_pointer_width = "64" ) ]
44+ _rc : u32 ,
4345 data : * const c_void ,
4446 len : usize ,
4547}
@@ -48,10 +50,26 @@ pub struct CFConstString {
4850unsafe impl Sync for CFConstString { }
4951
5052impl CFConstString {
53+ // From `CFString.c`:
54+ // <https://github.com/apple-oss-distributions/CF/blob/CF-1153.18/CFString.c#L184-L212>
55+ // > !!! Note: Constant CFStrings use the bit patterns:
56+ // > C8 (11001000 = default allocator, not inline, not freed contents; 8-bit; has NULL byte; doesn't have length; is immutable)
57+ // > D0 (11010000 = default allocator, not inline, not freed contents; Unicode; is immutable)
58+ // > The bit usages should not be modified in a way that would effect these bit patterns.
59+ //
60+ // Hence CoreFoundation guarantees that these two are always valid.
61+ //
62+ // The `CFTypeID` of `CFStringRef` is guaranteed to always be 7:
63+ // <https://github.com/apple-oss-distributions/CF/blob/CF-1153.18/CFRuntime.c#L982>
64+ const FLAGS_ASCII : u32 = 0x07_C8 ;
65+ const FLAGS_UTF16 : u32 = 0x07_D0 ;
66+
5167 pub const unsafe fn new_ascii ( isa : & ' static Class , data : & ' static [ u8 ] ) -> Self {
5268 Self {
5369 isa,
54- flags : FLAGS_ASCII ,
70+ cfinfo : Self :: FLAGS_ASCII ,
71+ #[ cfg( target_pointer_width = "64" ) ]
72+ _rc : 0 ,
5573 data : data. as_ptr ( ) . cast ( ) ,
5674 // The length does not include the trailing NUL.
5775 len : data. len ( ) - 1 ,
@@ -61,7 +79,9 @@ impl CFConstString {
6179 pub const unsafe fn new_utf16 ( isa : & ' static Class , data : & ' static [ u16 ] ) -> Self {
6280 Self {
6381 isa,
64- flags : FLAGS_UTF16 ,
82+ cfinfo : Self :: FLAGS_UTF16 ,
83+ #[ cfg( target_pointer_width = "64" ) ]
84+ _rc : 0 ,
6585 data : data. as_ptr ( ) . cast ( ) ,
6686 // The length does not include the trailing NUL.
6787 len : data. len ( ) - 1 ,
0 commit comments