Implement ToStr for CFString; fix off-by-one error in CFString::new_static; make clean now removes test binary.

This commit is contained in:
Brian J. Burg
2012-11-07 19:47:22 -08:00
parent a7eade7fc2
commit 22ff767266
3 changed files with 52 additions and 7 deletions
+1 -1
View File
@@ -19,5 +19,5 @@ check: rustcorefoundation-test
./rustcorefoundation-test
clean:
rm -f *.o *.a *.so *.dylib *.dll *.dummy
rm -f *.o *.a *.so *.dylib *.dll *.dummy rustcorefoundation-test
+4 -3
View File
@@ -9,6 +9,10 @@ pub struct CFRange {
length: CFIndex
}
fn CFRangeMake(off: CFIndex, len: CFIndex) -> CFRange {
CFRange { location: off, length: len }
}
struct __CFAllocator { private: () }
pub type CFAllocatorRef = *__CFAllocator;
@@ -138,7 +142,4 @@ extern {
/* Base Utilities Reference */
// N.B. Some things missing here.
//fn CFRangeMake
}
+47 -3
View File
@@ -5,6 +5,8 @@ use base::{
CFAllocatorRef,
CFIndex,
CFOptionFlags,
CFRange,
CFRangeMake,
CFRelease,
CFTypeRef,
CFTypeID,
@@ -234,7 +236,7 @@ pub impl CFString {
let string_ref = do str::as_buf(string) |bytes, len| {
CFStringCreateWithBytesNoCopy(kCFAllocatorDefault,
bytes,
len as CFIndex,
(len-1) as CFIndex, // does NOT want trailing NUL
kCFStringEncodingUTF8,
false as Boolean,
kCFAllocatorNull)
@@ -243,6 +245,39 @@ pub impl CFString {
}
}
pub impl CFString {
pub pure fn char_len() -> uint unsafe {
CFStringGetLength(self.obj) as uint
}
}
pub impl CFString : ToStr {
pure fn to_str() -> ~str unsafe {
let char_len = self.char_len();
let range : CFRange = CFRangeMake(0 as CFIndex, char_len as CFIndex);
let encoding = kCFStringEncodingUTF8;
let mut bytes_required: CFIndex = 0 as CFIndex;
// first, ask how big the buffer ought to be.
CFStringGetBytes(self.obj, range, encoding, 0, false as Boolean,
ptr::null(), 0, ptr::to_unsafe_ptr(&bytes_required));
let buffer : ~[u8] = vec::from_elem(1+bytes_required as uint, '\x00' as u8);
let mut bytes_used: CFIndex = 0 as CFIndex;
// then, allocate the buffer and actually copy.
let chars_written = CFStringGetBytes(self.obj, range, encoding, 0, false as Boolean,
vec::raw::to_ptr(buffer), buffer.len() as CFIndex,
ptr::to_unsafe_ptr(&bytes_used)) as uint;
assert chars_written == char_len;
// this is dangerous; we over-allocate and nul-terminate the string (during initialization)
assert bytes_used + 1 == buffer.len() as CFIndex;
// then, reinterpret it as as string. you have been warned!
let casted_str : ~str = cast::transmute(move buffer);
// sanity check.
return move casted_str;
}
}
#[link_args="-framework CoreFoundation"]
#[nolink]
extern {
@@ -293,14 +328,16 @@ extern {
/* Accessing Characters */
//fn CFStringCreateExternalRepresentation
//fn CFStringGetBytes
fn CFStringGetBytes(theString: CFStringRef, ++range: CFRange, encoding: CFStringEncoding,
lossByte: u8, isExternalRepresentation: Boolean,
buffer: *u8, maxBufLen: CFIndex, usedBufLen: *CFIndex) -> CFIndex;
//fn CFStringGetCharacterAtIndex
//fn CFStringGetCharacters
//fn CFStringGetCharactersPtr
//fn CFStringGetCharacterFromInlineBuffer
//fn CFStringGetCString
//fn CFStringGetCStringPtr
//fn CFStringGetLength
fn CFStringGetLength(theString: CFStringRef) -> CFIndex;
//fn CFStringGetPascalString
//fn CFStringGetPascalStringPtr
//fn CFStringGetRangeOfComposedCharactersAtIndex
@@ -349,3 +386,10 @@ extern {
//fn CFStringIsSurrogateLowCharacter
}
#[test]
fn string_and_back() {
let original = "The quick brown fox jumped over the slow lazy dog.";
let cfstr = CFString::new_static(original);
let converted = cfstr.to_str();
assert original == converted;
}