1//
2//  SecCFWrappers.c
3//  utilities
4//
5//  Created by Michael Brouwer on 11/15/12.
6//  Copyright 2012 Apple Inc. All rights reserved.
7//
8
9#include <utilities/SecCFWrappers.h>
10
11void CFStringPerformWithCStringAndLength(CFStringRef inStr, void(^operation)(const char *utf8String, size_t utf8Length)) {
12    const char *cstr = CFStringGetCStringPtr(inStr, kCFStringEncodingUTF8);
13    if (cstr) {
14        operation(cstr, strlen(cstr));
15    } else {
16        CFIndex neededLen = 0;
17        CFRange range = { 0, CFStringGetLength(inStr) };
18        CFStringGetBytes(inStr, range, kCFStringEncodingUTF8,
19                         0, FALSE, NULL, 0, &neededLen);
20        CFIndex usedLen = 0;
21        if (neededLen < 4096) {
22            char buf[neededLen + 1];
23            CFStringGetBytes(inStr, range, kCFStringEncodingUTF8,
24                             0, FALSE, (UInt8 *)buf, neededLen, &usedLen);
25            assert(usedLen == neededLen);
26            buf[usedLen] = 0;
27            operation(buf, (size_t)usedLen);
28            //cc_zero(neededLen, buf);
29        } else {
30            char *buf = malloc(neededLen + 1);
31            CFStringGetBytes(inStr, range, kCFStringEncodingUTF8,
32                             0, FALSE, (UInt8 *)buf, neededLen, &usedLen);
33            assert(usedLen == neededLen);
34            buf[usedLen] = 0;
35            operation(buf, (size_t)usedLen);
36            //cc_zero(neededLen, buf);
37            free(buf);
38        }
39    }
40}
41
42void CFStringPerformWithCString(CFStringRef inStr, void(^operation)(const char *utf8String)) {
43    const char *cstr = CFStringGetCStringPtr(inStr, kCFStringEncodingUTF8);
44    if (cstr) {
45        operation(cstr);
46    } else {
47        CFIndex neededLen = 0;
48        CFRange range = { 0, CFStringGetLength(inStr) };
49        CFStringGetBytes(inStr, range, kCFStringEncodingUTF8,
50                         0, FALSE, NULL, 0, &neededLen);
51        CFIndex usedLen = 0;
52        if (neededLen < 4096) {
53            char buf[neededLen + 1];
54            CFStringGetBytes(inStr, range, kCFStringEncodingUTF8,
55                             0, FALSE, (UInt8 *)buf, neededLen, &usedLen);
56            assert(usedLen == neededLen);
57            buf[usedLen] = 0;
58            operation(buf);
59            //cc_zero(neededLen, buf);
60        } else {
61            char *buf = malloc(neededLen + 1);
62            CFStringGetBytes(inStr, range, kCFStringEncodingUTF8,
63                             0, FALSE, (UInt8 *)buf, neededLen, &usedLen);
64            assert(usedLen == neededLen);
65            buf[usedLen] = 0;
66            operation(buf);
67            //cc_zero(neededLen, buf);
68            free(buf);
69        }
70    }
71}
72