2 * Copyright (c) 2010-2012,2014 Apple Inc. All Rights Reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
21 * @APPLE_LICENSE_HEADER_END@
26 #include "SecCFRelease.h"
28 // NOTE: the return may or allocate a fair bit more space then it needs.
29 // Use it for short lived conversions (or strdup the result).
30 char *utf8(CFStringRef s
) {
31 CFIndex sz
= CFStringGetMaximumSizeForEncoding(CFStringGetLength(s
), kCFStringEncodingUTF8
) + 1;
33 UInt8
*buf
= (UInt8
*)malloc(sz
);
37 CFStringGetBytes(s
, CFRangeMake(0, CFStringGetLength(s
)), kCFStringEncodingUTF8
, '?', FALSE
, buf
, sz
, &used
);
43 void CFfprintf(FILE *f
, const char *format
, ...) {
47 CFStringRef fmt
= CFStringCreateWithCString(NULL
, format
, kCFStringEncodingUTF8
);
48 CFStringRef str
= CFStringCreateWithFormatAndArguments(NULL
, NULL
, fmt
, ap
);
52 CFIndex sz
= CFStringGetMaximumSizeForEncoding(CFStringGetLength(str
), kCFStringEncodingUTF8
);
56 bool needs_free
= false;
64 CFStringGetBytes(str
, CFRangeMake(0, CFStringGetLength(str
)), kCFStringEncodingUTF8
, '?', FALSE
, buf
, sz
, &used
);
66 buf
= (unsigned char *)"malloc failue during CFfprintf\n";
70 fwrite(buf
, 1, used
, f
);
78 CFErrorRef
fancy_error(CFStringRef domain
, CFIndex code
, CFStringRef description
) {
79 const void *v_ekey
= kCFErrorDescriptionKey
;
80 const void *v_description
= description
;
81 CFErrorRef err
= CFErrorCreateWithUserInfoKeysAndValues(NULL
, domain
, code
, &v_ekey
, &v_description
, 1);
88 void add_t2ca(CFMutableDictionaryRef t2ca
, CFStringRef t
, CFStringRef a
) {
89 CFMutableSetRef ca
= (CFMutableSetRef
)CFDictionaryGetValue(t2ca
, t
);
91 ca
= CFSetCreateMutable(NULL
, 0, &kCFCopyStringSetCallBacks
);
92 CFDictionarySetValue(t2ca
, t
, ca
);
97 void CFSafeRelease(CFTypeRef object
) {
99 CFReleaseNull(object
);
103 void graphviz(FILE *f
, SecTransformRef tr
) {
104 CFDictionaryRef d
= SecTransformCopyExternalRepresentation(tr
);
106 CFfprintf(f
, "digraph TR {\n\tnode [shape=plaintext];\n\n");
108 CFArrayRef transforms
= CFDictionaryGetValue(d
, CFSTR("TRANSFORMS"));
109 CFArrayRef connections
= CFDictionaryGetValue(d
, CFSTR("ARRAY"));
112 // map transforms to connected attributes
113 CFMutableDictionaryRef t2ca
= CFDictionaryCreateMutable(NULL
, 0, &kCFCopyStringDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
114 for(i
= 0; i
< CFArrayGetCount(connections
); i
++) {
115 CFDictionaryRef c
= CFArrayGetValueAtIndex(connections
, i
);
117 CFStringRef t_from
= CFDictionaryGetValue(c
, CFSTR("FROM_NAME"));
118 CFStringRef t_to
= CFDictionaryGetValue(c
, CFSTR("TO_NAME"));
119 CFStringRef a_from
= CFDictionaryGetValue(c
, CFSTR("FROM_ATTRIBUTE"));
120 CFStringRef a_to
= CFDictionaryGetValue(c
, CFSTR("TO_ATTRIBUTE"));
122 add_t2ca(t2ca
, t_from
, a_from
);
123 add_t2ca(t2ca
, t_to
, a_to
);
127 for(i
= 0; i
< CFArrayGetCount(transforms
); i
++) {
128 CFDictionaryRef t
= CFArrayGetValueAtIndex(transforms
, i
);
129 // NAME STATE(dict) TYPE
130 CFStringRef name
= CFDictionaryGetValue(t
, CFSTR("NAME"));
132 CFfprintf(f
, "\tsubgraph \"cluster_%@\"{\n", name
);
134 CFMutableSetRef ca
= (CFMutableSetRef
)CFDictionaryGetValue(t2ca
, name
);
136 CFIndex cnt
= CFSetGetCount(ca
);
137 CFStringRef
*attrs
= malloc(cnt
* sizeof(CFStringRef
));
138 CFSetGetValues(ca
, (const void **)attrs
);
140 for(j
= 0; j
< cnt
; j
++) {
141 CFfprintf(f
, "\t\t\"%@#%@\" [label=\"%@\"];\n", name
, attrs
[j
], attrs
[j
]);
143 CFfprintf(f
, "\t\t\"%@\" [fontcolor=blue, fontsize=20];\n\t}\n");
150 for(i
= 0; i
< CFArrayGetCount(connections
); i
++) {
151 CFDictionaryRef c
= CFArrayGetValueAtIndex(connections
, i
);
153 CFStringRef t_from
= CFDictionaryGetValue(c
, CFSTR("FROM_NAME"));
154 CFStringRef t_to
= CFDictionaryGetValue(c
, CFSTR("TO_NAME"));
155 CFStringRef a_from
= CFDictionaryGetValue(c
, CFSTR("FROM_ATTRIBUTE"));
156 CFStringRef a_to
= CFDictionaryGetValue(c
, CFSTR("TO_ATTRIBUTE"));
158 CFfprintf(f
, "\t\"%@#%@\" -> \"%@#%@\";\n", t_from
, a_from
, t_to
, a_to
);
163 CFfprintf(f
, "\n/*\n%@\n/*\n", d
);