]> git.saurik.com Git - apple/libdispatch.git/blob - src/data.m
libdispatch-913.1.6.tar.gz
[apple/libdispatch.git] / src / data.m
1 /*
2 * Copyright (c) 2012-2013 Apple Inc. All rights reserved.
3 *
4 * @APPLE_APACHE_LICENSE_HEADER_START@
5 *
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 *
18 * @APPLE_APACHE_LICENSE_HEADER_END@
19 */
20
21 #include "internal.h"
22
23 #if DISPATCH_DATA_IS_BRIDGED_TO_NSDATA
24
25 #if _OS_OBJECT_OBJC_ARC
26 #error "Cannot build with ARC"
27 #endif
28
29 #include <Foundation/NSString.h>
30
31 // NOTE: this file must not contain any atomic operations
32
33 @interface DISPATCH_CLASS(data) () <DISPATCH_CLASS(data)>
34 @property (readonly,nonatomic) NSUInteger length;
35 @property (readonly,nonatomic) const void *bytes NS_RETURNS_INNER_POINTER;
36
37 - (id)initWithBytes:(void *)bytes length:(NSUInteger)length copy:(BOOL)copy
38 freeWhenDone:(BOOL)freeBytes bytesAreVM:(BOOL)vm;
39 - (BOOL)_bytesAreVM;
40 - (BOOL)_isCompact;
41 @end
42
43 @interface DISPATCH_CLASS(data_empty) : DISPATCH_CLASS(data)
44 @end
45
46 @implementation DISPATCH_CLASS(data)
47
48 + (id)allocWithZone:(NSZone *) DISPATCH_UNUSED zone {
49 return _dispatch_objc_alloc(self, sizeof(struct dispatch_data_s));
50 }
51
52 - (id)init {
53 return [self initWithBytes:NULL length:0 copy:NO freeWhenDone:NO
54 bytesAreVM:NO];
55 }
56
57 - (id)initWithBytes:(void *)bytes length:(NSUInteger)length copy:(BOOL)copy
58 freeWhenDone:(BOOL)freeBytes bytesAreVM:(BOOL)vm {
59 dispatch_block_t destructor;
60 if (copy) {
61 destructor = DISPATCH_DATA_DESTRUCTOR_DEFAULT;
62 } else if (freeBytes) {
63 if (vm) {
64 destructor = DISPATCH_DATA_DESTRUCTOR_VM_DEALLOCATE;
65 } else {
66 destructor = DISPATCH_DATA_DESTRUCTOR_FREE;
67 }
68 } else {
69 destructor = DISPATCH_DATA_DESTRUCTOR_NONE;
70 }
71 _dispatch_data_init_with_bytes(self, bytes, length, destructor);
72 return self;
73 }
74
75 - (void)dealloc {
76 struct dispatch_data_s *dd = (void*)self;
77 _dispatch_data_dispose(self, NULL);
78 dispatch_queue_t tq = dd->do_targetq;
79 dispatch_function_t func = dd->finalizer;
80 void *ctxt = dd->ctxt;
81 [super dealloc];
82 if (func && ctxt) {
83 if (!tq) {
84 tq = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0);
85 }
86 dispatch_async_f(tq, ctxt, func);
87 }
88 if (tq) {
89 _os_object_release_internal((_os_object_t)tq);
90 }
91 }
92
93 - (BOOL)_bytesAreVM {
94 struct dispatch_data_s *dd = (void*)self;
95 return dd->destructor == DISPATCH_DATA_DESTRUCTOR_VM_DEALLOCATE;
96 }
97
98 - (void)_setContext:(void*)context {
99 struct dispatch_data_s *dd = (void*)self;
100 dd->ctxt = context;
101 }
102
103 - (void*)_getContext {
104 struct dispatch_data_s *dd = (void*)self;
105 return dd->ctxt;
106 }
107
108 - (void)_setFinalizer:(dispatch_function_t)finalizer {
109 struct dispatch_data_s *dd = (void*)self;
110 dd->finalizer = finalizer;
111 }
112
113 - (void)_setTargetQueue:(dispatch_queue_t)queue {
114 struct dispatch_data_s *dd = (void*)self;
115 return _dispatch_data_set_target_queue(dd, queue);
116 }
117
118 - (NSString *)debugDescription {
119 Class nsstring = objc_lookUpClass("NSString");
120 if (!nsstring) return nil;
121 char buf[2048];
122 _dispatch_data_debug(self, buf, sizeof(buf));
123 NSString *format = [nsstring stringWithUTF8String:"<%s: %s>"];
124 if (!format) return nil;
125 return [nsstring stringWithFormat:format, class_getName([self class]), buf];
126 }
127
128 - (NSUInteger)length {
129 struct dispatch_data_s *dd = (void*)self;
130 return dd->size;
131 }
132
133 - (const void *)bytes {
134 struct dispatch_data_s *dd = (void*)self;
135 return _dispatch_data_get_flattened_bytes(dd);
136 }
137
138 - (BOOL)_isCompact {
139 struct dispatch_data_s *dd = (void*)self;
140 return !dd->size || _dispatch_data_map_direct(dd, 0, NULL, NULL) != NULL;
141 }
142
143 - (void)_suspend {
144 }
145
146 - (void)_resume {
147 }
148
149 - (void)_activate {
150 }
151
152 @end
153
154 @implementation DISPATCH_CLASS(data_empty)
155
156 // Force non-lazy class realization rdar://10640168
157 + (void)load {
158 }
159
160 - (id)retain {
161 return (id)self;
162 }
163
164 - (oneway void)release {
165 }
166
167 - (id)autorelease {
168 return (id)self;
169 }
170
171 - (NSUInteger)retainCount {
172 return ULONG_MAX;
173 }
174
175 + (id)allocWithZone:(NSZone *) DISPATCH_UNUSED zone {
176 return (id)&_dispatch_data_empty;
177 }
178
179 - (void)_setContext:(void*) DISPATCH_UNUSED context {
180 }
181
182 - (void*)_getContext {
183 return NULL;
184 }
185
186 - (void)_setFinalizer:(dispatch_function_t) DISPATCH_UNUSED finalizer {
187 }
188
189 - (void)_setTargetQueue:(dispatch_queue_t) DISPATCH_UNUSED queue {
190 }
191
192 - (void)_suspend {
193 }
194
195 - (void)_resume {
196 }
197
198 - (void)_activate {
199 }
200
201 @end
202
203 #endif // USE_OBJC