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@ 
  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"; 
  69         fwrite(buf
, 1, used
, f
); 
  77 CFErrorRef 
fancy_error(CFStringRef domain
, CFIndex code
, CFStringRef description
) { 
  78         const void *v_ekey 
= kCFErrorDescriptionKey
; 
  79         const void *v_description 
= description
; 
  80         CFErrorRef err 
= CFErrorCreateWithUserInfoKeysAndValues(NULL
, domain
, code
, &v_ekey
, &v_description
, 1); 
  86 void add_t2ca(CFMutableDictionaryRef t2ca
, CFStringRef t
, CFStringRef a
) { 
  87         CFMutableSetRef ca 
= (CFMutableSetRef
)CFDictionaryGetValue(t2ca
, t
); 
  89                 ca 
= CFSetCreateMutable(NULL
, 0, &kCFCopyStringSetCallBacks
); 
  90                 CFDictionarySetValue(t2ca
, t
, ca
); 
  95 void CFSafeRelease(CFTypeRef object
) { 
 101 void graphviz(FILE *f
, SecTransformRef tr
) { 
 102         CFDictionaryRef d 
= SecTransformCopyExternalRepresentation(tr
); 
 104         CFfprintf(f
, "digraph TR {\n\tnode [shape=plaintext];\n\n"); 
 106         CFArrayRef transforms 
= CFDictionaryGetValue(d
, CFSTR("TRANSFORMS")); 
 107         CFArrayRef connections 
= CFDictionaryGetValue(d
, CFSTR("ARRAY")); 
 110         // map transforms to connected attributes 
 111         CFMutableDictionaryRef t2ca 
= CFDictionaryCreateMutable(NULL
, 0, &kCFCopyStringDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
); 
 112         for(i 
= 0; i 
< CFArrayGetCount(connections
); i
++) { 
 113                 CFDictionaryRef c 
= CFArrayGetValueAtIndex(connections
, i
); 
 115                 CFStringRef t_from 
= CFDictionaryGetValue(c
, CFSTR("FROM_NAME")); 
 116                 CFStringRef t_to 
= CFDictionaryGetValue(c
, CFSTR("TO_NAME")); 
 117                 CFStringRef a_from 
= CFDictionaryGetValue(c
, CFSTR("FROM_ATTRIBUTE")); 
 118                 CFStringRef a_to 
= CFDictionaryGetValue(c
, CFSTR("TO_ATTRIBUTE")); 
 120                 add_t2ca(t2ca
, t_from
, a_from
); 
 121                 add_t2ca(t2ca
, t_to
, a_to
); 
 125         for(i 
= 0; i 
< CFArrayGetCount(transforms
); i
++) { 
 126                 CFDictionaryRef t 
= CFArrayGetValueAtIndex(transforms
, i
); 
 127                 // NAME STATE(dict) TYPE 
 128                 CFStringRef name 
= CFDictionaryGetValue(t
, CFSTR("NAME"));               
 130                 CFfprintf(f
, "\tsubgraph \"cluster_%@\"{\n", name
); 
 132                 CFMutableSetRef ca 
= (CFMutableSetRef
)CFDictionaryGetValue(t2ca
, name
); 
 134                         CFIndex cnt 
= CFSetGetCount(ca
); 
 135                         CFStringRef 
*attrs 
= malloc(cnt 
* sizeof(CFStringRef
)); 
 136                         CFSetGetValues(ca
, (const void **)attrs
); 
 138                         for(j 
= 0; j 
< cnt
; j
++) { 
 139                                 CFfprintf(f
, "\t\t\"%@#%@\" [label=\"%@\"];\n", name
, attrs
[j
], attrs
[j
]); 
 141                         CFfprintf(f
, "\t\t\"%@\" [fontcolor=blue, fontsize=20];\n\t}\n"); 
 147         for(i 
= 0; i 
< CFArrayGetCount(connections
); i
++) { 
 148                 CFDictionaryRef c 
= CFArrayGetValueAtIndex(connections
, i
); 
 150                 CFStringRef t_from 
= CFDictionaryGetValue(c
, CFSTR("FROM_NAME")); 
 151                 CFStringRef t_to 
= CFDictionaryGetValue(c
, CFSTR("TO_NAME")); 
 152                 CFStringRef a_from 
= CFDictionaryGetValue(c
, CFSTR("FROM_ATTRIBUTE")); 
 153                 CFStringRef a_to 
= CFDictionaryGetValue(c
, CFSTR("TO_ATTRIBUTE")); 
 155                 CFfprintf(f
, "\t\"%@#%@\" -> \"%@#%@\";\n", t_from
, a_from
, t_to
, a_to
); 
 160         CFfprintf(f
, "\n/*\n%@\n/*\n", d
);