/* * Copyright (c) 2011-2012 Apple Inc. All rights reserved. * * @APPLE_APACHE_LICENSE_HEADER_START@ * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @APPLE_APACHE_LICENSE_HEADER_END@ */ #include #if DISPATCH_API_VERSION >= 20111008 && !TARGET_OS_EMBEDDED #include #include #include #include #define printf_data(p, s) ({ \ __typeof__(s) _i; \ for (_i=0; _i UTF16LE)", transformed); dispatch_release(utf8_data); (void)context; } void truncated_utf8_test(void * context) { dispatch_data_t utf8_data = dispatch_data_create(utf8, sizeof(utf8) - 3, NULL, ^{}); dispatch_data_t transformed = dispatch_data_create_with_transform(utf8_data, DISPATCH_DATA_FORMAT_TYPE_UTF8, DISPATCH_DATA_FORMAT_TYPE_UTF16LE); test_ptr_null("dispatch_data_create_with_transform (UTF8 (truncated) -> UTF16LE)", transformed); dispatch_release(utf8_data); dispatch_group_async_f(context, dispatch_get_main_queue(), context, invalid_utf8_test); } void invalid_utf16le_surrogate_test(void * context) { dispatch_data_t utf8_data = dispatch_data_create(utf8, sizeof(utf8), NULL, ^{}); dispatch_data_t utf16_data = dispatch_data_create(utf16le_invalid, sizeof(utf16le_invalid), NULL, ^{}); dispatch_data_t transformed = dispatch_data_create_with_transform(utf16_data, DISPATCH_DATA_FORMAT_TYPE_UTF16LE, DISPATCH_DATA_FORMAT_TYPE_UTF8); test_ptr_null("dispatch_data_create_with_transform (UTF16LE (missing surrogate) -> UTF8)", transformed); dispatch_release(utf16_data); dispatch_release(utf8_data); dispatch_group_async_f(context, dispatch_get_main_queue(), context, truncated_utf8_test); } void invalid_utf16le_test(void * context) { dispatch_data_t utf8_data = dispatch_data_create(utf8, sizeof(utf8), NULL, ^{}); dispatch_data_t utf16_data = dispatch_data_create(utf16, (sizeof(utf16) % 2) + 1, NULL, ^{}); dispatch_data_t transformed = dispatch_data_create_with_transform(utf16_data, DISPATCH_DATA_FORMAT_TYPE_UTF16LE, DISPATCH_DATA_FORMAT_TYPE_UTF8); test_ptr_null("dispatch_data_create_with_transform (UTF16LE (invalid) -> UTF8)", transformed); dispatch_release(utf16_data); dispatch_release(utf8_data); dispatch_group_async_f(context, dispatch_get_main_queue(), context, invalid_utf16le_surrogate_test); } void utf16le_bytes_to_utf8_test(void * context) { dispatch_data_t utf16_data = dispatch_data_empty; dispatch_data_t utf8_data = dispatch_data_create(utf8, sizeof(utf8), NULL, ^{}); size_t i; for (i=0; i UTF8)", transformed); test_data_equal("utf16le_bytes_to_utf8_test", transformed, utf8_data); dispatch_release(transformed); dispatch_release(utf8_data); dispatch_release(utf16_data); dispatch_group_async_f(context, dispatch_get_main_queue(), context, invalid_utf16le_test); } void utf8_bytes_to_utf16le_test(void * context) { dispatch_data_t utf8_data = dispatch_data_empty; dispatch_data_t utf16_data = dispatch_data_create(utf16, sizeof(utf16), NULL, ^{}); size_t i; for (i=0; i UTF16LE)", transformed); test_data_equal("utf8_bytes_to_utf16le_test", transformed, utf16_data); dispatch_release(transformed); dispatch_release(utf8_data); dispatch_release(utf16_data); dispatch_group_async_f(context, dispatch_get_main_queue(), context, utf16le_bytes_to_utf8_test); } void utf16be_detect_to_utf16le_test(void * context) { dispatch_data_t utf16be_data = dispatch_data_create(utf16be, sizeof(utf16be), NULL, ^{}); dispatch_data_t utf16_data = dispatch_data_create(utf16, sizeof(utf16), NULL, ^{}); dispatch_data_t transformed = dispatch_data_create_with_transform(utf16be_data, DISPATCH_DATA_FORMAT_TYPE_UTF_ANY, DISPATCH_DATA_FORMAT_TYPE_UTF16LE); test_ptr_notnull("dispatch_data_create_with_transform (UTF16BE (any) -> UTF16LE)", transformed); test_data_equal("utf16be_detect_to_utf16le_test", transformed, utf16_data); dispatch_release(transformed); dispatch_release(utf16be_data); dispatch_release(utf16_data); dispatch_group_async_f(context, dispatch_get_main_queue(), context, utf8_bytes_to_utf16le_test); } void utf16be_detect_to_utf8_test(void * context) { dispatch_data_t utf8_data = dispatch_data_create(utf8, sizeof(utf8), NULL, ^{}); dispatch_data_t utf16_data = dispatch_data_create(utf16be, sizeof(utf16be), NULL, ^{}); dispatch_data_t transformed = dispatch_data_create_with_transform(utf16_data, DISPATCH_DATA_FORMAT_TYPE_UTF_ANY, DISPATCH_DATA_FORMAT_TYPE_UTF8); test_ptr_notnull("dispatch_data_create_with_transform (UTF16BE (any) -> UTF8)", transformed); test_data_equal("utf16be_detect_to_utf8_test", transformed, utf8_data); dispatch_release(transformed); dispatch_release(utf16_data); dispatch_release(utf8_data); dispatch_group_async_f(context, dispatch_get_main_queue(), context, utf16be_detect_to_utf16le_test); } void utf16le_detect_to_utf8_test(void * context) { dispatch_data_t utf8_data = dispatch_data_create(utf8, sizeof(utf8), NULL, ^{}); dispatch_data_t utf16_data = dispatch_data_create(utf16, sizeof(utf16), NULL, ^{}); dispatch_data_t transformed = dispatch_data_create_with_transform(utf16_data, DISPATCH_DATA_FORMAT_TYPE_UTF_ANY, DISPATCH_DATA_FORMAT_TYPE_UTF8); test_ptr_notnull("dispatch_data_create_with_transform (UTF16LE (any) -> UTF8)", transformed); test_data_equal("utf16le_detect_to_utf8_test", transformed, utf8_data); dispatch_release(transformed); dispatch_release(utf16_data); dispatch_release(utf8_data); dispatch_group_async_f(context, dispatch_get_main_queue(), context, utf16be_detect_to_utf8_test); } void utf16be_to_utf8_test(void * context) { dispatch_data_t utf8_data = dispatch_data_create(utf8, sizeof(utf8), NULL, ^{}); dispatch_data_t utf16_data = dispatch_data_create(utf16be, sizeof(utf16be), NULL, ^{}); dispatch_data_t transformed = dispatch_data_create_with_transform(utf16_data, DISPATCH_DATA_FORMAT_TYPE_UTF16BE, DISPATCH_DATA_FORMAT_TYPE_UTF8); test_ptr_notnull("dispatch_data_create_with_transform (UTF16BE -> UTF8)", transformed); test_data_equal("utf16be_to_utf8_test", transformed, utf8_data); dispatch_release(transformed); dispatch_release(utf16_data); dispatch_release(utf8_data); dispatch_group_async_f(context, dispatch_get_main_queue(), context, utf16le_detect_to_utf8_test); } void utf16le_to_utf8_test(void * context) { dispatch_data_t utf8_data = dispatch_data_create(utf8, sizeof(utf8), NULL, ^{}); dispatch_data_t utf16_data = dispatch_data_create(utf16, sizeof(utf16), NULL, ^{}); dispatch_data_t transformed = dispatch_data_create_with_transform(utf16_data, DISPATCH_DATA_FORMAT_TYPE_UTF16LE, DISPATCH_DATA_FORMAT_TYPE_UTF8); test_ptr_notnull("dispatch_data_create_with_transform (UTF16LE -> UTF8)", transformed); test_data_equal("utf16le_to_utf8_test", transformed, utf8_data); dispatch_release(transformed); dispatch_release(utf16_data); dispatch_release(utf8_data); dispatch_group_async_f(context, dispatch_get_main_queue(), context, utf16be_to_utf8_test); } void utf8_to_utf16be_test(void * context) { dispatch_data_t utf8_data = dispatch_data_create(utf8, sizeof(utf8), NULL, ^{}); dispatch_data_t utf16_data = dispatch_data_create(utf16be, sizeof(utf16be), NULL, ^{}); dispatch_data_t transformed = dispatch_data_create_with_transform(utf8_data, DISPATCH_DATA_FORMAT_TYPE_UTF8, DISPATCH_DATA_FORMAT_TYPE_UTF16BE); test_ptr_notnull("dispatch_data_create_with_transform (UTF8 -> UTF16BE)", transformed); test_data_equal("utf8_to_utf16be_test", transformed, utf16_data); dispatch_release(transformed); dispatch_release(utf16_data); dispatch_release(utf8_data); dispatch_group_async_f(context, dispatch_get_main_queue(), context, utf16le_to_utf8_test); } void utf8_to_utf16le_test(void * context) { dispatch_data_t utf8_data = dispatch_data_create(utf8, sizeof(utf8), NULL, ^{}); dispatch_data_t utf16_data = dispatch_data_create(utf16, sizeof(utf16), NULL, ^{}); dispatch_data_t transformed = dispatch_data_create_with_transform(utf8_data, DISPATCH_DATA_FORMAT_TYPE_UTF8, DISPATCH_DATA_FORMAT_TYPE_UTF16LE); test_ptr_notnull("dispatch_data_create_with_transform (UTF8 -> UTF16LE)", transformed); test_data_equal("utf8_to_utf16le_test", transformed, utf16_data); dispatch_release(transformed); dispatch_release(utf16_data); dispatch_release(utf8_data); dispatch_group_async_f(context, dispatch_get_main_queue(), context, utf8_to_utf16be_test); } #pragma mark - base32 tests void decode32_corrupt_test(void * context) { dispatch_group_enter((dispatch_group_t)context); int fd = open("/dev/random", O_RDONLY); assert(fd >= 0); dispatch_read(fd, 4096, dispatch_get_main_queue(), ^(dispatch_data_t data, int error) { assert(error == 0); SecTransformRef transformRef = SecEncodeTransformCreate(kSecBase32Encoding, NULL); assert(transformRef); dispatch_data_t sectransform_data = execute_sectransform(transformRef, data); assert(sectransform_data); CFRelease(transformRef); void * corrupt_buffer = malloc(dispatch_data_get_size(sectransform_data)); const void * source; size_t size; dispatch_data_t map = dispatch_data_create_map(sectransform_data, &source, &size); memcpy(corrupt_buffer, source, size); size_t i; for (i=0; i= 'A' && x <= 'Z') || (x >= 'a' && x <= 'z') || (x >= '0' && x <= '9') || x == '/' || x == '+' || x == '=') { x = arc4random() & 0xff; } ((char*)corrupt_buffer)[i] = x; } dispatch_release(map); dispatch_release(sectransform_data); dispatch_data_t corrupt_data = dispatch_data_create(corrupt_buffer, size, dispatch_get_main_queue(), DISPATCH_DATA_DESTRUCTOR_FREE); dispatch_data_t transform_data = dispatch_data_create_with_transform(corrupt_data, DISPATCH_DATA_FORMAT_TYPE_BASE32, DISPATCH_DATA_FORMAT_TYPE_NONE); test_ptr_null("decode32_corrupt_test: dispatch_data_create_with_transform", transform_data); dispatch_release(corrupt_data); close(fd); dispatch_group_async_f(context, dispatch_get_main_queue(), context, utf8_to_utf16le_test); dispatch_group_leave((dispatch_group_t)context); }); } void chunking_decode32_test(void * context) { (void)context; int fd = open("/dev/random", O_RDONLY); assert(fd >= 0); dispatch_data_t __block data = dispatch_data_empty; int i; dispatch_group_t group = dispatch_group_create(); dispatch_queue_t queue = dispatch_queue_create("read", 0); for (i=0; i<4096; i++) { dispatch_group_enter(group); dispatch_read(fd, 1, queue, ^(dispatch_data_t d, int error) { assert(error == 0); dispatch_data_t concat = dispatch_data_create_concat(data, d); dispatch_release(data); data = concat; dispatch_group_leave(group); }); } dispatch_group_wait(group, DISPATCH_TIME_FOREVER); dispatch_release(queue); dispatch_release(group); SecTransformRef transformRef = SecEncodeTransformCreate(kSecBase32Encoding, NULL); assert(transformRef); dispatch_data_t sectransform_data = execute_sectransform(transformRef, data); assert(sectransform_data); CFRelease(transformRef); dispatch_data_t transformed_data = dispatch_data_create_with_transform(sectransform_data, DISPATCH_DATA_FORMAT_TYPE_BASE32, DISPATCH_DATA_FORMAT_TYPE_NONE); test_ptr_notnull("chunking_decode32_test: dispatch_data_create_with_transform", transformed_data); test_data_equal("chunking_decode32_test", transformed_data, data); dispatch_release(sectransform_data); dispatch_release(transformed_data); dispatch_release(data); close(fd); dispatch_group_async_f(context, dispatch_get_main_queue(), context, decode32_corrupt_test); } void chunking_encode32_test(void * context) { (void)context; int fd = open("/dev/random", O_RDONLY); assert(fd >= 0); dispatch_data_t __block data = dispatch_data_empty; int i; dispatch_group_t group = dispatch_group_create(); dispatch_queue_t queue = dispatch_queue_create("read", 0); for (i=0; i<4096; i++) { dispatch_group_enter(group); dispatch_read(fd, 1, queue, ^(dispatch_data_t d, int error) { assert(error == 0); dispatch_data_t concat = dispatch_data_create_concat(data, d); dispatch_release(data); data = concat; dispatch_group_leave(group); }); } dispatch_group_wait(group, DISPATCH_TIME_FOREVER); dispatch_release(queue); dispatch_release(group); SecTransformRef transformRef = SecEncodeTransformCreate(kSecBase32Encoding, NULL); assert(transformRef); dispatch_data_t sectransform_data = execute_sectransform(transformRef, data); assert(sectransform_data); CFRelease(transformRef); dispatch_data_t transformed_data = dispatch_data_create_with_transform(data, DISPATCH_DATA_FORMAT_TYPE_NONE, DISPATCH_DATA_FORMAT_TYPE_BASE32); test_ptr_notnull("chunking_encode32_test: dispatch_data_create_with_transform", transformed_data); test_data_equal("chunking_encode32_test", transformed_data, sectransform_data); dispatch_release(sectransform_data); dispatch_release(transformed_data); dispatch_release(data); close(fd); dispatch_group_async_f(context, dispatch_get_main_queue(), context, chunking_decode32_test); } void decode32_test(void * context) { dispatch_group_enter((dispatch_group_t)context); int fd = open("/dev/random", O_RDONLY); assert(fd >= 0); dispatch_read(fd, 4096, dispatch_get_main_queue(), ^(dispatch_data_t data, int error) { assert(error == 0); SecTransformRef transformRef = SecEncodeTransformCreate(kSecBase32Encoding, NULL); assert(transformRef); dispatch_data_t sectransform_data = execute_sectransform(transformRef, data); assert(sectransform_data); CFRelease(transformRef); dispatch_data_t transform_data = dispatch_data_create_with_transform(sectransform_data, DISPATCH_DATA_FORMAT_TYPE_BASE32, DISPATCH_DATA_FORMAT_TYPE_NONE); test_ptr_notnull("decode32_test: dispatch_data_create_with_transform", transform_data); test_data_equal("decode32_test", transform_data, data); dispatch_release(sectransform_data); dispatch_release(transform_data); close(fd); dispatch_group_async_f((dispatch_group_t)context, dispatch_get_main_queue(), context, chunking_encode32_test); dispatch_group_leave((dispatch_group_t)context); }); } void encode32_test(void * context) { dispatch_group_enter((dispatch_group_t)context); int fd = open("/dev/random", O_RDONLY); assert(fd >= 0); dispatch_read(fd, 4096, dispatch_get_main_queue(), ^(dispatch_data_t data, int error) { assert(error == 0); SecTransformRef transformRef = SecEncodeTransformCreate(kSecBase32Encoding, NULL); assert(transformRef); dispatch_data_t sectransform_data = execute_sectransform(transformRef, data); assert(sectransform_data); CFRelease(transformRef); dispatch_data_t transformed_data = dispatch_data_create_with_transform(data, DISPATCH_DATA_FORMAT_TYPE_NONE, DISPATCH_DATA_FORMAT_TYPE_BASE32); test_ptr_notnull("encode32_test: dispatch_data_create_with_transform", transformed_data); test_data_equal("encode32_test", transformed_data, sectransform_data); dispatch_release(sectransform_data); dispatch_release(transformed_data); close(fd); dispatch_group_async_f((dispatch_group_t)context, dispatch_get_main_queue(), context, decode32_test); dispatch_group_leave((dispatch_group_t)context); }); } #pragma mark - base64 tests void decode64_loop_test(void * context) { if (getenv("LOOP_SKIP") == NULL) { int fd = open("/dev/random", O_RDONLY); assert(fd >= 0); dispatch_semaphore_t sema = dispatch_semaphore_create(0); size_t i, __block tests = 0; for (i=1; i<4097; i++) { dispatch_read(fd, i, dispatch_get_global_queue(0, 0), ^(dispatch_data_t data, int error) { assert(error == 0); SecTransformRef transformRef = SecEncodeTransformCreate(kSecBase64Encoding, NULL); assert(transformRef); dispatch_data_t sectransform_data = execute_sectransform(transformRef, data); assert(sectransform_data); CFRelease(transformRef); dispatch_data_t transform_data = dispatch_data_create_with_transform(sectransform_data, DISPATCH_DATA_FORMAT_TYPE_BASE64, DISPATCH_DATA_FORMAT_TYPE_NONE); if (dispatch_data_equal(transform_data, data)) { tests++; } dispatch_release(sectransform_data); dispatch_release(transform_data); dispatch_semaphore_signal(sema); }); dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER); } dispatch_release(sema); close(fd); test_long("decode64_loop_test", tests, 4096); } dispatch_group_async_f((dispatch_group_t)context, dispatch_get_main_queue(), context, encode32_test); } void decode64_corrupt_test(void * context) { dispatch_group_enter((dispatch_group_t)context); int fd = open("/dev/random", O_RDONLY); assert(fd >= 0); dispatch_read(fd, 4096, dispatch_get_main_queue(), ^(dispatch_data_t data, int error) { assert(error == 0); SecTransformRef transformRef = SecEncodeTransformCreate(kSecBase64Encoding, NULL); assert(transformRef); dispatch_data_t sectransform_data = execute_sectransform(transformRef, data); assert(sectransform_data); CFRelease(transformRef); void * corrupt_buffer = malloc(dispatch_data_get_size(sectransform_data)); const void * source; size_t size; dispatch_data_t map = dispatch_data_create_map(sectransform_data, &source, &size); memcpy(corrupt_buffer, source, size); size_t i; for (i=0; i= 'A' && x <= 'Z') || (x >= 'a' && x <= 'z') || (x >= '0' && x <= '9') || x == '/' || x == '+' || x == '=') { x = arc4random() & 0xff; } ((char*)corrupt_buffer)[i] = x; } dispatch_release(map); dispatch_release(sectransform_data); dispatch_data_t corrupt_data = dispatch_data_create(corrupt_buffer, size, dispatch_get_main_queue(), DISPATCH_DATA_DESTRUCTOR_FREE); dispatch_data_t transform_data = dispatch_data_create_with_transform(corrupt_data, DISPATCH_DATA_FORMAT_TYPE_BASE64, DISPATCH_DATA_FORMAT_TYPE_NONE); test_ptr_null("decode64_corrupt_test: dispatch_data_create_with_transform", transform_data); dispatch_release(corrupt_data); close(fd); dispatch_group_async_f((dispatch_group_t)context, dispatch_get_main_queue(), context, decode64_loop_test); dispatch_group_leave((dispatch_group_t)context); }); } void chunking_decode64_test(void * context) { (void)context; int fd = open("/dev/random", O_RDONLY); assert(fd >= 0); dispatch_data_t __block data = dispatch_data_empty; int i; dispatch_group_t group = dispatch_group_create(); dispatch_queue_t queue = dispatch_queue_create("read", 0); for (i=0; i<4096; i++) { dispatch_group_enter(group); dispatch_read(fd, 1, queue, ^(dispatch_data_t d, int error) { assert(error == 0); dispatch_data_t concat = dispatch_data_create_concat(data, d); dispatch_release(data); data = concat; dispatch_group_leave(group); }); } dispatch_group_wait(group, DISPATCH_TIME_FOREVER); dispatch_release(queue); dispatch_release(group); SecTransformRef transformRef = SecEncodeTransformCreate(kSecBase64Encoding, NULL); assert(transformRef); dispatch_data_t sectransform_data = execute_sectransform(transformRef, data); assert(sectransform_data); CFRelease(transformRef); dispatch_data_t transformed_data = dispatch_data_create_with_transform(sectransform_data, DISPATCH_DATA_FORMAT_TYPE_BASE64, DISPATCH_DATA_FORMAT_TYPE_NONE); test_ptr_notnull("chunking_decode64_test: dispatch_data_create_with_transform", transformed_data); test_data_equal("chunking_decode64_test", transformed_data, data); dispatch_release(sectransform_data); dispatch_release(transformed_data); dispatch_release(data); close(fd); dispatch_group_async_f(context, dispatch_get_main_queue(), context, decode64_corrupt_test); } void chunking_encode64_test(void * context) { (void)context; int fd = open("/dev/random", O_RDONLY); assert(fd >= 0); dispatch_data_t __block data = dispatch_data_empty; int i; dispatch_group_t group = dispatch_group_create(); dispatch_queue_t queue = dispatch_queue_create("read", 0); for (i=0; i<4097; i++) { dispatch_group_enter(group); dispatch_read(fd, 1, queue, ^(dispatch_data_t d, int error) { assert(error == 0); dispatch_data_t concat = dispatch_data_create_concat(data, d); dispatch_release(data); data = concat; dispatch_group_leave(group); }); } dispatch_group_wait(group, DISPATCH_TIME_FOREVER); dispatch_release(queue); dispatch_release(group); SecTransformRef transformRef = SecEncodeTransformCreate(kSecBase64Encoding, NULL); assert(transformRef); dispatch_data_t sectransform_data = execute_sectransform(transformRef, data); assert(sectransform_data); CFRelease(transformRef); dispatch_data_t transformed_data = dispatch_data_create_with_transform(data, DISPATCH_DATA_FORMAT_TYPE_NONE, DISPATCH_DATA_FORMAT_TYPE_BASE64); test_ptr_notnull("chunking_encode64_test: dispatch_data_create_with_transform", transformed_data); test_data_equal("chunking_encode64_test", transformed_data, sectransform_data); dispatch_release(sectransform_data); dispatch_release(transformed_data); dispatch_release(data); close(fd); dispatch_group_async_f(context, dispatch_get_main_queue(), context, chunking_decode64_test); } void decode64_test(void * context) { dispatch_group_enter((dispatch_group_t)context); int fd = open("/dev/random", O_RDONLY); assert(fd >= 0); dispatch_read(fd, 4096, dispatch_get_main_queue(), ^(dispatch_data_t data, int error) { assert(error == 0); SecTransformRef transformRef = SecEncodeTransformCreate(kSecBase64Encoding, NULL); assert(transformRef); dispatch_data_t sectransform_data = execute_sectransform(transformRef, data); assert(sectransform_data); CFRelease(transformRef); dispatch_data_t transform_data = dispatch_data_create_with_transform(sectransform_data, DISPATCH_DATA_FORMAT_TYPE_BASE64, DISPATCH_DATA_FORMAT_TYPE_NONE); test_ptr_notnull("decode64_test: dispatch_data_create_with_transform", transform_data); test_data_equal("decode64_test", transform_data, data); dispatch_release(sectransform_data); dispatch_release(transform_data); close(fd); dispatch_group_async_f((dispatch_group_t)context, dispatch_get_main_queue(), context, chunking_encode64_test); dispatch_group_leave((dispatch_group_t)context); }); } void encode64_test(void * context) { dispatch_group_enter((dispatch_group_t)context); int fd = open("/dev/random", O_RDONLY); assert(fd >= 0); dispatch_read(fd, 4096, dispatch_get_main_queue(), ^(dispatch_data_t data, int error) { assert(error == 0); SecTransformRef transformRef = SecEncodeTransformCreate(kSecBase64Encoding, NULL); assert(transformRef); dispatch_data_t sectransform_data = execute_sectransform(transformRef, data); assert(sectransform_data); CFRelease(transformRef); dispatch_data_t transformed_data = dispatch_data_create_with_transform(data, DISPATCH_DATA_FORMAT_TYPE_NONE, DISPATCH_DATA_FORMAT_TYPE_BASE64); test_ptr_notnull("encode64_test: dispatch_data_create_with_transform", transformed_data); test_data_equal("encode64_test", transformed_data, sectransform_data); dispatch_release(sectransform_data); dispatch_release(transformed_data); close(fd); dispatch_group_async_f((dispatch_group_t)context, dispatch_get_main_queue(), context, decode64_test); dispatch_group_leave((dispatch_group_t)context); }); } #pragma mark - main int main(void) { test_start("Dispatch data transforms test"); dispatch_group_t group = dispatch_group_create(); dispatch_group_async_f(group, dispatch_get_main_queue(), group, encode64_test); dispatch_group_notify(group, dispatch_get_main_queue(), ^{ dispatch_release(group); test_stop(); exit(0); }); dispatch_main(); return 0; } #else int main(void) { test_skip("Dispatch data transforms test"); return 0; } #endif