blob: 1d024ffe7bd63dfae02e566ab85b1c4ea5efde62 [file] [log] [blame]
/*
* Copyright (c) 2012-2013 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 "internal.h"
#if DISPATCH_DATA_IS_BRIDGED_TO_NSDATA
#if _OS_OBJECT_OBJC_ARC
#error "Cannot build with ARC"
#endif
#include <Foundation/NSString.h>
// NOTE: this file must not contain any atomic operations
@interface DISPATCH_CLASS(data) () <DISPATCH_CLASS(data)>
@property (readonly,nonatomic) NSUInteger length;
@property (readonly,nonatomic) const void *bytes NS_RETURNS_INNER_POINTER;
- (id)initWithBytes:(void *)bytes length:(NSUInteger)length copy:(BOOL)copy
freeWhenDone:(BOOL)freeBytes bytesAreVM:(BOOL)vm;
- (BOOL)_bytesAreVM;
- (BOOL)_isCompact;
@end
@interface DISPATCH_CLASS(data_empty) : DISPATCH_CLASS(data)
@end
@implementation DISPATCH_CLASS(data)
+ (id)allocWithZone:(NSZone *) DISPATCH_UNUSED zone {
return _dispatch_objc_alloc(self, sizeof(struct dispatch_data_s));
}
- (id)init {
return [self initWithBytes:NULL length:0 copy:NO freeWhenDone:NO
bytesAreVM:NO];
}
- (id)initWithBytes:(void *)bytes length:(NSUInteger)length copy:(BOOL)copy
freeWhenDone:(BOOL)freeBytes bytesAreVM:(BOOL)vm {
dispatch_block_t destructor;
if (copy) {
destructor = DISPATCH_DATA_DESTRUCTOR_DEFAULT;
} else if (freeBytes) {
if (vm) {
destructor = DISPATCH_DATA_DESTRUCTOR_VM_DEALLOCATE;
} else {
destructor = DISPATCH_DATA_DESTRUCTOR_FREE;
}
} else {
destructor = DISPATCH_DATA_DESTRUCTOR_NONE;
}
_dispatch_data_init_with_bytes(self, bytes, length, destructor);
return self;
}
- (void)dealloc {
struct dispatch_data_s *dd = (void*)self;
_dispatch_data_dispose(self, NULL);
dispatch_queue_t tq = dd->do_targetq;
dispatch_function_t func = dd->finalizer;
void *ctxt = dd->ctxt;
[super dealloc];
if (func && ctxt) {
if (!tq) {
tq = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0);
}
dispatch_async_f(tq, ctxt, func);
}
if (tq) {
_os_object_release_internal((_os_object_t)tq);
}
}
- (BOOL)_bytesAreVM {
struct dispatch_data_s *dd = (void*)self;
return dd->destructor == DISPATCH_DATA_DESTRUCTOR_VM_DEALLOCATE;
}
- (void)_setContext:(void*)context {
struct dispatch_data_s *dd = (void*)self;
dd->ctxt = context;
}
- (void*)_getContext {
struct dispatch_data_s *dd = (void*)self;
return dd->ctxt;
}
- (void)_setFinalizer:(dispatch_function_t)finalizer {
struct dispatch_data_s *dd = (void*)self;
dd->finalizer = finalizer;
}
- (void)_setTargetQueue:(dispatch_queue_t)queue {
struct dispatch_data_s *dd = (void*)self;
return _dispatch_data_set_target_queue(dd, queue);
}
- (NSString *)debugDescription {
Class nsstring = objc_lookUpClass("NSString");
if (!nsstring) return nil;
char buf[2048];
_dispatch_data_debug(self, buf, sizeof(buf));
NSString *format = [nsstring stringWithUTF8String:"<%s: %s>"];
if (!format) return nil;
return [nsstring stringWithFormat:format, class_getName([self class]), buf];
}
- (NSUInteger)length {
struct dispatch_data_s *dd = (void*)self;
return dd->size;
}
- (const void *)bytes {
struct dispatch_data_s *dd = (void*)self;
return _dispatch_data_get_flattened_bytes(dd);
}
- (BOOL)_isCompact {
struct dispatch_data_s *dd = (void*)self;
return !dd->size || _dispatch_data_map_direct(dd, 0, NULL, NULL) != NULL;
}
- (void)_suspend {
}
- (void)_resume {
}
- (void)_activate {
}
@end
@implementation DISPATCH_CLASS(data_empty)
// Force non-lazy class realization rdar://10640168
+ (void)load {
}
- (id)retain {
return (id)self;
}
- (oneway void)release {
}
- (id)autorelease {
return (id)self;
}
- (NSUInteger)retainCount {
return ULONG_MAX;
}
+ (id)allocWithZone:(NSZone *) DISPATCH_UNUSED zone {
return (id)&_dispatch_data_empty;
}
- (void)_setContext:(void*) DISPATCH_UNUSED context {
}
- (void*)_getContext {
return NULL;
}
- (void)_setFinalizer:(dispatch_function_t) DISPATCH_UNUSED finalizer {
}
- (void)_setTargetQueue:(dispatch_queue_t) DISPATCH_UNUSED queue {
}
- (void)_suspend {
}
- (void)_resume {
}
- (void)_activate {
}
@end
#endif // USE_OBJC