// Copyright 2013 The Servo Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution. // // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your // option. This file may not be copied, modified, or distributed // except according to those terms.
//! Immutable strings.
pubuse core_foundation_sys::string::*;
usecrate::base::{CFIndexConvertible, TCFType};
use core_foundation_sys::base::{kCFAllocatorDefault, kCFAllocatorNull}; use core_foundation_sys::base::{Boolean, CFIndex, CFRange}; use std::borrow::Cow; use std::ffi::CStr; use std::fmt; use std::ptr; use std::str::{self, FromStr};
declare_TCFType! { /// An immutable string in one of a variety of encodings.
CFString, CFStringRef
}
impl_TCFType!(CFString, CFStringRef, CFStringGetTypeID);
impl FromStr for CFString { type Err = ();
/// See also [`CFString::new()`] for a variant of this which does not return a `Result`. #[inline] fn from_str(string: &str) -> Result<CFString, ()> {
Ok(CFString::new(string))
}
}
impl<'a> From<&'a CFString> for Cow<'a, str> { fn from(cf_str: &'a CFString) -> Cow<'a, str> { unsafe { // Do this without allocating if we can get away with it let c_string = CFStringGetCStringPtr(cf_str.0, kCFStringEncodingUTF8); if !c_string.is_null() { let c_str = CStr::from_ptr(c_string);
Cow::Borrowed(str::from_utf8_unchecked(c_str.to_bytes()))
} else { let char_len = cf_str.char_len();
// First, ask how big the buffer ought to be. letmut bytes_required: CFIndex = 0;
CFStringGetBytes(
cf_str.0,
CFRange {
location: 0,
length: char_len,
},
kCFStringEncodingUTF8, 0, falseas Boolean,
ptr::null_mut(), 0,
&mut bytes_required,
);
// Then, allocate the buffer and actually copy. letmut buffer = vec![b'\x00'; bytes_required as usize];
// This is dangerous; we over-allocate and null-terminate the string (during // initialization).
assert_eq!(bytes_used, buffer.len().to_CFIndex());
Cow::Owned(String::from_utf8_unchecked(buffer))
}
}
}
}
impl CFString { /// Creates a new `CFString` instance from a Rust string. #[inline] pubfn new(string: &str) -> CFString { unsafe { let string_ref = CFStringCreateWithBytes(
kCFAllocatorDefault,
string.as_ptr(),
string.len().to_CFIndex(),
kCFStringEncodingUTF8, falseas Boolean,
);
CFString::wrap_under_create_rule(string_ref)
}
}
/// Like `CFString::new`, but references a string that can be used as a backing store /// by virtue of being statically allocated. #[inline] pubfn from_static_string(string: &'static str) -> CFString { unsafe { let string_ref = CFStringCreateWithBytesNoCopy(
kCFAllocatorDefault,
string.as_ptr(),
string.len().to_CFIndex(),
kCFStringEncodingUTF8, falseas Boolean,
kCFAllocatorNull,
);
TCFType::wrap_under_create_rule(string_ref)
}
}
/// Returns the number of characters in the string. #[inline] pubfn char_len(&self) -> CFIndex { unsafe { CFStringGetLength(self.0) }
}
}
#[test] fn string_and_back() { let original = "The quick brown fox jumped over the slow lazy dog."; let cfstr = CFString::from_static_string(original); let converted = cfstr.to_string();
assert_eq!(converted, original);
}
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.27 Sekunden
(vorverarbeitet am 2026-06-20)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.