3 * libsecurity_transform
5 * Created by JOsborne on 3/14/10.
6 * Copyright 2010 Apple. All rights reserved.
13 // NOTE: the return may or allocate a fair bit more space then it needs.
14 // Use it for short lived conversions (or strdup the result).
15 char *utf8(CFStringRef s
) {
16 CFIndex sz
= CFStringGetMaximumSizeForEncoding(CFStringGetLength(s
), kCFStringEncodingUTF8
) + 1;
18 UInt8
*buf
= (UInt8
*)malloc(sz
);
22 CFStringGetBytes(s
, CFRangeMake(0, CFStringGetLength(s
)), kCFStringEncodingUTF8
, '?', FALSE
, buf
, sz
, &used
);
28 void CFfprintf(FILE *f
, const char *format
, ...) {
32 CFStringRef fmt
= CFStringCreateWithCString(NULL
, format
, kCFStringEncodingUTF8
);
33 CFStringRef str
= CFStringCreateWithFormatAndArguments(NULL
, NULL
, fmt
, ap
);
37 CFIndex sz
= CFStringGetMaximumSizeForEncoding(CFStringGetLength(str
), kCFStringEncodingUTF8
);
41 bool needs_free
= false;
49 CFStringGetBytes(str
, CFRangeMake(0, CFStringGetLength(str
)), kCFStringEncodingUTF8
, '?', FALSE
, buf
, sz
, &used
);
51 buf
= (unsigned char *)"malloc failue during CFfprintf\n";
54 fwrite(buf
, 1, used
, f
);
62 CFErrorRef
fancy_error(CFStringRef domain
, CFIndex code
, CFStringRef description
) {
63 const void *v_ekey
= kCFErrorDescriptionKey
;
64 const void *v_description
= description
;
65 CFErrorRef err
= CFErrorCreateWithUserInfoKeysAndValues(NULL
, domain
, code
, &v_ekey
, &v_description
, 1);
70 void add_t2ca(CFMutableDictionaryRef t2ca
, CFStringRef t
, CFStringRef a
) {
71 CFMutableSetRef ca
= (CFMutableSetRef
)CFDictionaryGetValue(t2ca
, t
);
73 ca
= CFSetCreateMutable(NULL
, 0, &kCFCopyStringSetCallBacks
);
74 CFDictionarySetValue(t2ca
, t
, ca
);
79 void CFSafeRelease(CFTypeRef object
) {
85 void graphviz(FILE *f
, SecTransformRef tr
) {
86 CFDictionaryRef d
= SecTransformCopyExternalRepresentation(tr
);
88 CFfprintf(f
, "digraph TR {\n\tnode [shape=plaintext];\n\n");
90 CFArrayRef transforms
= CFDictionaryGetValue(d
, CFSTR("TRANSFORMS"));
91 CFArrayRef connections
= CFDictionaryGetValue(d
, CFSTR("ARRAY"));
94 // map transforms to connected attributes
95 CFMutableDictionaryRef t2ca
= CFDictionaryCreateMutable(NULL
, 0, &kCFCopyStringDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
96 for(i
= 0; i
< CFArrayGetCount(connections
); i
++) {
97 CFDictionaryRef c
= CFArrayGetValueAtIndex(connections
, i
);
99 CFStringRef t_from
= CFDictionaryGetValue(c
, CFSTR("FROM_NAME"));
100 CFStringRef t_to
= CFDictionaryGetValue(c
, CFSTR("TO_NAME"));
101 CFStringRef a_from
= CFDictionaryGetValue(c
, CFSTR("FROM_ATTRIBUTE"));
102 CFStringRef a_to
= CFDictionaryGetValue(c
, CFSTR("TO_ATTRIBUTE"));
104 add_t2ca(t2ca
, t_from
, a_from
);
105 add_t2ca(t2ca
, t_to
, a_to
);
109 for(i
= 0; i
< CFArrayGetCount(transforms
); i
++) {
110 CFDictionaryRef t
= CFArrayGetValueAtIndex(transforms
, i
);
111 // NAME STATE(dict) TYPE
112 CFStringRef name
= CFDictionaryGetValue(t
, CFSTR("NAME"));
114 CFfprintf(f
, "\tsubgraph \"cluster_%@\"{\n", name
);
116 CFMutableSetRef ca
= (CFMutableSetRef
)CFDictionaryGetValue(t2ca
, name
);
118 CFIndex cnt
= CFSetGetCount(ca
);
119 CFStringRef
*attrs
= malloc(cnt
* sizeof(CFStringRef
));
120 CFSetGetValues(ca
, (const void **)attrs
);
122 for(j
= 0; j
< cnt
; j
++) {
123 CFfprintf(f
, "\t\t\"%@#%@\" [label=\"%@\"];\n", name
, attrs
[j
], attrs
[j
]);
125 CFfprintf(f
, "\t\t\"%@\" [fontcolor=blue, fontsize=20];\n\t}\n");
131 for(i
= 0; i
< CFArrayGetCount(connections
); i
++) {
132 CFDictionaryRef c
= CFArrayGetValueAtIndex(connections
, i
);
134 CFStringRef t_from
= CFDictionaryGetValue(c
, CFSTR("FROM_NAME"));
135 CFStringRef t_to
= CFDictionaryGetValue(c
, CFSTR("TO_NAME"));
136 CFStringRef a_from
= CFDictionaryGetValue(c
, CFSTR("FROM_ATTRIBUTE"));
137 CFStringRef a_to
= CFDictionaryGetValue(c
, CFSTR("TO_ATTRIBUTE"));
139 CFfprintf(f
, "\t\"%@#%@\" -> \"%@#%@\";\n", t_from
, a_from
, t_to
, a_to
);
144 CFfprintf(f
, "\n/*\n%@\n/*\n", d
);