Comment: | Remove underscores from class names |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA3-256: |
17d57e01ff2cbbeae46beecbe74678e7 |
User & Date: | js on 2019-06-17 02:33:47 |
Other Links: | manifest | tags |
2019-06-18
| ||
00:06 | Fix typo to fix Win32 check-in: c15164ca65 user: js tags: trunk | |
2019-06-17
| ||
02:33 | Remove underscores from class names check-in: 17d57e01ff user: js tags: trunk | |
00:38 | Remove underscores from library & framework names check-in: 79fe29dbf4 user: js tags: trunk | |
Modified configure.ac from [7b78df7df0] to [f70db2a2e3].
︙ | ︙ | |||
1304 1305 1306 1307 1308 1309 1310 | #endif ]) AC_CHECK_FUNCS(paccept accept4, break) AC_CHECK_FUNCS(kqueue1 kqueue, [ AC_DEFINE(HAVE_KQUEUE, 1, [Whether we have kqueue]) | | | | | | | | | | | | | | 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 | #endif ]) AC_CHECK_FUNCS(paccept accept4, break) AC_CHECK_FUNCS(kqueue1 kqueue, [ AC_DEFINE(HAVE_KQUEUE, 1, [Whether we have kqueue]) AC_SUBST(OFKQUEUEKERNELEVENTOBSERVER_M, "OFKqueueKernelEventObserver.m") break ]) AC_CHECK_FUNCS(epoll_create1 epoll_create, [ AC_DEFINE(HAVE_EPOLL, 1, [Whether we have epoll]) AC_SUBST(OFEPOLLKERNELEVENTOBSERVER_M, "OFEpollKernelEventObserver.m") break ]) AS_IF([test x"$with_wii" = x"yes"], [ AC_DEFINE(HAVE_POLL, 1, [Whether we have poll()]) AC_SUBST(OFPOLLKERNELEVENTOBSERVER_M, "OFPollKernelEventObserver.m") ], [ AC_CHECK_HEADERS(poll.h) AC_CHECK_FUNC(poll, [ AC_DEFINE(HAVE_POLL, 1, [Whether we have poll()]) AC_SUBST(OFPOLLKERNELEVENTOBSERVER_M, "OFPollKernelEventObserver.m") ]) ]) case "$host_os" in mingw* | morphos*) AC_DEFINE(HAVE_SELECT, 1, [Whether we have select() or similar]) AC_SUBST(OFSELECTKERNELEVENTOBSERVER_M, "OFSelectKernelEventObserver.m") ;; *) AC_CHECK_HEADERS(sys/select.h) AC_CHECK_FUNC(select, [ AC_DEFINE(HAVE_SELECT, 1, [Whether we have select() or similar]) AC_SUBST(OFSELECTKERNELEVENTOBSERVER_M, "OFSelectKernelEventObserver.m") ]) ;; esac AS_IF([test x"$enable_threads" != x"no"], [ AC_SUBST(OFHTTPCLIENTTESTS_M, "OFHTTPClientTests.m") ]) |
︙ | ︙ |
Modified extra.mk.in from [24ff396ef7] to [29e7c06e6b].
︙ | ︙ | |||
51 52 53 54 55 56 57 58 59 60 | LOOKUP_ASM_LIB_A = @LOOKUP_ASM_LIB_A@ LOOKUP_ASM_LOOKUP_ASM_A = @LOOKUP_ASM_LOOKUP_ASM_A@ LOOKUP_ASM_LOOKUP_ASM_LIB_A = @LOOKUP_ASM_LOOKUP_ASM_LIB_A@ MAP_LDFLAGS = @MAP_LDFLAGS@ OFARC = @OFARC@ OFBLOCKTESTS_M = @OFBLOCKTESTS_M@ OFDNS = @OFDNS@ OFHASH = @OFHASH@ OFHTTP = @OFHTTP@ OFHTTPCLIENTTESTS_M = @OFHTTPCLIENTTESTS_M@ | > | < | < > | 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 | LOOKUP_ASM_LIB_A = @LOOKUP_ASM_LIB_A@ LOOKUP_ASM_LOOKUP_ASM_A = @LOOKUP_ASM_LOOKUP_ASM_A@ LOOKUP_ASM_LOOKUP_ASM_LIB_A = @LOOKUP_ASM_LOOKUP_ASM_LIB_A@ MAP_LDFLAGS = @MAP_LDFLAGS@ OFARC = @OFARC@ OFBLOCKTESTS_M = @OFBLOCKTESTS_M@ OFDNS = @OFDNS@ OFEPOLLKERNELEVENTOBSERVER_M = @OFEPOLLKERNELEVENTOBSERVER_M@ OFHASH = @OFHASH@ OFHTTP = @OFHTTP@ OFHTTPCLIENTTESTS_M = @OFHTTPCLIENTTESTS_M@ OFKQUEUEKERNELEVENTOBSERVER_M = @OFKQUEUEKERNELEVENTOBSERVER_M@ OFPOLLKERNELEVENTOBSERVER_M = @OFPOLLKERNELEVENTOBSERVER_M@ OFPROCESS_M = @OFPROCESS_M@ OFSELECTKERNELEVENTOBSERVER_M = @OFSELECTKERNELEVENTOBSERVER_M@ OFSTDIOSTREAM_WIN32CONSOLE_M = @OFSTDIOSTREAM_WIN32CONSOLE_M@ REEXPORT_RUNTIME = @REEXPORT_RUNTIME@ REEXPORT_RUNTIME_FRAMEWORK = @REEXPORT_RUNTIME_FRAMEWORK@ RUNTIME = @RUNTIME@ RUNTIME_FRAMEWORK_LIBS = @RUNTIME_FRAMEWORK_LIBS@ RUNTIME_LIBS = @RUNTIME_LIBS@ RUN_TESTS = @RUN_TESTS@ |
︙ | ︙ |
Modified src/Makefile from [f656662078] to [3a28246372].
︙ | ︙ | |||
148 149 150 151 152 153 154 | OFUDPSocket.m \ socket.m SRCS_THREADS = OFCondition.m \ OFMutex.m \ OFRecursiveMutex.m \ OFThreadPool.m \ threading.m | | | 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 | OFUDPSocket.m \ socket.m SRCS_THREADS = OFCondition.m \ OFMutex.m \ OFRecursiveMutex.m \ OFThreadPool.m \ threading.m SRCS_WINDOWS = OFWin32ConsoleStdIOStream.m \ OFWindowsRegistryKey.m INCLUDES_ATOMIC = atomic.h \ atomic_builtins.h \ atomic_no_threads.h \ atomic_osatomic.h \ atomic_powerpc.h \ |
︙ | ︙ | |||
177 178 179 180 181 182 183 | block.h \ instance.h \ macros.h \ objfw-defs.h \ platform.h \ ${USE_INCLUDES_ATOMIC} | | | < | > | > | | | | | | | | | | | | < | | | | | > | | | | | | < | 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 | block.h \ instance.h \ macros.h \ objfw-defs.h \ platform.h \ ${USE_INCLUDES_ATOMIC} SRCS += OFAdjacentArray.m \ OFAdjacentSubarray.m \ OFBitSetCharacterSet.m \ OFBytesValue.m \ OFCountedMapTableSet.m \ OFDimensionValue.m \ OFInvertedCharacterSet.m \ OFLHADecompressingStream.m \ OFMapTableDictionary.m \ OFMapTableSet.m \ OFMutableAdjacentArray.m \ OFMutableMapTableDictionary.m \ OFMutableMapTableSet.m \ OFMutableUTF8String.m \ OFNonretainedObjectValue.m \ OFPointValue.m \ OFPointerValue.m \ OFRangeCharacterSet.m \ OFRangeValue.m \ OFRectangleValue.m \ OFSubarray.m \ OFUTF8String.m \ ${AUTORELEASE_M} \ ${FOUNDATION_COMPAT_M} \ ${INSTANCE_M} SRCS_FILES += OFFileURLHandler.m \ OFINIFileSettings.m SRCS_SOCKETS += OFHTTPURLHandler.m \ OFKernelEventObserver.m \ ${OFEPOLLKERNELEVENTOBSERVER_M} \ ${OFKQUEUEKERNELEVENTOBSERVER_M} \ ${OFPOLLKERNELEVENTOBSERVER_M} \ ${OFSELECTKERNELEVENTOBSERVER_M} OBJS_EXTRA = ${RUNTIME_RUNTIME_A} \ ${EXCEPTIONS_EXCEPTIONS_A} \ ${ENCODINGS_ENCODINGS_A} \ ${FORWARDING_FORWARDING_A} \ ${INVOCATION_INVOCATION_A} LIB_OBJS_EXTRA = ${RUNTIME_RUNTIME_LIB_A} \ |
︙ | ︙ |
Added src/OFAdjacentArray.h version [6f24e09a18].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | /* * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, * 2018, 2019 * Jonathan Schleifer <js@heap.zone> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #import "OFArray.h" OF_ASSUME_NONNULL_BEGIN @class OFMutableData; @interface OFAdjacentArray: OFArray { OFMutableData *_array; } @end OF_ASSUME_NONNULL_END |
Added src/OFAdjacentArray.m version [7320d2bf06].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 | /* * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, * 2018, 2019 * Jonathan Schleifer <js@heap.zone> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #include <stdarg.h> #import "OFAdjacentArray.h" #import "OFAdjacentSubarray.h" #import "OFData.h" #import "OFMutableAdjacentArray.h" #import "OFString.h" #import "OFXMLElement.h" #import "OFEnumerationMutationException.h" #import "OFInvalidArgumentException.h" #import "OFOutOfRangeException.h" @implementation OFAdjacentArray - (instancetype)init { self = [super init]; @try { _array = [[OFMutableData alloc] initWithItemSize: sizeof(id)]; } @catch (id e) { [self release]; @throw e; } return self; } - (instancetype)initWithObject: (id)object { self = [self init]; @try { if (object == nil) @throw [OFInvalidArgumentException exception]; [_array addItem: &object]; [object retain]; } @catch (id e) { [self release]; @throw e; } return self; } - (instancetype)initWithObject: (id)firstObject arguments: (va_list)arguments { self = [self init]; @try { id object; [_array addItem: &firstObject]; [firstObject retain]; while ((object = va_arg(arguments, id)) != nil) { [_array addItem: &object]; [object retain]; } } @catch (id e) { [self release]; @throw e; } return self; } - (instancetype)initWithArray: (OFArray *)array { id const *objects; size_t count; self = [super init]; if (array == nil) return self; @try { objects = array.objects; count = array.count; _array = [[OFMutableData alloc] initWithItemSize: sizeof(id) capacity: count]; } @catch (id e) { [self release]; @throw e; } @try { for (size_t i = 0; i < count; i++) [objects[i] retain]; [_array addItems: objects count: count]; } @catch (id e) { for (size_t i = 0; i < count; i++) [objects[i] release]; /* Prevent double-release of objects */ [_array release]; _array = nil; [self release]; @throw e; } return self; } - (instancetype)initWithObjects: (id const *)objects count: (size_t)count { self = [self init]; @try { bool ok = true; for (size_t i = 0; i < count; i++) { if (objects[i] == nil) ok = false; [objects[i] retain]; } if (!ok) @throw [OFInvalidArgumentException exception]; [_array addItems: objects count: count]; } @catch (id e) { for (size_t i = 0; i < count; i++) [objects[i] release]; [self release]; @throw e; } return self; } - (instancetype)initWithSerialization: (OFXMLElement *)element { self = [self init]; @try { void *pool = objc_autoreleasePoolPush(); if ((![element.name isEqual: @"OFArray"] && ![element.name isEqual: @"OFMutableArray"]) || ![element.namespace isEqual: OF_SERIALIZATION_NS]) @throw [OFInvalidArgumentException exception]; for (OFXMLElement *child in [element elementsForNamespace: OF_SERIALIZATION_NS]) { void *pool2 = objc_autoreleasePoolPush(); id object; object = child.objectByDeserializing; [_array addItem: &object]; [object retain]; objc_autoreleasePoolPop(pool2); } objc_autoreleasePoolPop(pool); } @catch (id e) { [self release]; @throw e; } return self; } - (size_t)count { return _array.count; } - (id const *)objects { return _array.items; } - (id)objectAtIndex: (size_t)idx { return *((id *)[_array itemAtIndex: idx]); } - (id)objectAtIndexedSubscript: (size_t)idx { return *((id *)[_array itemAtIndex: idx]); } - (void)getObjects: (id *)buffer inRange: (of_range_t)range { id const *objects = _array.items; size_t count = _array.count; if (range.length > SIZE_MAX - range.location || range.location + range.length > count) @throw [OFOutOfRangeException exception]; for (size_t i = 0; i < range.length; i++) buffer[i] = objects[range.location + i]; } - (size_t)indexOfObject: (id)object { id const *objects; size_t count; if (object == nil) return OF_NOT_FOUND; objects = _array.items; count = _array.count; for (size_t i = 0; i < count; i++) if ([objects[i] isEqual: object]) return i; return OF_NOT_FOUND; } - (size_t)indexOfObjectIdenticalTo: (id)object { id const *objects; size_t count; if (object == nil) return OF_NOT_FOUND; objects = _array.items; count = _array.count; for (size_t i = 0; i < count; i++) if (objects[i] == object) return i; return OF_NOT_FOUND; } - (OFArray *)objectsInRange: (of_range_t)range { if (range.length > SIZE_MAX - range.location || range.location + range.length > _array.count) @throw [OFOutOfRangeException exception]; if ([self isKindOfClass: [OFMutableArray class]]) return [OFArray arrayWithObjects: (id *)_array.items + range.location count: range.length]; return [OFAdjacentSubarray arrayWithArray: self range: range]; } - (bool)isEqual: (id)object { OFArray *otherArray; id const *objects, *otherObjects; size_t count; if (object == self) return true; if (![object isKindOfClass: [OFAdjacentArray class]] && ![object isKindOfClass: [OFMutableAdjacentArray class]]) return [super isEqual: object]; otherArray = object; count = _array.count; if (count != otherArray.count) return false; objects = _array.items; otherObjects = otherArray.objects; for (size_t i = 0; i < count; i++) if (![objects[i] isEqual: otherObjects[i]]) return false; return true; } - (uint32_t)hash { id const *objects = _array.items; size_t count = _array.count; uint32_t hash; OF_HASH_INIT(hash); for (size_t i = 0; i < count; i++) OF_HASH_ADD_HASH(hash, [objects[i] hash]); OF_HASH_FINALIZE(hash); return hash; } - (int)countByEnumeratingWithState: (of_fast_enumeration_state_t *)state objects: (id *)objects count: (int)count_ { size_t count = _array.count; if (count > INT_MAX) /* * Use the implementation from OFArray, which is slower, but can * enumerate in chunks. */ return [super countByEnumeratingWithState: state objects: objects count: count_]; if (state->state >= count) return 0; state->state = (unsigned long)count; state->itemsPtr = _array.items; state->mutationsPtr = (unsigned long *)self; return (int)count; } #ifdef OF_HAVE_BLOCKS - (void)enumerateObjectsUsingBlock: (of_array_enumeration_block_t)block { id const *objects = _array.items; size_t count = _array.count; bool stop = false; for (size_t i = 0; i < count && !stop; i++) block(objects[i], i, &stop); } #endif - (void)dealloc { id const *objects = _array.items; size_t count = _array.count; for (size_t i = 0; i < count; i++) [objects[i] release]; [_array release]; [super dealloc]; } @end |
Added src/OFAdjacentSubarray.h version [089d0764c2].
> > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | /* * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, * 2018, 2019 * Jonathan Schleifer <js@heap.zone> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #import "OFSubarray.h" OF_ASSUME_NONNULL_BEGIN @interface OFAdjacentSubarray: OFSubarray @end OF_ASSUME_NONNULL_END |
Added src/OFAdjacentSubarray.m version [9980c4d1c5].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 | /* * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, * 2018, 2019 * Jonathan Schleifer <js@heap.zone> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #import "OFAdjacentSubarray.h" #import "OFAdjacentArray.h" #import "OFMutableAdjacentArray.h" @implementation OFAdjacentSubarray - (const id *)objects { return _array.objects + _range.location; } - (bool)isEqual: (id)object { OFArray *otherArray; id const *objects, *otherObjects; if (object == self) return true; if (![object isKindOfClass: [OFAdjacentArray class]] && ![object isKindOfClass: [OFMutableAdjacentArray class]]) return [super isEqual: object]; otherArray = object; if (_range.length != otherArray.count) return false; objects = self.objects; otherObjects = otherArray.objects; for (size_t i = 0; i < _range.length; i++) if (![objects[i] isEqual: otherObjects[i]]) return false; return true; } #ifdef OF_HAVE_BLOCKS - (void)enumerateObjectsUsingBlock: (of_array_enumeration_block_t)block { id const *objects = self.objects; bool stop = false; for (size_t i = 0; i < _range.length && !stop; i++) block(objects[i], i, &stop); } #endif @end |
Modified src/OFArray.m from [d37721f3e3] to [297edbd879].
︙ | ︙ | |||
19 20 21 22 23 24 25 | #include <stdarg.h> #include <stdlib.h> #include <assert.h> #import "OFArray.h" | | | | | | | | | | | | | | | | | | | | 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 | #include <stdarg.h> #include <stdlib.h> #include <assert.h> #import "OFArray.h" #import "OFAdjacentArray.h" #import "OFData.h" #import "OFNull.h" #import "OFString.h" #import "OFSubarray.h" #import "OFXMLElement.h" #import "OFEnumerationMutationException.h" #import "OFInvalidArgumentException.h" #import "OFOutOfRangeException.h" static struct { Class isa; } placeholder; @interface OFArray () - (OFString *)of_JSONRepresentationWithOptions: (int)options depth: (size_t)depth; @end @interface OFPlaceholderArray: OFArray @end @implementation OFPlaceholderArray - (instancetype)init { return (id)[[OFAdjacentArray alloc] init]; } - (instancetype)initWithObject: (id)object { return (id)[[OFAdjacentArray alloc] initWithObject: object]; } - (instancetype)initWithObjects: (id)firstObject, ... { id ret; va_list arguments; va_start(arguments, firstObject); ret = [[OFAdjacentArray alloc] initWithObject: firstObject arguments: arguments]; va_end(arguments); return ret; } - (instancetype)initWithObject: (id)firstObject arguments: (va_list)arguments { return (id)[[OFAdjacentArray alloc] initWithObject: firstObject arguments: arguments]; } - (instancetype)initWithArray: (OFArray *)array { return (id)[[OFAdjacentArray alloc] initWithArray: array]; } - (instancetype)initWithObjects: (id const *)objects count: (size_t)count { return (id)[[OFAdjacentArray alloc] initWithObjects: objects count: count]; } - (instancetype)initWithSerialization: (OFXMLElement *)element { return (id)[[OFAdjacentArray alloc] initWithSerialization: element]; } - (instancetype)retain { return self; } |
︙ | ︙ | |||
114 115 116 117 118 119 120 | } @end @implementation OFArray + (void)initialize { if (self == [OFArray class]) | | | 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 | } @end @implementation OFArray + (void)initialize { if (self == [OFArray class]) placeholder.isa = [OFPlaceholderArray class]; } + (instancetype)alloc { if (self == [OFArray class]) return (id)&placeholder; |
︙ | ︙ | |||
373 374 375 376 377 378 379 | id *buffer; if (range.length > SIZE_MAX - range.location || range.location + range.length < self.count) @throw [OFOutOfRangeException exception]; if (![self isKindOfClass: [OFMutableArray class]]) | | | | 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 | id *buffer; if (range.length > SIZE_MAX - range.location || range.location + range.length < self.count) @throw [OFOutOfRangeException exception]; if (![self isKindOfClass: [OFMutableArray class]]) return [OFSubarray arrayWithArray: self range: range]; buffer = [self allocMemoryWithSize: sizeof(*buffer) count: range.length]; @try { [self getObjects: buffer inRange: range]; |
︙ | ︙ |
Deleted src/OFArray_adjacent.h version [cf13aac8f8].
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted src/OFArray_adjacent.m version [8d3e15f3ea].
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted src/OFArray_adjacentSubarray.h version [a8790ecdf7].
|
| < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted src/OFArray_adjacentSubarray.m version [71c6741d2d].
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted src/OFArray_subarray.h version [2fca210b9f].
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted src/OFArray_subarray.m version [aa22fe0ab0].
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Added src/OFBitSetCharacterSet.h version [354358342b].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | /* * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, * 2018, 2019 * Jonathan Schleifer <js@heap.zone> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #import "OFCharacterSet.h" OF_ASSUME_NONNULL_BEGIN @interface OFBitSetCharacterSet: OFCharacterSet { unsigned char *_bitset; size_t _size; } @end OF_ASSUME_NONNULL_END |
Added src/OFBitSetCharacterSet.m version [21c8b3a701].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 | /* * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, * 2018, 2019 * Jonathan Schleifer <js@heap.zone> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #import "OFBitSetCharacterSet.h" #import "OFString.h" #import "OFOutOfRangeException.h" @implementation OFBitSetCharacterSet - (instancetype)init { OF_INVALID_INIT_METHOD } - (instancetype)initWithCharactersInString: (OFString *)string { self = [super init]; @try { void *pool = objc_autoreleasePoolPush(); const of_unichar_t *characters = string.characters; size_t length = string.length; for (size_t i = 0; i < length; i++) { of_unichar_t c = characters[i]; if (c / 8 >= _size) { size_t newSize; if (UINT32_MAX - c < 1) @throw [OFOutOfRangeException exception]; newSize = OF_ROUND_UP_POW2(8, c + 1) / 8; _bitset = [self resizeMemory: _bitset size: newSize]; memset(_bitset + _size, '\0', newSize - _size); _size = newSize; } of_bitset_set(_bitset, c); } objc_autoreleasePoolPop(pool); } @catch (id e) { [self release]; @throw e; } return self; } - (bool)characterIsMember: (of_unichar_t)character { if (character / 8 >= _size) return false; return of_bitset_isset(_bitset, character); } @end |
Added src/OFBytesValue.h version [064f02062a].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | /* * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, * 2018, 2019 * Jonathan Schleifer <js@heap.zone> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #import "OFValue.h" OF_ASSUME_NONNULL_BEGIN @interface OFBytesValue: OFValue { size_t _size; void *_bytes; const char *_objCType; } @end OF_ASSUME_NONNULL_END |
Added src/OFBytesValue.m version [0015e832d3].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | /* * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, * 2018, 2019 * Jonathan Schleifer <js@heap.zone> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #import "OFBytesValue.h" #import "OFMethodSignature.h" #import "OFOutOfRangeException.h" @implementation OFBytesValue @synthesize objCType = _objCType; - (instancetype)initWithBytes: (const void *)bytes objCType: (const char *)objCType { self = [super init]; @try { _size = of_sizeof_type_encoding(objCType); _objCType = objCType; _bytes = [self allocMemoryWithSize: _size]; memcpy(_bytes, bytes, _size); } @catch (id e) { [self release]; @throw e; } return self; } - (void)getValue: (void *)value size: (size_t)size { if (size != _size) @throw [OFOutOfRangeException exception]; memcpy(value, _bytes, _size); } @end |
Modified src/OFCharacterSet.m from [b3111ce4c7] to [0f6fc5e073].
︙ | ︙ | |||
14 15 16 17 18 19 20 | * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #import "OFCharacterSet.h" | | | | | | | | | | | 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 | * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #import "OFCharacterSet.h" #import "OFBitSetCharacterSet.h" #import "OFInvertedCharacterSet.h" #import "OFRangeCharacterSet.h" static struct { Class isa; } placeholder; static OFCharacterSet *whitespaceCharacterSet = nil; @interface OFPlaceholderCharacterSet: OFCharacterSet @end @interface OFWhitespaceCharacterSet: OFCharacterSet - (instancetype)of_init; @end @implementation OFPlaceholderCharacterSet - (instancetype)init { return (id)[[OFBitSetCharacterSet alloc] init]; } - (instancetype)initWithCharactersInString: (OFString *)characters { return (id)[[OFBitSetCharacterSet alloc] initWithCharactersInString: characters]; } - (instancetype)initWithRange: (of_range_t)range { return (id)[[OFRangeCharacterSet alloc] initWithRange: range]; } - (instancetype)retain { return self; } |
︙ | ︙ | |||
74 75 76 77 78 79 80 | @implementation OFCharacterSet + (void)initialize { if (self != [OFCharacterSet class]) return; | | | 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 | @implementation OFCharacterSet + (void)initialize { if (self != [OFCharacterSet class]) return; placeholder.isa = [OFPlaceholderCharacterSet class]; } + (instancetype)alloc { if (self == [OFCharacterSet class]) return (id)&placeholder; |
︙ | ︙ | |||
98 99 100 101 102 103 104 | + (instancetype)characterSetWithRange: (of_range_t)range { return [[[self alloc] initWithRange: range] autorelease]; } + (OFCharacterSet *)whitespaceCharacterSet { | | | 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 | + (instancetype)characterSetWithRange: (of_range_t)range { return [[[self alloc] initWithRange: range] autorelease]; } + (OFCharacterSet *)whitespaceCharacterSet { return [OFWhitespaceCharacterSet whitespaceCharacterSet]; } - (instancetype)init { if ([self isMemberOfClass: [OFCharacterSet class]]) { @try { [self doesNotRecognizeSelector: _cmd]; |
︙ | ︙ | |||
134 135 136 137 138 139 140 | - (bool)characterIsMember: (of_unichar_t)character { OF_UNRECOGNIZED_SELECTOR } - (OFCharacterSet *)invertedSet { | | | | | | 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 | - (bool)characterIsMember: (of_unichar_t)character { OF_UNRECOGNIZED_SELECTOR } - (OFCharacterSet *)invertedSet { return [[[OFInvertedCharacterSet alloc] of_initWithCharacterSet: self] autorelease]; } @end @implementation OFWhitespaceCharacterSet + (void)initialize { if (self != [OFWhitespaceCharacterSet class]) return; whitespaceCharacterSet = [[OFWhitespaceCharacterSet alloc] of_init]; } + (OFCharacterSet *)whitespaceCharacterSet { return whitespaceCharacterSet; } |
︙ | ︙ |
Deleted src/OFCharacterSet_bitset.h version [87ada6ad3e].
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted src/OFCharacterSet_bitset.m version [37fa197eff].
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted src/OFCharacterSet_invertedSet.h version [76de880ce5].
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted src/OFCharacterSet_invertedSet.m version [9fff03f3e8].
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted src/OFCharacterSet_range.h version [fed98bedb2].
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted src/OFCharacterSet_range.m version [80859f1b87].
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Modified src/OFConstantString.m from [5af702f073] to [7863900fc6].
︙ | ︙ | |||
19 20 21 22 23 24 25 | #include "config.h" #include <stdlib.h> #include <string.h> #import "OFConstantString.h" | | | 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | #include "config.h" #include <stdlib.h> #include <string.h> #import "OFConstantString.h" #import "OFUTF8String.h" #import "OFInitializationFailedException.h" #import "OFInvalidEncodingException.h" #import "OFOutOfMemoryException.h" #if defined(OF_APPLE_RUNTIME) && !defined(__OBJC2__) # import <objc/runtime.h> |
︙ | ︙ | |||
41 42 43 44 45 46 47 | struct cache *cache; struct protocol_list *protocols; const char *iVarLayout; struct class_ext *ext; } _OFConstantStringClassReference; #endif | | | | 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 | struct cache *cache; struct protocol_list *protocols; const char *iVarLayout; struct class_ext *ext; } _OFConstantStringClassReference; #endif @interface OFConstantUTF8String: OFUTF8String @end @implementation OFConstantUTF8String + (instancetype)alloc { OF_UNRECOGNIZED_SELECTOR } - (void *)allocMemoryWithSize: (size_t)size { |
︙ | ︙ | |||
135 136 137 138 139 140 141 | } - (void)finishInitialization { @synchronized (self) { struct of_string_utf8_ivars *ivars; | | | 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 | } - (void)finishInitialization { @synchronized (self) { struct of_string_utf8_ivars *ivars; if ([self isMemberOfClass: [OFConstantUTF8String class]]) return; if ((ivars = calloc(1, sizeof(*ivars))) == NULL) @throw [OFOutOfMemoryException exceptionWithRequestedSize: sizeof(*ivars)]; ivars->cString = _cString; |
︙ | ︙ | |||
157 158 159 160 161 162 163 | break; case -1: free(ivars); @throw [OFInvalidEncodingException exception]; } _cString = (char *)ivars; | | | 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 | break; case -1: free(ivars); @throw [OFInvalidEncodingException exception]; } _cString = (char *)ivars; object_setClass(self, [OFConstantUTF8String class]); } } + (instancetype)alloc { OF_UNRECOGNIZED_SELECTOR } |
︙ | ︙ | |||
221 222 223 224 225 226 227 | - (void)dealloc { OF_DEALLOC_UNSUPPORTED } /* * In all following methods, the constant string is converted to an | | | 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 | - (void)dealloc { OF_DEALLOC_UNSUPPORTED } /* * In all following methods, the constant string is converted to an * OFUTF8String and the message sent again. */ /* From protocol OFCopying */ - (id)copy { [self finishInitialization]; |
︙ | ︙ |
Added src/OFCountedMapTableSet.h version [425da1187b].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | /* * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, * 2018, 2019 * Jonathan Schleifer <js@heap.zone> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #import "OFCountedSet.h" OF_ASSUME_NONNULL_BEGIN @class OFMapTable; @interface OFCountedMapTableSet: OFCountedSet { OFMapTable *_mapTable; } @end OF_ASSUME_NONNULL_END |
Added src/OFCountedMapTableSet.m version [45a118d97e].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 | /* * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, * 2018, 2019 * Jonathan Schleifer <js@heap.zone> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #import "OFCountedMapTableSet.h" #import "OFArray.h" #import "OFMapTable.h" #import "OFMutableMapTableSet.h" #import "OFString.h" #import "OFXMLAttribute.h" #import "OFXMLElement.h" #import "OFInvalidArgumentException.h" #import "OFInvalidFormatException.h" #import "OFEnumerationMutationException.h" #import "OFOutOfRangeException.h" @implementation OFCountedMapTableSet + (void)initialize { if (self == [OFCountedMapTableSet class]) [self inheritMethodsFromClass: [OFMutableMapTableSet class]]; } - (instancetype)initWithSet: (OFSet *)set { self = [self init]; @try { void *pool = objc_autoreleasePoolPush(); if ([set isKindOfClass: [OFCountedSet class]]) { OFCountedSet *countedSet = (OFCountedSet *)countedSet; for (id object in countedSet) { size_t count = [countedSet countForObject: object]; for (size_t i = 0; i < count; i++) [self addObject: object]; } } else for (id object in set) [self addObject: object]; objc_autoreleasePoolPop(pool); } @catch (id e) { [self release]; @throw e; } return self; } - (instancetype)initWithArray: (OFArray *)array { self = [self init]; @try { id const *objects = array.objects; size_t count = array.count; for (size_t i = 0; i < count; i++) [self addObject: objects[i]]; } @catch (id e) { [self release]; @throw e; } return self; } - (instancetype)initWithObjects: (id const *)objects count: (size_t)count { self = [self init]; @try { for (size_t i = 0; i < count; i++) [self addObject: objects[i]]; } @catch (id e) { [self release]; @throw e; } return self; } - (instancetype)initWithObject: (id)firstObject arguments: (va_list)arguments { self = [self init]; @try { id object; [self addObject: firstObject]; while ((object = va_arg(arguments, id)) != nil) [self addObject: object]; } @catch (id e) { [self release]; @throw e; } return self; } - (instancetype)initWithSerialization: (OFXMLElement *)element { self = [self init]; @try { void *pool = objc_autoreleasePoolPush(); if (![element.name isEqual: @"OFCountedSet"] || ![element.namespace isEqual: OF_SERIALIZATION_NS]) @throw [OFInvalidArgumentException exception]; for (OFXMLElement *objectElement in [element elementsForName: @"object" namespace: OF_SERIALIZATION_NS]) { void *pool2 = objc_autoreleasePoolPush(); OFXMLElement *object; OFXMLAttribute *countAttribute; intmax_t signedCount; uintmax_t count; object = [objectElement elementsForNamespace: OF_SERIALIZATION_NS].firstObject; countAttribute = [objectElement attributeForName: @"count"]; if (object == nil || countAttribute == nil) @throw [OFInvalidFormatException exception]; signedCount = countAttribute.decimalValue; if (signedCount < 0) @throw [OFOutOfRangeException exception]; count = signedCount; if (count > SIZE_MAX || count > UINTPTR_MAX) @throw [OFOutOfRangeException exception]; [_mapTable setObject: (void *)(uintptr_t)count forKey: object.objectByDeserializing]; objc_autoreleasePoolPop(pool2); } objc_autoreleasePoolPop(pool); } @catch (id e) { [self release]; @throw e; } return self; } - (size_t)countForObject: (id)object { return (size_t)(uintptr_t)[_mapTable objectForKey: object]; } #ifdef OF_HAVE_BLOCKS - (void)enumerateObjectsAndCountUsingBlock: (of_counted_set_enumeration_block_t)block { @try { [_mapTable enumerateKeysAndObjectsUsingBlock: ^ (void *key, void *object, bool *stop) { block(key, (size_t)(uintptr_t)object, stop); }]; } @catch (OFEnumerationMutationException *e) { @throw [OFEnumerationMutationException exceptionWithObject: self]; } } #endif - (void)addObject: (id)object { size_t count = (size_t)(uintptr_t)[_mapTable objectForKey: object]; if (SIZE_MAX - count < 1 || UINTPTR_MAX - count < 1) @throw [OFOutOfRangeException exception]; [_mapTable setObject: (void *)(uintptr_t)(count + 1) forKey: object]; } - (void)removeObject: (id)object { size_t count = (size_t)(uintptr_t)[_mapTable objectForKey: object]; if (count == 0) return; count--; if (count > 0) [_mapTable setObject: (void *)(uintptr_t)count forKey: object]; else [_mapTable removeObjectForKey: object]; } - (void)removeAllObjects { [_mapTable removeAllObjects]; } - (void)makeImmutable { } @end |
Modified src/OFCountedSet.m from [d7f89e4f31] to [1fdac7b584].
︙ | ︙ | |||
16 17 18 19 20 21 22 | */ #include "config.h" #include <stdlib.h> #import "OFCountedSet.h" | | | | | | | | | | | | | | | 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 | */ #include "config.h" #include <stdlib.h> #import "OFCountedSet.h" #import "OFCountedMapTableSet.h" #import "OFNumber.h" #import "OFString.h" #import "OFXMLElement.h" static struct { Class isa; } placeholder; @interface OFCountedSetPlaceholder: OFCountedSet @end @implementation OFCountedSetPlaceholder - (instancetype)init { return (id)[[OFCountedMapTableSet alloc] init]; } - (instancetype)initWithSet: (OFSet *)set { return (id)[[OFCountedMapTableSet alloc] initWithSet: set]; } - (instancetype)initWithArray: (OFArray *)array { return (id)[[OFCountedMapTableSet alloc] initWithArray: array]; } - (instancetype)initWithObjects: (id)firstObject, ... { id ret; va_list arguments; va_start(arguments, firstObject); ret = [[OFCountedMapTableSet alloc] initWithObject: firstObject arguments: arguments]; va_end(arguments); return ret; } - (instancetype)initWithObjects: (id const *)objects count: (size_t)count { return (id)[[OFCountedMapTableSet alloc] initWithObjects: objects count: count]; } - (instancetype)initWithObject: (id)firstObject arguments: (va_list)arguments { return (id)[[OFCountedMapTableSet alloc] initWithObject: firstObject arguments: arguments]; } - (instancetype)initWithSerialization: (OFXMLElement *)element { return (id)[[OFCountedMapTableSet alloc] initWithSerialization: element]; } - (instancetype)retain { return self; } |
︙ | ︙ | |||
101 102 103 104 105 106 107 | } @end @implementation OFCountedSet + (void)initialize { if (self == [OFCountedSet class]) | | | 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 | } @end @implementation OFCountedSet + (void)initialize { if (self == [OFCountedSet class]) placeholder.isa = [OFCountedSetPlaceholder class]; } + (instancetype)alloc { if (self == [OFCountedSet class]) return (id)&placeholder; |
︙ | ︙ |
Deleted src/OFCountedSet_hashtable.h version [faac06f013].
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted src/OFCountedSet_hashtable.m version [730baf31e4].
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Modified src/OFDNSResolver.m from [e622efd3e9] to [a2fc2aa0b5].
︙ | ︙ | |||
166 167 168 169 170 171 172 | nameServersIndex: (size_t)nameServersIndex searchDomainsIndex: (size_t)searchDomainsIndex target: (id)target selector: (SEL)selector context: (id)context; @end | | | 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 | nameServersIndex: (size_t)nameServersIndex searchDomainsIndex: (size_t)searchDomainsIndex target: (id)target selector: (SEL)selector context: (id)context; @end @interface OFDNSResolverAsyncResolveSocketAddressesContext: OFObject { OFString *_host; id _delegate; OFMutableArray OF_GENERIC(OF_KINDOF(OFDNSResourceRecord *)) *_records; OFDNSResolver *_resolver; OFString *_domainName; @public |
︙ | ︙ | |||
208 209 210 211 212 213 214 | answerRecords: (OFDictionary *)answerRecords authorityRecords: (OFDictionary *)authorityRecords additionalRecords: (OFDictionary *)additionalRecords context: (OFNumber *)context exception: (id)exception; @end | | | 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 | answerRecords: (OFDictionary *)answerRecords authorityRecords: (OFDictionary *)authorityRecords additionalRecords: (OFDictionary *)additionalRecords context: (OFNumber *)context exception: (id)exception; @end @interface OFDNSResolverResolveSocketAddressesDelegate: OFObject <OFDNSResolverDelegate> { @public bool _done; OFData *_socketAddresses; id _exception; } |
︙ | ︙ | |||
830 831 832 833 834 835 836 | [_queryData release]; [_cancelTimer release]; [super dealloc]; } @end | | | 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 | [_queryData release]; [_cancelTimer release]; [super dealloc]; } @end @implementation OFDNSResolverAsyncResolveSocketAddressesContext - (instancetype)initWithHost: (OFString *)host delegate: (id)delegate { self = [super init]; @try { _host = [host copy]; |
︙ | ︙ | |||
1109 1110 1111 1112 1113 1114 1115 | result: _records]; if (_expectedResponses == 0) [self done]; } @end | | | 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 | result: _records]; if (_expectedResponses == 0) [self done]; } @end @implementation OFDNSResolverResolveSocketAddressesDelegate - (void)dealloc { [_socketAddresses release]; [_exception release]; [super dealloc]; } |
︙ | ︙ | |||
2065 2066 2067 2068 2069 2070 2071 | addressFamily: (of_socket_address_family_t) addressFamily runLoopMode: (of_run_loop_mode_t)runLoopMode delegate: (id <OFDNSResolverDelegate>)delegate { OFArray OF_GENERIC(OFString *) *aliases; void *pool; | | | 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 | addressFamily: (of_socket_address_family_t) addressFamily runLoopMode: (of_run_loop_mode_t)runLoopMode delegate: (id <OFDNSResolverDelegate>)delegate { OFArray OF_GENERIC(OFString *) *aliases; void *pool; OFDNSResolverAsyncResolveSocketAddressesContext *context; @try { of_socket_address_t address = of_socket_address_parse_ip(host, 0); OFData *addresses = nil; id exception = nil; |
︙ | ︙ | |||
2184 2185 2186 2187 2188 2189 2190 | } return; } pool = objc_autoreleasePoolPush(); | | | 2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 2196 2197 2198 | } return; } pool = objc_autoreleasePoolPush(); context = [[[OFDNSResolverAsyncResolveSocketAddressesContext alloc] initWithHost: host delegate: delegate] autorelease]; switch (addressFamily) { case OF_SOCKET_ADDRESS_FAMILY_IPV4: #ifdef OF_HAVE_IPV6 case OF_SOCKET_ADDRESS_FAMILY_IPV6: |
︙ | ︙ | |||
2250 2251 2252 2253 2254 2255 2256 | - (OFData *)resolveSocketAddressesForHost: (OFString *)host addressFamily: (of_socket_address_family_t) addressFamily { void *pool = objc_autoreleasePoolPush(); OFRunLoop *runLoop = [OFRunLoop currentRunLoop]; | | | | 2250 2251 2252 2253 2254 2255 2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 2267 | - (OFData *)resolveSocketAddressesForHost: (OFString *)host addressFamily: (of_socket_address_family_t) addressFamily { void *pool = objc_autoreleasePoolPush(); OFRunLoop *runLoop = [OFRunLoop currentRunLoop]; OFDNSResolverResolveSocketAddressesDelegate *delegate; OFData *ret; delegate = [[[OFDNSResolverResolveSocketAddressesDelegate alloc] init] autorelease]; [self asyncResolveSocketAddressesForHost: host addressFamily: addressFamily runLoopMode: resolveRunLoopMode delegate: delegate]; |
︙ | ︙ |
Modified src/OFDictionary.m from [17f313b4bd] to [bc54a55dea].
︙ | ︙ | |||
18 19 20 21 22 23 24 | #include "config.h" #include <stdlib.h> #include <assert.h> #import "OFDictionary.h" | < | > | | | | | | | | | | | | | | | | | | | | 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 | #include "config.h" #include <stdlib.h> #include <assert.h> #import "OFDictionary.h" #import "OFArray.h" #import "OFCharacterSet.h" #import "OFData.h" #import "OFMapTableDictionary.h" #import "OFString.h" #import "OFXMLElement.h" #import "OFInvalidArgumentException.h" #import "OFOutOfRangeException.h" #import "OFUndefinedKeyException.h" static struct { Class isa; } placeholder; static OFCharacterSet *URLQueryPartAllowedCharacterSet = nil; @interface OFDictionary () - (OFString *)of_JSONRepresentationWithOptions: (int)options depth: (size_t)depth; @end @interface OFDictionaryPlaceholder: OFDictionary @end @interface OFURLQueryPartAllowedCharacterSet: OFCharacterSet + (OFCharacterSet *)URLQueryPartAllowedCharacterSet; @end @implementation OFDictionaryPlaceholder - (instancetype)init { return (id)[[OFMapTableDictionary alloc] init]; } - (instancetype)initWithDictionary: (OFDictionary *)dictionary { return (id)[[OFMapTableDictionary alloc] initWithDictionary: dictionary]; } - (instancetype)initWithObject: (id)object forKey: (id)key { return (id)[[OFMapTableDictionary alloc] initWithObject: object forKey: key]; } - (instancetype)initWithObjects: (OFArray *)objects forKeys: (OFArray *)keys { return (id)[[OFMapTableDictionary alloc] initWithObjects: objects forKeys: keys]; } - (instancetype)initWithObjects: (id const *)objects forKeys: (id const *)keys count: (size_t)count { return (id)[[OFMapTableDictionary alloc] initWithObjects: objects forKeys: keys count: count]; } - (instancetype)initWithKeysAndObjects: (id <OFCopying>)firstKey, ... { id ret; va_list arguments; va_start(arguments, firstKey); ret = [[OFMapTableDictionary alloc] initWithKey: firstKey arguments: arguments]; va_end(arguments); return ret; } - (instancetype)initWithKey: (id <OFCopying>)firstKey arguments: (va_list)arguments { return (id)[[OFMapTableDictionary alloc] initWithKey: firstKey arguments: arguments]; } - (instancetype)initWithSerialization: (OFXMLElement *)element { return (id)[[OFMapTableDictionary alloc] initWithSerialization: element]; } - (instancetype)retain { return self; } |
︙ | ︙ | |||
128 129 130 131 132 133 134 | - (void)dealloc { OF_DEALLOC_UNSUPPORTED } @end | | | | | 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 | - (void)dealloc { OF_DEALLOC_UNSUPPORTED } @end @implementation OFURLQueryPartAllowedCharacterSet + (void)initialize { if (self != [OFURLQueryPartAllowedCharacterSet class]) return; URLQueryPartAllowedCharacterSet = [[OFURLQueryPartAllowedCharacterSet alloc] init]; } + (OFCharacterSet *)URLQueryPartAllowedCharacterSet { return URLQueryPartAllowedCharacterSet; } |
︙ | ︙ | |||
192 193 194 195 196 197 198 | } @end @implementation OFDictionary + (void)initialize { if (self == [OFDictionary class]) | | | 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 | } @end @implementation OFDictionary + (void)initialize { if (self == [OFDictionary class]) placeholder.isa = [OFDictionaryPlaceholder class]; } + (instancetype)alloc { if (self == [OFDictionary class]) return (id)&placeholder; |
︙ | ︙ | |||
623 624 625 626 627 628 629 | - (OFString *)stringByURLEncoding { OFMutableString *ret = [OFMutableString string]; void *pool = objc_autoreleasePoolPush(); OFEnumerator *keyEnumerator = [self keyEnumerator]; OFEnumerator *objectEnumerator = [self objectEnumerator]; | | | 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 | - (OFString *)stringByURLEncoding { OFMutableString *ret = [OFMutableString string]; void *pool = objc_autoreleasePoolPush(); OFEnumerator *keyEnumerator = [self keyEnumerator]; OFEnumerator *objectEnumerator = [self objectEnumerator]; OFCharacterSet *allowed = [OFURLQueryPartAllowedCharacterSet URLQueryPartAllowedCharacterSet]; bool first = true; OFObject *key, *object; while ((key = [keyEnumerator nextObject]) != nil && (object = [objectEnumerator nextObject]) != nil) { if OF_UNLIKELY (first) |
︙ | ︙ |
Deleted src/OFDictionary_hashtable.h version [ef2a78ca48].
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted src/OFDictionary_hashtable.m version [59f7a05c14].
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Added src/OFDimensionValue.h version [506e11e7af].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | /* * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, * 2018, 2019 * Jonathan Schleifer <js@heap.zone> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #import "OFValue.h" OF_ASSUME_NONNULL_BEGIN @interface OFDimensionValue: OFValue { of_dimension_t _dimension; } @end OF_ASSUME_NONNULL_END |
Added src/OFDimensionValue.m version [352d1aa709].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 | /* * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, * 2018, 2019 * Jonathan Schleifer <js@heap.zone> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #import "OFDimensionValue.h" #import "OFMethodSignature.h" #import "OFString.h" #import "OFOutOfRangeException.h" @implementation OFDimensionValue @synthesize dimensionValue = _dimension; - (instancetype)initWithDimension: (of_dimension_t)dimension { self = [super init]; _dimension = dimension; return self; } - (const char *)objCType { return @encode(of_dimension_t); } - (void)getValue: (void *)value size: (size_t)size { if (size != sizeof(_dimension)) @throw [OFOutOfRangeException exception]; memcpy(value, &_dimension, sizeof(_dimension)); } - (OFString *)description { return [OFString stringWithFormat: @"<OFValue: of_dimension_t { %f, %f }>", _dimension.width, _dimension.height]; } @end |
Added src/OFEpollKernelEventObserver.h version [a52cc0d821].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | /* * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, * 2018, 2019 * Jonathan Schleifer <js@heap.zone> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #import "OFKernelEventObserver.h" OF_ASSUME_NONNULL_BEGIN @class OFMapTable; @interface OFEpollKernelEventObserver: OFKernelEventObserver { int _epfd; OFMapTable *_FDToEvents; } @end OF_ASSUME_NONNULL_END |
Added src/OFEpollKernelEventObserver.m version [57b7e47f90].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 | /* * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, * 2018, 2019 * Jonathan Schleifer <js@heap.zone> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #include <assert.h> #include <errno.h> #ifdef HAVE_FCNTL_H # include <fcntl.h> #endif #include "unistd_wrapper.h" #include <sys/epoll.h> #import "OFEpollKernelEventObserver.h" #import "OFArray.h" #import "OFKernelEventObserver+Private.h" #import "OFKernelEventObserver.h" #import "OFMapTable.h" #ifdef OF_HAVE_THREADS # import "OFMutex.h" #endif #import "OFNull.h" #import "OFInitializationFailedException.h" #import "OFObserveFailedException.h" #define EVENTLIST_SIZE 64 static const of_map_table_functions_t mapFunctions = { NULL }; @implementation OFEpollKernelEventObserver - (instancetype)init { self = [super init]; @try { struct epoll_event event; #ifdef HAVE_EPOLL_CREATE1 if ((_epfd = epoll_create1(EPOLL_CLOEXEC)) == -1) @throw [OFInitializationFailedException exceptionWithClass: self.class]; #else int flags; if ((_epfd = epoll_create(1)) == -1) @throw [OFInitializationFailedException exceptionWithClass: self.class]; if ((flags = fcntl(_epfd, F_GETFD, 0)) != -1) fcntl(_epfd, F_SETFD, flags | FD_CLOEXEC); #endif _FDToEvents = [[OFMapTable alloc] initWithKeyFunctions: mapFunctions objectFunctions: mapFunctions]; memset(&event, 0, sizeof(event)); event.events = EPOLLIN; event.data.ptr = [OFNull null]; if (epoll_ctl(_epfd, EPOLL_CTL_ADD, _cancelFD[0], &event) == -1) @throw [OFInitializationFailedException exceptionWithClass: self.class]; } @catch (id e) { [self release]; @throw e; } return self; } - (void)dealloc { close(_epfd); [_FDToEvents release]; [super dealloc]; } - (void)of_addObject: (id)object fileDescriptor: (int)fd events: (int)addEvents { struct epoll_event event; intptr_t events; events = (intptr_t)[_FDToEvents objectForKey: (void *)((intptr_t)fd + 1)]; memset(&event, 0, sizeof(event)); event.events = (int)events | addEvents; event.data.ptr = object; if (epoll_ctl(_epfd, (events == 0 ? EPOLL_CTL_ADD : EPOLL_CTL_MOD), fd, &event) == -1) @throw [OFObserveFailedException exceptionWithObserver: self errNo: errno]; [_FDToEvents setObject: (void *)(events | addEvents) forKey: (void *)((intptr_t)fd + 1)]; } - (void)of_removeObject: (id)object fileDescriptor: (int)fd events: (int)removeEvents { intptr_t events; events = (intptr_t)[_FDToEvents objectForKey: (void *)((intptr_t)fd + 1)]; events &= ~removeEvents; if (events == 0) { if (epoll_ctl(_epfd, EPOLL_CTL_DEL, fd, NULL) == -1) @throw [OFObserveFailedException exceptionWithObserver: self errNo: errno]; [_FDToEvents removeObjectForKey: (void *)((intptr_t)fd + 1)]; } else { struct epoll_event event; memset(&event, 0, sizeof(event)); event.events = (int)events; event.data.ptr = object; if (epoll_ctl(_epfd, EPOLL_CTL_MOD, fd, &event) == -1) @throw [OFObserveFailedException exceptionWithObserver: self errNo: errno]; [_FDToEvents setObject: (void *)events forKey: (void *)((intptr_t)fd + 1)]; } } - (void)of_addObjectForReading: (id <OFReadyForReadingObserving>)object { [self of_addObject: object fileDescriptor: object.fileDescriptorForReading events: EPOLLIN]; } - (void)of_addObjectForWriting: (id <OFReadyForWritingObserving>)object { [self of_addObject: object fileDescriptor: object.fileDescriptorForWriting events: EPOLLOUT]; } - (void)of_removeObjectForReading: (id <OFReadyForReadingObserving>)object { [self of_removeObject: object fileDescriptor: object.fileDescriptorForReading events: EPOLLIN]; } - (void)of_removeObjectForWriting: (id <OFReadyForWritingObserving>)object { [self of_removeObject: object fileDescriptor: object.fileDescriptorForWriting events: EPOLLOUT]; } - (void)observeForTimeInterval: (of_time_interval_t)timeInterval { OFNull *nullObject = [OFNull null]; struct epoll_event eventList[EVENTLIST_SIZE]; int events; [self of_processQueue]; if ([self of_processReadBuffers]) return; events = epoll_wait(_epfd, eventList, EVENTLIST_SIZE, (timeInterval != -1 ? timeInterval * 1000 : -1)); if (events < 0) @throw [OFObserveFailedException exceptionWithObserver: self errNo: errno]; for (int i = 0; i < events; i++) { if (eventList[i].data.ptr == nullObject) { char buffer; assert(eventList[i].events == EPOLLIN); OF_ENSURE(read(_cancelFD[0], &buffer, 1) == 1); continue; } if (eventList[i].events & EPOLLIN) { void *pool = objc_autoreleasePoolPush(); if ([_delegate respondsToSelector: @selector(objectIsReadyForReading:)]) [_delegate objectIsReadyForReading: eventList[i].data.ptr]; objc_autoreleasePoolPop(pool); } if (eventList[i].events & EPOLLOUT) { void *pool = objc_autoreleasePoolPush(); if ([_delegate respondsToSelector: @selector(objectIsReadyForWriting:)]) [_delegate objectIsReadyForWriting: eventList[i].data.ptr]; objc_autoreleasePoolPop(pool); } assert((eventList[i].events & ~(EPOLLIN | EPOLLOUT)) == 0); } } @end |
Modified src/OFFileManager.m from [3d2ebfc062] to [fd1d5c75f5].
︙ | ︙ | |||
70 71 72 73 74 75 76 | # define __NOGLOBALIFACE__ # endif # include <proto/exec.h> # include <proto/dos.h> # include <proto/locale.h> #endif | | | 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 | # define __NOGLOBALIFACE__ # endif # include <proto/exec.h> # include <proto/dos.h> # include <proto/locale.h> #endif @interface OFDefaultFileManager: OFFileManager @end const of_file_attribute_key_t of_file_attribute_key_size = @"of_file_attribute_key_size"; const of_file_attribute_key_t of_file_attribute_key_type = @"of_file_attribute_key_type"; const of_file_attribute_key_t of_file_attribute_key_posix_permissions = |
︙ | ︙ | |||
173 174 175 176 177 178 179 | /* * Make sure OFFile is initialized. * On some systems, this is needed to initialize the file system driver. */ [OFFile class]; #endif | | | 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 | /* * Make sure OFFile is initialized. * On some systems, this is needed to initialize the file system driver. */ [OFFile class]; #endif defaultManager = [[OFDefaultFileManager alloc] init]; } + (OFFileManager *)defaultManager { return defaultManager; } |
︙ | ︙ | |||
890 891 892 893 894 895 896 | withDestinationPath: target]; objc_autoreleasePoolPop(pool); } #endif @end | | | 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 | withDestinationPath: target]; objc_autoreleasePoolPop(pool); } #endif @end @implementation OFDefaultFileManager - (instancetype)autorelease { return self; } - (instancetype)retain { |
︙ | ︙ |
Added src/OFFileURLHandler.h version [4c8d0c729e].
> > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | /* * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, * 2018, 2019 * Jonathan Schleifer <js@heap.zone> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #import "OFURLHandler.h" OF_ASSUME_NONNULL_BEGIN @interface OFFileURLHandler: OFURLHandler + (bool)of_directoryExistsAtPath: (OFString *)path; @end OF_ASSUME_NONNULL_END |
Added src/OFFileURLHandler.m version [6199066dbb].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 | /* * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, * 2018, 2019 * Jonathan Schleifer <js@heap.zone> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #include <errno.h> #ifdef HAVE_DIRENT_H # include <dirent.h> #endif #include "unistd_wrapper.h" #ifdef HAVE_SYS_STAT_H # include <sys/stat.h> #endif #ifdef HAVE_PWD_H # include <pwd.h> #endif #ifdef HAVE_GRP_H # include <grp.h> #endif #import "OFFileURLHandler.h" #import "OFArray.h" #import "OFDate.h" #import "OFFile.h" #import "OFFileManager.h" #import "OFLocale.h" #import "OFNumber.h" #import "OFURL.h" #ifdef OF_HAVE_THREADS # import "OFMutex.h" #endif #import "OFCreateDirectoryFailedException.h" #import "OFCreateSymbolicLinkFailedException.h" #import "OFInitializationFailedException.h" #import "OFInvalidArgumentException.h" #import "OFLinkFailedException.h" #import "OFMoveItemFailedException.h" #import "OFNotImplementedException.h" #import "OFOpenItemFailedException.h" #import "OFOutOfRangeException.h" #import "OFReadFailedException.h" #import "OFRemoveItemFailedException.h" #import "OFRetrieveItemAttributesFailedException.h" #import "OFSetItemAttributesFailedException.h" #ifdef OF_WINDOWS # include <windows.h> # include <direct.h> # include <ntdef.h> # include <wchar.h> #endif #ifdef OF_AMIGAOS # ifdef OF_AMIGAOS4 # define __USE_INLINE__ # define __NOLIBBASE__ # define __NOGLOBALIFACE__ # endif # include <proto/exec.h> # include <proto/dos.h> # include <proto/locale.h> # ifdef OF_AMIGAOS4 # define DeleteFile(path) Delete(path) # endif #endif #if defined(OF_WINDOWS) || defined(OF_AMIGAOS) typedef struct { of_offset_t st_size; unsigned int st_mode; of_time_interval_t st_atime, st_mtime, st_ctime; # ifdef OF_WINDOWS # define HAVE_STRUCT_STAT_ST_BIRTHTIME of_time_interval_t st_birthtime; DWORD fileAttributes; # endif } of_stat_t; #elif defined(OF_HAVE_OFF64_T) typedef struct stat64 of_stat_t; #else typedef struct stat of_stat_t; #endif #ifdef OF_WINDOWS # define S_IFLNK 0x10000 # define S_ISLNK(mode) (mode & S_IFLNK) #endif #if defined(OF_HAVE_CHOWN) && defined(OF_HAVE_THREADS) && !defined(OF_AMIGAOS) static OFMutex *passwdMutex; #endif #if !defined(HAVE_READDIR_R) && defined(OF_HAVE_THREADS) && !defined(OF_WINDOWS) static OFMutex *readdirMutex; #endif #ifdef OF_WINDOWS static WINAPI BOOLEAN (*func_CreateSymbolicLinkW)(LPCWSTR, LPCWSTR, DWORD); #endif #ifdef OF_AMIGAOS4 extern struct ExecIFace *IExec; static struct Library *DOSBase = NULL; static struct DOSIFace *IDOS = NULL; static struct Library *LocaleBase = NULL; static struct LocaleIFace *ILocale = NULL; OF_DESTRUCTOR() { if (ILocale != NULL) DropInterface((struct Interface *)ILocale); if (LocaleBase != NULL) CloseLibrary(LocaleBase); if (IDOS != NULL) DropInterface((struct Interface *)IDOS); if (DOSBase != NULL) CloseLibrary(DOSBase); } #endif #ifdef OF_WINDOWS static of_time_interval_t filetimeToTimeInterval(const FILETIME *filetime) { return (double)((int64_t)filetime->dwHighDateTime << 32 | filetime->dwLowDateTime) / 10000000.0 - 11644473600.0; } static void setErrno(void) { switch (GetLastError()) { case ERROR_FILE_NOT_FOUND: case ERROR_PATH_NOT_FOUND: case ERROR_NO_MORE_FILES: errno = ENOENT; return; case ERROR_ACCESS_DENIED: errno = EACCES; return; case ERROR_DIRECTORY: errno = ENOTDIR; return; case ERROR_NOT_READY: errno = EBUSY; return; } errno = 0; } #endif static int of_stat(OFString *path, of_stat_t *buffer) { #if defined(OF_WINDOWS) WIN32_FILE_ATTRIBUTE_DATA data; if (!GetFileAttributesExW(path.UTF16String, GetFileExInfoStandard, &data)) { setErrno(); return -1; } buffer->st_size = (uint64_t)data.nFileSizeHigh << 32 | data.nFileSizeLow; if (data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) buffer->st_mode = S_IFDIR; else if (data.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) { WIN32_FIND_DATAW findData; HANDLE findHandle; if ((findHandle = FindFirstFileW(path.UTF16String, &findData)) == INVALID_HANDLE_VALUE) { setErrno(); return -1; } @try { if (!(findData.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)) { /* Race? Indicate to try again. */ errno = EAGAIN; return -1; } buffer->st_mode = (findData.dwReserved0 == IO_REPARSE_TAG_SYMLINK ? S_IFLNK : S_IFREG); } @finally { FindClose(findHandle); } } else buffer->st_mode = S_IFREG; buffer->st_mode |= (data.dwFileAttributes & FILE_ATTRIBUTE_READONLY ? (S_IRUSR | S_IXUSR) : (S_IRUSR | S_IWUSR | S_IXUSR)); buffer->st_atime = filetimeToTimeInterval(&data.ftLastAccessTime); buffer->st_mtime = filetimeToTimeInterval(&data.ftLastWriteTime); buffer->st_ctime = buffer->st_birthtime = filetimeToTimeInterval(&data.ftCreationTime); buffer->fileAttributes = data.dwFileAttributes; return 0; #elif defined(OF_AMIGAOS) BPTR lock; # ifdef OF_AMIGAOS4 struct ExamineData *ed; # else struct FileInfoBlock fib; # endif of_time_interval_t timeInterval; struct Locale *locale; struct DateStamp *date; if ((lock = Lock([path cStringWithEncoding: [OFLocale encoding]], SHARED_LOCK)) == 0) { switch (IoErr()) { case ERROR_OBJECT_IN_USE: case ERROR_DISK_NOT_VALIDATED: errno = EBUSY; break; case ERROR_OBJECT_NOT_FOUND: errno = ENOENT; break; default: errno = 0; break; } return -1; } # if defined(OF_MORPHOS) if (!Examine64(lock, &fib, TAG_DONE)) { # elif defined(OF_AMIGAOS4) if ((ed = ExamineObjectTags(EX_FileLockInput, lock, TAG_END)) == NULL) { # else if (!Examine(lock, &fib)) { # endif UnLock(lock); errno = 0; return -1; } UnLock(lock); # if defined(OF_MORPHOS) buffer->st_size = fib.fib_Size64; # elif defined(OF_AMIGAOS4) buffer->st_size = ed->FileSize; # else buffer->st_size = fib.fib_Size; # endif # ifdef OF_AMIGAOS4 buffer->st_mode = (EXD_IS_DIRECTORY(ed) ? S_IFDIR : S_IFREG); # else buffer->st_mode = (fib.fib_DirEntryType > 0 ? S_IFDIR : S_IFREG); # endif timeInterval = 252460800; /* 1978-01-01 */ locale = OpenLocale(NULL); /* * FIXME: This does not take DST into account. But unfortunately, there * is no way to figure out if DST was in effect when the file was * modified. */ timeInterval += locale->loc_GMTOffset * 60.0; CloseLocale(locale); # ifdef OF_AMIGAOS4 date = &ed->Date; # else date = &fib.fib_Date; # endif timeInterval += date->ds_Days * 86400.0; timeInterval += date->ds_Minute * 60.0; timeInterval += date->ds_Tick / (of_time_interval_t)TICKS_PER_SECOND; buffer->st_atime = buffer->st_mtime = buffer->st_ctime = timeInterval; # ifdef OF_AMIGAOS4 FreeDosObject(DOS_EXAMINEDATA, ed); # endif return 0; #elif defined(OF_HAVE_OFF64_T) return stat64([path cStringWithEncoding: [OFLocale encoding]], buffer); #else return stat([path cStringWithEncoding: [OFLocale encoding]], buffer); #endif } static int of_lstat(OFString *path, of_stat_t *buffer) { #if defined(HAVE_LSTAT) && !defined(OF_WINDOWS) && !defined(OF_AMIGAOS) && \ !defined(OF_NINTENDO_3DS) && !defined(OF_WII) # ifdef OF_HAVE_OFF64_T return lstat64([path cStringWithEncoding: [OFLocale encoding]], buffer); # else return lstat([path cStringWithEncoding: [OFLocale encoding]], buffer); # endif #else return of_stat(path, buffer); #endif } static void setTypeAttribute(of_mutable_file_attributes_t attributes, of_stat_t *s) { if (S_ISREG(s->st_mode)) [attributes setObject: of_file_type_regular forKey: of_file_attribute_key_type]; else if (S_ISDIR(s->st_mode)) [attributes setObject: of_file_type_directory forKey: of_file_attribute_key_type]; #ifdef S_ISLNK else if (S_ISLNK(s->st_mode)) [attributes setObject: of_file_type_symbolic_link forKey: of_file_attribute_key_type]; #endif #ifdef S_ISFIFO else if (S_ISFIFO(s->st_mode)) [attributes setObject: of_file_type_fifo forKey: of_file_attribute_key_type]; #endif #ifdef S_ISCHR else if (S_ISCHR(s->st_mode)) [attributes setObject: of_file_type_character_special forKey: of_file_attribute_key_type]; #endif #ifdef S_ISBLK else if (S_ISBLK(s->st_mode)) [attributes setObject: of_file_type_block_special forKey: of_file_attribute_key_type]; #endif #ifdef S_ISSOCK else if (S_ISSOCK(s->st_mode)) [attributes setObject: of_file_type_socket forKey: of_file_attribute_key_type]; #endif } static void setDateAttributes(of_mutable_file_attributes_t attributes, of_stat_t *s) { /* FIXME: We could be more precise on some OSes */ [attributes setObject: [OFDate dateWithTimeIntervalSince1970: s->st_atime] forKey: of_file_attribute_key_last_access_date]; [attributes setObject: [OFDate dateWithTimeIntervalSince1970: s->st_mtime] forKey: of_file_attribute_key_modification_date]; [attributes setObject: [OFDate dateWithTimeIntervalSince1970: s->st_ctime] forKey: of_file_attribute_key_status_change_date]; #ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME [attributes setObject: [OFDate dateWithTimeIntervalSince1970: s->st_birthtime] forKey: of_file_attribute_key_creation_date]; #endif } static void setOwnerAndGroupAttributes(of_mutable_file_attributes_t attributes, of_stat_t *s) { #ifdef OF_FILE_MANAGER_SUPPORTS_OWNER [attributes setObject: [NSNumber numberWithUInt16: s->st_uid] forKey: of_file_attribute_key_posix_uid]; [attributes setObject: [NSNumber numberWithUInt16: s->st_gid] forKey: of_file_attribute_key_posix_gid]; # ifdef OF_HAVE_THREADS [passwdMutex lock]; @try { # endif of_string_encoding_t encoding = [OFLocale encoding]; struct passwd *passwd = getpwuid(s->st_uid); struct group *group_ = getgrgid(s->st_gid); if (passwd != NULL) { OFString *owner = [OFString stringWithCString: passwd->pw_name encoding: encoding]; [attributes setObject: owner forKey: of_file_attribute_key_owner]; } if (group_ != NULL) { OFString *group = [OFString stringWithCString: group_->gr_name encoding: encoding]; [attributes setObject: group forKey: of_file_attribute_key_group]; } # ifdef OF_HAVE_THREADS } @finally { [passwdMutex unlock]; } # endif #endif } #ifdef OF_FILE_MANAGER_SUPPORTS_SYMLINKS static void setSymbolicLinkDestinationAttribute(of_mutable_file_attributes_t attributes, OFURL *URL) { OFString *path = URL.fileSystemRepresentation; # ifndef OF_WINDOWS of_string_encoding_t encoding = [OFLocale encoding]; char destinationC[PATH_MAX]; ssize_t length; OFString *destination; of_file_attribute_key_t key; length = readlink([path cStringWithEncoding: encoding], destinationC, PATH_MAX); if (length < 0) @throw [OFRetrieveItemAttributesFailedException exceptionWithURL: URL errNo: errno]; destination = [OFString stringWithCString: destinationC encoding: encoding length: length]; key = of_file_attribute_key_symbolic_link_destination; [attributes setObject: destination forKey: key]; # else HANDLE handle; OFString *destination; if (func_CreateSymbolicLinkW == NULL) return; if ((handle = CreateFileW(path.UTF16String, 0, (FILE_SHARE_READ | FILE_SHARE_WRITE), NULL, OPEN_EXISTING, FILE_FLAG_OPEN_REPARSE_POINT, NULL)) == INVALID_HANDLE_VALUE) @throw [OFRetrieveItemAttributesFailedException exceptionWithURL: URL errNo: 0]; @try { union { char bytes[MAXIMUM_REPARSE_DATA_BUFFER_SIZE]; REPARSE_DATA_BUFFER data; } buffer; DWORD size; wchar_t *tmp; of_file_attribute_key_t key; if (!DeviceIoControl(handle, FSCTL_GET_REPARSE_POINT, NULL, 0, buffer.bytes, MAXIMUM_REPARSE_DATA_BUFFER_SIZE, &size, NULL)) @throw [OFRetrieveItemAttributesFailedException exceptionWithURL: URL errNo: 0]; if (buffer.data.ReparseTag != IO_REPARSE_TAG_SYMLINK) @throw [OFRetrieveItemAttributesFailedException exceptionWithURL: URL errNo: 0]; # define slrb buffer.data.SymbolicLinkReparseBuffer tmp = slrb.PathBuffer + (slrb.SubstituteNameOffset / sizeof(wchar_t)); destination = [OFString stringWithUTF16String: tmp length: slrb.SubstituteNameLength / sizeof(wchar_t)]; [attributes setObject: of_file_type_symbolic_link forKey: of_file_attribute_key_type]; key = of_file_attribute_key_symbolic_link_destination; [attributes setObject: destination forKey: key]; # undef slrb } @finally { CloseHandle(handle); } # endif } #endif @implementation OFFileURLHandler + (void)initialize { #ifdef OF_WINDOWS HMODULE module; #endif if (self != [OFFileURLHandler class]) return; #ifdef OF_AMIGAOS4 if ((DOSBase = OpenLibrary("dos.library", 36)) == NULL) @throw [OFInitializationFailedException exceptionWithClass: self]; if ((IDOS = (struct DOSIFace *) GetInterface(DOSBase, "main", 1, NULL)) == NULL) @throw [OFInitializationFailedException exceptionWithClass: self]; if ((LocaleBase = OpenLibrary("locale.library", 38)) == NULL) @throw [OFInitializationFailedException exceptionWithClass: self]; if ((ILocale = (struct LocaleIFace *) GetInterface(LocaleBase, "main", 1, NULL)) == NULL) @throw [OFInitializationFailedException exceptionWithClass: self]; #endif #if defined(OF_HAVE_CHOWN) && defined(OF_HAVE_THREADS) passwdMutex = [[OFMutex alloc] init]; #endif #if !defined(HAVE_READDIR_R) && !defined(OF_WINDOWS) && defined(OF_HAVE_THREADS) readdirMutex = [[OFMutex alloc] init]; #endif #ifdef OF_WINDOWS if ((module = LoadLibrary("kernel32.dll")) != NULL) func_CreateSymbolicLinkW = (WINAPI BOOLEAN (*)(LPCWSTR, LPCWSTR, DWORD)) GetProcAddress(module, "CreateSymbolicLinkW"); #endif /* * Make sure OFFile is initialized. * On some systems, this is needed to initialize the file system driver. */ [OFFile class]; } + (bool)of_directoryExistsAtPath: (OFString *)path { of_stat_t s; if (of_stat(path, &s) == -1) return false; return S_ISDIR(s.st_mode); } - (OFStream *)openItemAtURL: (OFURL *)URL mode: (OFString *)mode { void *pool = objc_autoreleasePoolPush(); OFFile *file = [[OFFile alloc] initWithPath: URL.fileSystemRepresentation mode: mode]; objc_autoreleasePoolPop(pool); return [file autorelease]; } - (of_file_attributes_t)attributesOfItemAtURL: (OFURL *)URL { of_mutable_file_attributes_t ret = [OFMutableDictionary dictionary]; void *pool = objc_autoreleasePoolPush(); OFString *path; of_stat_t s; if (URL == nil) @throw [OFInvalidArgumentException exception]; if (![[URL scheme] isEqual: _scheme]) @throw [OFInvalidArgumentException exception]; path = URL.fileSystemRepresentation; if (of_lstat(path, &s) == -1) @throw [OFRetrieveItemAttributesFailedException exceptionWithURL: URL errNo: errno]; if (s.st_size < 0) @throw [OFOutOfRangeException exception]; [ret setObject: [NSNumber numberWithUIntMax: s.st_size] forKey: of_file_attribute_key_size]; setTypeAttribute(ret, &s); [ret setObject: [NSNumber numberWithUInt16: s.st_mode & 07777] forKey: of_file_attribute_key_posix_permissions]; setOwnerAndGroupAttributes(ret, &s); setDateAttributes(ret, &s); #ifdef OF_FILE_MANAGER_SUPPORTS_SYMLINKS if (S_ISLNK(s.st_mode)) setSymbolicLinkDestinationAttribute(ret, URL); #endif objc_autoreleasePoolPop(pool); return ret; } - (void)of_setPOSIXPermissions: (OFNumber *)permissions ofItemAtURL: (OFURL *)URL attributes: (of_file_attributes_t)attributes { #ifdef OF_FILE_MANAGER_SUPPORTS_PERMISSIONS uint16_t mode = permissions.uInt16Value & 0777; OFString *path = URL.fileSystemRepresentation; # ifndef OF_WINDOWS if (chmod([path cStringWithEncoding: [OFLocale encoding]], mode) != 0) # else if (_wchmod(path.UTF16String, mode) != 0) # endif @throw [OFSetItemAttributesFailedException exceptionWithURL: URL attributes: attributes failedAttribute: of_file_attribute_key_posix_permissions errNo: errno]; #else OF_UNRECOGNIZED_SELECTOR #endif } - (void)of_setOwner: (OFString *)owner andGroup: (OFString *)group ofItemAtURL: (OFURL *)URL attributeKey: (of_file_attribute_key_t)attributeKey attributes: (of_file_attributes_t)attributes { #ifdef OF_FILE_MANAGER_SUPPORTS_OWNER OFString *path = URL.fileSystemRepresentation; uid_t uid = -1; gid_t gid = -1; of_string_encoding_t encoding; if (owner == nil && group == nil) @throw [OFInvalidArgumentException exception]; encoding = [OFLocale encoding]; # ifdef OF_HAVE_THREADS [passwdMutex lock]; @try { # endif if (owner != nil) { struct passwd *passwd; if ((passwd = getpwnam([owner cStringWithEncoding: encoding])) == NULL) @throw [OFSetItemAttributesFailedException exceptionWithURL: URL attributes: attributes failedAttribute: attributeKey errNo: errno]; uid = passwd->pw_uid; } if (group != nil) { struct group *group_; if ((group_ = getgrnam([group cStringWithEncoding: encoding])) == NULL) @throw [OFSetItemAttributesFailedException exceptionWithURL: URL attributes: attributes failedAttribute: attributeKey errNo: errno]; gid = group_->gr_gid; } # ifdef OF_HAVE_THREADS } @finally { [passwdMutex unlock]; } # endif if (chown([path cStringWithEncoding: encoding], uid, gid) != 0) @throw [OFSetItemAttributesFailedException exceptionWithURL: URL attributes: attributes failedAttribute: attributeKey errNo: errno]; #else OF_UNRECOGNIZED_SELECTOR #endif } - (void)setAttributes: (of_file_attributes_t)attributes ofItemAtURL: (OFURL *)URL { void *pool = objc_autoreleasePoolPush(); OFEnumerator OF_GENERIC(of_file_attribute_key_t) *keyEnumerator; OFEnumerator *objectEnumerator; of_file_attribute_key_t key; id object; if (URL == nil) @throw [OFInvalidArgumentException exception]; if (![URL.scheme isEqual: _scheme]) @throw [OFInvalidArgumentException exception]; keyEnumerator = [attributes keyEnumerator]; objectEnumerator = [attributes objectEnumerator]; while ((key = [keyEnumerator nextObject]) != nil && (object = [objectEnumerator nextObject]) != nil) { if ([key isEqual: of_file_attribute_key_posix_permissions]) [self of_setPOSIXPermissions: object ofItemAtURL: URL attributes: attributes]; else if ([key isEqual: of_file_attribute_key_owner]) [self of_setOwner: object andGroup: nil ofItemAtURL: URL attributeKey: key attributes: attributes]; else if ([key isEqual: of_file_attribute_key_group]) [self of_setOwner: nil andGroup: object ofItemAtURL: URL attributeKey: key attributes: attributes]; else @throw [OFNotImplementedException exceptionWithSelector: _cmd object: self]; } objc_autoreleasePoolPop(pool); } - (bool)fileExistsAtURL: (OFURL *)URL { void *pool = objc_autoreleasePoolPush(); of_stat_t s; bool ret; if (URL == nil) @throw [OFInvalidArgumentException exception]; if (![URL.scheme isEqual: _scheme]) @throw [OFInvalidArgumentException exception]; if (of_stat(URL.fileSystemRepresentation, &s) == -1) { objc_autoreleasePoolPop(pool); return false; } ret = S_ISREG(s.st_mode); objc_autoreleasePoolPop(pool); return ret; } - (bool)directoryExistsAtURL: (OFURL *)URL { void *pool = objc_autoreleasePoolPush(); of_stat_t s; bool ret; if (URL == nil) @throw [OFInvalidArgumentException exception]; if (![URL.scheme isEqual: _scheme]) @throw [OFInvalidArgumentException exception]; if (of_stat(URL.fileSystemRepresentation, &s) == -1) { objc_autoreleasePoolPop(pool); return false; } ret = S_ISDIR(s.st_mode); objc_autoreleasePoolPop(pool); return ret; } - (void)createDirectoryAtURL: (OFURL *)URL { void *pool = objc_autoreleasePoolPush(); OFString *path; if (URL == nil) @throw [OFInvalidArgumentException exception]; if (![URL.scheme isEqual: _scheme]) @throw [OFInvalidArgumentException exception]; path = URL.fileSystemRepresentation; #if defined(OF_WINDOWS) if (_wmkdir(path.UTF16String) != 0) @throw [OFCreateDirectoryFailedException exceptionWithURL: URL errNo: errno]; #elif defined(OF_AMIGAOS) BPTR lock; if ((lock = CreateDir( [path cStringWithEncoding: [OFLocale encoding]])) == 0) { int errNo; switch (IoErr()) { case ERROR_NO_FREE_STORE: case ERROR_DISK_FULL: errNo = ENOSPC; break; case ERROR_OBJECT_IN_USE: case ERROR_DISK_NOT_VALIDATED: errNo = EBUSY; break; case ERROR_OBJECT_EXISTS: errNo = EEXIST; break; case ERROR_OBJECT_NOT_FOUND: errNo = ENOENT; break; case ERROR_DISK_WRITE_PROTECTED: errNo = EROFS; break; default: errNo = 0; break; } @throw [OFCreateDirectoryFailedException exceptionWithURL: URL errNo: errNo]; } UnLock(lock); #else if (mkdir([path cStringWithEncoding: [OFLocale encoding]], 0777) != 0) @throw [OFCreateDirectoryFailedException exceptionWithURL: URL errNo: errno]; #endif objc_autoreleasePoolPop(pool); } - (OFArray OF_GENERIC(OFString *) *)contentsOfDirectoryAtURL: (OFURL *)URL { OFMutableArray *files = [OFMutableArray array]; void *pool = objc_autoreleasePoolPush(); OFString *path; if (URL == nil) @throw [OFInvalidArgumentException exception]; if (![URL.scheme isEqual: _scheme]) @throw [OFInvalidArgumentException exception]; path = URL.fileSystemRepresentation; #if defined(OF_WINDOWS) HANDLE handle; WIN32_FIND_DATAW fd; path = [path stringByAppendingString: @"\\*"]; if ((handle = FindFirstFileW(path.UTF16String, &fd)) == INVALID_HANDLE_VALUE) { int errNo = 0; if (GetLastError() == ERROR_FILE_NOT_FOUND) errNo = ENOENT; @throw [OFOpenItemFailedException exceptionWithURL: URL mode: nil errNo: errNo]; } @try { do { OFString *file; if (!wcscmp(fd.cFileName, L".") || !wcscmp(fd.cFileName, L"..")) continue; file = [[OFString alloc] initWithUTF16String: fd.cFileName]; @try { [files addObject: file]; } @finally { [file release]; } } while (FindNextFileW(handle, &fd)); if (GetLastError() != ERROR_NO_MORE_FILES) @throw [OFReadFailedException exceptionWithObject: self requestedLength: 0 errNo: EIO]; } @finally { FindClose(handle); } #elif defined(OF_AMIGAOS) of_string_encoding_t encoding = [OFLocale encoding]; BPTR lock; if ((lock = Lock([path cStringWithEncoding: encoding], SHARED_LOCK)) == 0) { int errNo; switch (IoErr()) { case ERROR_OBJECT_IN_USE: case ERROR_DISK_NOT_VALIDATED: errNo = EBUSY; break; case ERROR_OBJECT_NOT_FOUND: errNo = ENOENT; break; default: errNo = 0; break; } @throw [OFOpenItemFailedException exceptionWithURL: URL mode: nil errNo: errNo]; } @try { # ifdef OF_AMIGAOS4 struct ExamineData *ed; APTR context; if ((context = ObtainDirContextTags(EX_FileLockInput, lock, EX_DoCurrentDir, TRUE, EX_DataFields, EXF_NAME, TAG_END)) == NULL) @throw [OFOpenItemFailedException exceptionWithURL: URL mode: nil errNo: 0]; @try { while ((ed = ExamineDir(context)) != NULL) { OFString *file = [[OFString alloc] initWithCString: ed->Name encoding: encoding]; @try { [files addObject: file]; } @finally { [file release]; } } } @finally { ReleaseDirContext(context); } # else struct FileInfoBlock fib; if (!Examine(lock, &fib)) @throw [OFOpenItemFailedException exceptionWithURL: URL mode: nil errNo: 0]; while (ExNext(lock, &fib)) { OFString *file = [[OFString alloc] initWithCString: fib.fib_FileName encoding: encoding]; @try { [files addObject: file]; } @finally { [file release]; } } # endif if (IoErr() != ERROR_NO_MORE_ENTRIES) @throw [OFReadFailedException exceptionWithObject: self requestedLength: 0 errNo: EIO]; } @finally { UnLock(lock); } #else of_string_encoding_t encoding = [OFLocale encoding]; DIR *dir; if ((dir = opendir([path cStringWithEncoding: encoding])) == NULL) @throw [OFOpenItemFailedException exceptionWithURL: URL mode: nil errNo: errno]; # if !defined(HAVE_READDIR_R) && defined(OF_HAVE_THREADS) @try { [readdirMutex lock]; } @catch (id e) { closedir(dir); @throw e; } # endif @try { for (;;) { struct dirent *dirent; # ifdef HAVE_READDIR_R struct dirent buffer; # endif OFString *file; # ifdef HAVE_READDIR_R if (readdir_r(dir, &buffer, &dirent) != 0) @throw [OFReadFailedException exceptionWithObject: self requestedLength: 0 errNo: errno]; if (dirent == NULL) break; # else errno = 0; if ((dirent = readdir(dir)) == NULL) { if (errno == 0) break; else @throw [OFReadFailedException exceptionWithObject: self requestedLength: 0 errNo: errno]; } # endif if (strcmp(dirent->d_name, ".") == 0 || strcmp(dirent->d_name, "..") == 0) continue; file = [[OFString alloc] initWithCString: dirent->d_name encoding: encoding]; @try { [files addObject: file]; } @finally { [file release]; } } } @finally { closedir(dir); # if !defined(HAVE_READDIR_R) && defined(OF_HAVE_THREADS) [readdirMutex unlock]; # endif } #endif [files makeImmutable]; objc_autoreleasePoolPop(pool); return files; } - (void)removeItemAtURL: (OFURL *)URL { void *pool = objc_autoreleasePoolPush(); OFString *path; of_stat_t s; if (URL == nil) @throw [OFInvalidArgumentException exception]; if (![URL.scheme isEqual: _scheme]) @throw [OFInvalidArgumentException exception]; path = URL.fileSystemRepresentation; if (of_lstat(path, &s) != 0) @throw [OFRemoveItemFailedException exceptionWithURL: URL errNo: errno]; if (S_ISDIR(s.st_mode)) { OFArray *contents; @try { contents = [self contentsOfDirectoryAtURL: URL]; } @catch (id e) { /* * Only convert exceptions to * OFRemoveItemFailedException that have an errNo * property. This covers all I/O related exceptions * from the operations used to remove an item, all * others should be left as is. */ if ([e respondsToSelector: @selector(errNo)]) @throw [OFRemoveItemFailedException exceptionWithURL: URL errNo: [e errNo]]; @throw e; } for (OFString *item in contents) { void *pool2 = objc_autoreleasePoolPush(); [self removeItemAtURL: [OFURL fileURLWithPath: [path stringByAppendingPathComponent: item]]]; objc_autoreleasePoolPop(pool2); } #ifndef OF_AMIGAOS # ifndef OF_WINDOWS if (rmdir([path cStringWithEncoding: [OFLocale encoding]]) != 0) # else if (_wrmdir(path.UTF16String) != 0) # endif @throw [OFRemoveItemFailedException exceptionWithURL: URL errNo: errno]; } else { # ifndef OF_WINDOWS if (unlink([path cStringWithEncoding: [OFLocale encoding]]) != 0) # else if (_wunlink(path.UTF16String) != 0) # endif @throw [OFRemoveItemFailedException exceptionWithURL: URL errNo: errno]; #endif } #ifdef OF_AMIGAOS if (!DeleteFile([path cStringWithEncoding: [OFLocale encoding]])) { int errNo; switch (IoErr()) { case ERROR_OBJECT_IN_USE: case ERROR_DISK_NOT_VALIDATED: errNo = EBUSY; break; case ERROR_OBJECT_NOT_FOUND: errNo = ENOENT; break; case ERROR_DISK_WRITE_PROTECTED: errNo = EROFS; break; case ERROR_DELETE_PROTECTED: errNo = EACCES; break; default: errNo = 0; break; } @throw [OFRemoveItemFailedException exceptionWithURL: URL errNo: errNo]; } #endif objc_autoreleasePoolPop(pool); } #ifdef OF_FILE_MANAGER_SUPPORTS_LINKS - (void)linkItemAtURL: (OFURL *)source toURL: (OFURL *)destination { void *pool = objc_autoreleasePoolPush(); OFString *sourcePath, *destinationPath; if (source == nil || destination == nil) @throw [OFInvalidArgumentException exception]; if (![source.scheme isEqual: _scheme] || ![destination.scheme isEqual: _scheme]) @throw [OFInvalidArgumentException exception]; sourcePath = source.fileSystemRepresentation; destinationPath = destination.fileSystemRepresentation; # ifndef OF_WINDOWS of_string_encoding_t encoding = [OFLocale encoding]; if (link([sourcePath cStringWithEncoding: encoding], [destinationPath cStringWithEncoding: encoding]) != 0) @throw [OFLinkFailedException exceptionWithSourceURL: source destinationURL: destination errNo: errno]; # else if (!CreateHardLinkW(destinationPath.UTF16String, sourcePath.UTF16String, NULL)) @throw [OFLinkFailedException exceptionWithSourceURL: source destinationURL: destination errNo: 0]; # endif objc_autoreleasePoolPop(pool); } #endif #ifdef OF_FILE_MANAGER_SUPPORTS_SYMLINKS - (void)createSymbolicLinkAtURL: (OFURL *)URL withDestinationPath: (OFString *)target { void *pool = objc_autoreleasePoolPush(); OFString *path; if (URL == nil || target == nil) @throw [OFInvalidArgumentException exception]; if (![URL.scheme isEqual: _scheme]) @throw [OFInvalidArgumentException exception]; path = URL.fileSystemRepresentation; # ifndef OF_WINDOWS of_string_encoding_t encoding = [OFLocale encoding]; if (symlink([target cStringWithEncoding: encoding], [path cStringWithEncoding: encoding]) != 0) @throw [OFCreateSymbolicLinkFailedException exceptionWithURL: URL target: target errNo: errno]; # else if (func_CreateSymbolicLinkW == NULL) @throw [OFNotImplementedException exceptionWithSelector: _cmd object: self]; if (!func_CreateSymbolicLinkW(path.UTF16String, target.UTF16String, 0)) @throw [OFCreateSymbolicLinkFailedException exceptionWithURL: URL target: target errNo: 0]; # endif objc_autoreleasePoolPop(pool); } #endif - (bool)moveItemAtURL: (OFURL *)source toURL: (OFURL *)destination { void *pool; if (![source.scheme isEqual: _scheme] || ![destination.scheme isEqual: _scheme]) return false; if ([self fileExistsAtURL: destination]) @throw [OFMoveItemFailedException exceptionWithSourceURL: source destinationURL: destination errNo: EEXIST]; pool = objc_autoreleasePoolPush(); #if defined(OF_WINDOWS) if (_wrename(source.fileSystemRepresentation.UTF16String, destination.fileSystemRepresentation.UTF16String) != 0) @throw [OFMoveItemFailedException exceptionWithSourceURL: source destinationURL: destination errNo: errno]; #elif defined(OF_AMIGAOS) of_string_encoding_t encoding = [OFLocale encoding]; if (!Rename([source.fileSystemRepresentation cStringWithEncoding: encoding], [destination.fileSystemRepresentation cStringWithEncoding: encoding])) { int errNo; switch (IoErr()) { case ERROR_RENAME_ACROSS_DEVICES: errNo = EXDEV; break; case ERROR_OBJECT_IN_USE: case ERROR_DISK_NOT_VALIDATED: errNo = EBUSY; break; case ERROR_OBJECT_EXISTS: errNo = EEXIST; break; case ERROR_OBJECT_NOT_FOUND: errNo = ENOENT; break; case ERROR_DISK_WRITE_PROTECTED: errNo = EROFS; break; default: errNo = 0; break; } @throw [OFMoveItemFailedException exceptionWithSourceURL: source destinationURL: destination errNo: errNo]; } #else of_string_encoding_t encoding = [OFLocale encoding]; if (rename([source.fileSystemRepresentation cStringWithEncoding: encoding], [destination.fileSystemRepresentation cStringWithEncoding: encoding]) != 0) @throw [OFMoveItemFailedException exceptionWithSourceURL: source destinationURL: destination errNo: errno]; #endif objc_autoreleasePoolPop(pool); return true; } @end |
Modified src/OFHTTPClient.m from [e2bb72d5a2] to [fd3a2fecad].
︙ | ︙ | |||
90 91 92 93 94 95 96 | } @property (nonatomic, setter=of_setKeepAlive:) bool of_keepAlive; - (instancetype)initWithSocket: (OFTCPSocket *)sock; @end | | | 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 | } @property (nonatomic, setter=of_setKeepAlive:) bool of_keepAlive; - (instancetype)initWithSocket: (OFTCPSocket *)sock; @end @interface OFHTTPClientSyncPerformer: OFObject <OFHTTPClientDelegate> { OFHTTPClient *_client; OFObject <OFHTTPClientDelegate> *_delegate; OFHTTPResponse *_response; } - (instancetype)initWithClient: (OFHTTPClient *)client; |
︙ | ︙ | |||
997 998 999 1000 1001 1002 1003 | [_socket release]; _socket = nil; [super close]; } @end | | | 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 | [_socket release]; _socket = nil; [super close]; } @end @implementation OFHTTPClientSyncPerformer - (instancetype)initWithClient: (OFHTTPClient *)client { self = [super init]; @try { _client = [client retain]; _delegate = client.delegate; |
︙ | ︙ | |||
1141 1142 1143 1144 1145 1146 1147 | redirects: REDIRECTS_DEFAULT]; } - (OFHTTPResponse *)performRequest: (OFHTTPRequest *)request redirects: (unsigned int)redirects { void *pool = objc_autoreleasePoolPush(); | | | | 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 | redirects: REDIRECTS_DEFAULT]; } - (OFHTTPResponse *)performRequest: (OFHTTPRequest *)request redirects: (unsigned int)redirects { void *pool = objc_autoreleasePoolPush(); OFHTTPClientSyncPerformer *syncPerformer = [[[OFHTTPClientSyncPerformer alloc] initWithClient: self] autorelease]; OFHTTPResponse *response = [syncPerformer performRequest: request redirects: redirects]; [response retain]; objc_autoreleasePoolPop(pool); |
︙ | ︙ |
Modified src/OFHTTPServer.m from [a4d123787e] to [59f972c93b].
︙ | ︙ | |||
64 65 66 67 68 69 70 | } - (instancetype)initWithSocket: (OFTCPSocket *)sock server: (OFHTTPServer *)server request: (OFHTTPRequest *)request; @end | | | 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 | } - (instancetype)initWithSocket: (OFTCPSocket *)sock server: (OFHTTPServer *)server request: (OFHTTPRequest *)request; @end @interface OFHTTPServerConnection: OFObject <OFTCPSocketDelegate> { @public OFTCPSocket *_socket; OFHTTPServer *_server; OFTimer *_timer; enum { AWAITING_PROLOG, |
︙ | ︙ | |||
365 366 367 368 369 370 371 | if (_socket == nil) return -1; return _socket.fileDescriptorForWriting; } @end | | | 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 | if (_socket == nil) return -1; return _socket.fileDescriptorForWriting; } @end @implementation OFHTTPServerConnection - (instancetype)initWithSocket: (OFTCPSocket *)sock server: (OFHTTPServer *)server { self = [super init]; @try { _socket = [sock retain]; |
︙ | ︙ | |||
941 942 943 944 945 946 947 | [_threadPool release]; _threadPool = nil; #endif } - (void)of_handleAcceptedSocket: (OFTCPSocket *)acceptedSocket { | | | 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 | [_threadPool release]; _threadPool = nil; #endif } - (void)of_handleAcceptedSocket: (OFTCPSocket *)acceptedSocket { OFHTTPServerConnection *connection = [[[OFHTTPServerConnection alloc] initWithSocket: acceptedSocket server: self] autorelease]; acceptedSocket.delegate = connection; [acceptedSocket asyncReadLine]; } |
︙ | ︙ |
Added src/OFHTTPURLHandler.h version [9220399ab4].
> > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | /* * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, * 2018, 2019 * Jonathan Schleifer <js@heap.zone> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #import "OFURLHandler.h" OF_ASSUME_NONNULL_BEGIN @interface OFHTTPURLHandler: OFURLHandler @end OF_ASSUME_NONNULL_END |
Added src/OFHTTPURLHandler.m version [58a5e06e80].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | /* * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, * 2018, 2019 * Jonathan Schleifer <js@heap.zone> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #import "OFHTTPURLHandler.h" #import "OFHTTPClient.h" #import "OFHTTPRequest.h" #import "OFHTTPResponse.h" @implementation OFHTTPURLHandler - (OFStream *)openItemAtURL: (OFURL *)URL mode: (OFString *)mode { void *pool = objc_autoreleasePoolPush(); OFHTTPClient *client = [OFHTTPClient client]; OFHTTPRequest *request = [OFHTTPRequest requestWithURL: URL]; OFHTTPResponse *response = [client performRequest: request]; [response retain]; objc_autoreleasePoolPop(pool); return [response autorelease]; } @end |
Modified src/OFINICategory.m from [aa5333e1f9] to [ac82dbaf9a].
︙ | ︙ | |||
22 23 24 25 26 27 28 | #import "OFArray.h" #import "OFString.h" #import "OFStream.h" #import "OFInvalidArgumentException.h" #import "OFInvalidFormatException.h" | | | | 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | #import "OFArray.h" #import "OFString.h" #import "OFStream.h" #import "OFInvalidArgumentException.h" #import "OFInvalidFormatException.h" @interface OFINICategoryPair: OFObject { @public OFString *_key, *_value; } @end @interface OFINICategoryComment: OFObject { @public OFString *_comment; } @end static OFString * |
︙ | ︙ | |||
96 97 98 99 100 101 102 | withString: @"\\"]; [mutableString makeImmutable]; return mutableString; } | | | | 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 | withString: @"\\"]; [mutableString makeImmutable]; return mutableString; } @implementation OFINICategoryPair - (void)dealloc { [_key release]; [_value release]; [super dealloc]; } @end @implementation OFINICategoryComment - (void)dealloc { [_comment release]; [super dealloc]; } @end |
︙ | ︙ | |||
149 150 151 152 153 154 155 | [super dealloc]; } - (void)of_parseLine: (OFString *)line { if (![line hasPrefix: @";"]) { | | | | 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 | [super dealloc]; } - (void)of_parseLine: (OFString *)line { if (![line hasPrefix: @";"]) { OFINICategoryPair *pair = [[[OFINICategoryPair alloc] init] autorelease]; OFString *key, *value; size_t pos; if ((pos = [line rangeOfString: @"="].location) == OF_NOT_FOUND) @throw [OFInvalidFormatException exception]; key = [line substringWithRange: of_range(0, pos)]; |
︙ | ︙ | |||
172 173 174 175 176 177 178 | value = unescapeString(value); pair->_key = [key copy]; pair->_value = [value copy]; [_lines addObject: pair]; } else { | | | | | | 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 | value = unescapeString(value); pair->_key = [key copy]; pair->_value = [value copy]; [_lines addObject: pair]; } else { OFINICategoryComment *comment = [[[OFINICategoryComment alloc] init] autorelease]; comment->_comment = [line copy]; [_lines addObject: comment]; } } - (OFString *)stringForKey: (OFString *)key { return [self stringForKey: key defaultValue: nil]; } - (OFString *)stringForKey: (OFString *)key defaultValue: (OFString *)defaultValue { for (id line in _lines) { OFINICategoryPair *pair; if (![line isKindOfClass: [OFINICategoryPair class]]) continue; pair = line; if ([pair->_key isEqual: key]) return [[pair->_value copy] autorelease]; } |
︙ | ︙ | |||
291 292 293 294 295 296 297 | - (OFArray *)arrayForKey: (OFString *)key { OFMutableArray *ret = [OFMutableArray array]; void *pool = objc_autoreleasePoolPush(); for (id line in _lines) { | | | | | | | 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 | - (OFArray *)arrayForKey: (OFString *)key { OFMutableArray *ret = [OFMutableArray array]; void *pool = objc_autoreleasePoolPush(); for (id line in _lines) { OFINICategoryPair *pair; if (![line isKindOfClass: [OFINICategoryPair class]]) continue; pair = line; if ([pair->_key isEqual: key]) [ret addObject: [[pair->_value copy] autorelease]]; } objc_autoreleasePoolPop(pool); [ret makeImmutable]; return ret; } - (void)setString: (OFString *)string forKey: (OFString *)key { void *pool = objc_autoreleasePoolPush(); OFINICategoryPair *pair; for (id line in _lines) { if (![line isKindOfClass: [OFINICategoryPair class]]) continue; pair = line; if ([pair->_key isEqual: key]) { OFString *old = pair->_value; pair->_value = [string copy]; [old release]; objc_autoreleasePoolPop(pool); return; } } pair = [[[OFINICategoryPair alloc] init] autorelease]; pair->_key = nil; pair->_value = nil; @try { pair->_key = [key copy]; pair->_value = [string copy]; [_lines addObject: pair]; |
︙ | ︙ | |||
409 410 411 412 413 414 415 | } pool = objc_autoreleasePoolPush(); pairs = [OFMutableArray arrayWithCapacity: array.count]; for (id object in array) { | | | | | | 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 | } pool = objc_autoreleasePoolPush(); pairs = [OFMutableArray arrayWithCapacity: array.count]; for (id object in array) { OFINICategoryPair *pair; if (![object isKindOfClass: [OFString class]]) @throw [OFInvalidArgumentException exception]; pair = [[[OFINICategoryPair alloc] init] autorelease]; pair->_key = [key copy]; pair->_value = [object copy]; [pairs addObject: pair]; } lines = _lines.objects; count = _lines.count; replaced = false; for (size_t i = 0; i < count; i++) { OFINICategoryPair *pair; if (![lines[i] isKindOfClass: [OFINICategoryPair class]]) continue; pair = lines[i]; if ([pair->_key isEqual: key]) { [_lines removeObjectAtIndex: i]; |
︙ | ︙ | |||
466 467 468 469 470 471 472 | - (void)removeValueForKey: (OFString *)key { void *pool = objc_autoreleasePoolPush(); id const *lines = _lines.objects; size_t count = _lines.count; for (size_t i = 0; i < count; i++) { | | | | 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 | - (void)removeValueForKey: (OFString *)key { void *pool = objc_autoreleasePoolPush(); id const *lines = _lines.objects; size_t count = _lines.count; for (size_t i = 0; i < count; i++) { OFINICategoryPair *pair; if (![lines[i] isKindOfClass: [OFINICategoryPair class]]) continue; pair = lines[i]; if ([pair->_key isEqual: key]) { [_lines removeObjectAtIndex: i]; |
︙ | ︙ | |||
500 501 502 503 504 505 506 | if (first) [stream writeFormat: @"[%@]\r\n", _name]; else [stream writeFormat: @"\r\n[%@]\r\n", _name]; for (id line in _lines) { | | | | | | 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 | if (first) [stream writeFormat: @"[%@]\r\n", _name]; else [stream writeFormat: @"\r\n[%@]\r\n", _name]; for (id line in _lines) { if ([line isKindOfClass: [OFINICategoryComment class]]) { OFINICategoryComment *comment = line; [stream writeFormat: @"%@\r\n", comment->_comment]; } else if ([line isKindOfClass: [OFINICategoryPair class]]) { OFINICategoryPair *pair = line; OFString *key = escapeString(pair->_key); OFString *value = escapeString(pair->_value); OFString *tmp = [OFString stringWithFormat: @"%@=%@\r\n", key, value]; [stream writeString: tmp encoding: encoding]; |
︙ | ︙ |
Added src/OFINIFileSettings.h version [0f40811c1f].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | /* * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, * 2018, 2019 * Jonathan Schleifer <js@heap.zone> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #import "OFSettings.h" OF_ASSUME_NONNULL_BEGIN @class OFString; @class OFINIFile; @interface OFINIFileSettings: OFSettings { OFString *_filePath; OFINIFile *_INIFile; } @end OF_ASSUME_NONNULL_END |
Added src/OFINIFileSettings.m version [8d209cd409].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 | /* * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, * 2018, 2019 * Jonathan Schleifer <js@heap.zone> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #import "OFINIFileSettings.h" #import "OFString.h" #import "OFArray.h" #import "OFINIFile.h" #import "OFSystemInfo.h" @implementation OFINIFileSettings - (instancetype)initWithApplicationName: (OFString *)applicationName { self = [super initWithApplicationName: applicationName]; @try { void *pool = objc_autoreleasePoolPush(); OFString *fileName; fileName = [applicationName stringByAppendingString: @".ini"]; _filePath = [[[OFSystemInfo userConfigPath] stringByAppendingPathComponent: fileName] copy]; _INIFile = [[OFINIFile alloc] initWithPath: _filePath]; objc_autoreleasePoolPop(pool); } @catch (id e) { [self release]; @throw e; } return self; } - (void)dealloc { [_filePath release]; [_INIFile release]; [super dealloc]; } - (void)of_getCategory: (OFString **)category andKey: (OFString **)key forPath: (OFString *)path { size_t pos = [path rangeOfString: @"." options: OF_STRING_SEARCH_BACKWARDS].location; if (pos == OF_NOT_FOUND) { *category = @""; *key = path; return; } *category = [path substringWithRange: of_range(0, pos)]; *key = [path substringWithRange: of_range(pos + 1, path.length - pos - 1)]; } - (void)setString: (OFString *)string forPath: (OFString *)path { void *pool = objc_autoreleasePoolPush(); OFString *category, *key; [self of_getCategory: &category andKey: &key forPath: path]; [[_INIFile categoryForName: category] setString: string forKey: key]; objc_autoreleasePoolPop(pool); } - (void)setInteger: (intmax_t)integer forPath: (OFString *)path { void *pool = objc_autoreleasePoolPush(); OFString *category, *key; [self of_getCategory: &category andKey: &key forPath: path]; [[_INIFile categoryForName: category] setInteger: integer forKey: key]; objc_autoreleasePoolPop(pool); } - (void)setBool: (bool)bool_ forPath: (OFString *)path { void *pool = objc_autoreleasePoolPush(); OFString *category, *key; [self of_getCategory: &category andKey: &key forPath: path]; [[_INIFile categoryForName: category] setBool: bool_ forKey: key]; objc_autoreleasePoolPop(pool); } - (void)setFloat: (float)float_ forPath: (OFString *)path { void *pool = objc_autoreleasePoolPush(); OFString *category, *key; [self of_getCategory: &category andKey: &key forPath: path]; [[_INIFile categoryForName: category] setFloat: float_ forKey: key]; objc_autoreleasePoolPop(pool); } - (void)setDouble: (double)double_ forPath: (OFString *)path { void *pool = objc_autoreleasePoolPush(); OFString *category, *key; [self of_getCategory: &category andKey: &key forPath: path]; [[_INIFile categoryForName: category] setDouble: double_ forKey: key]; objc_autoreleasePoolPop(pool); } - (void)setArray: (OFArray *)array forPath: (OFString *)path { void *pool = objc_autoreleasePoolPush(); OFString *category, *key; [self of_getCategory: &category andKey: &key forPath: path]; [[_INIFile categoryForName: category] setArray: array forKey: key]; objc_autoreleasePoolPop(pool); } - (OFString *)stringForPath: (OFString *)path defaultValue: (OFString *)defaultValue { void *pool = objc_autoreleasePoolPush(); OFString *category, *key, *ret; [self of_getCategory: &category andKey: &key forPath: path]; ret = [[_INIFile categoryForName: category] stringForKey: key defaultValue: defaultValue]; [ret retain]; objc_autoreleasePoolPop(pool); return [ret autorelease]; } - (intmax_t)integerForPath: (OFString *)path defaultValue: (intmax_t)defaultValue { void *pool = objc_autoreleasePoolPush(); OFString *category, *key; intmax_t ret; [self of_getCategory: &category andKey: &key forPath: path]; ret = [[_INIFile categoryForName: category] integerForKey: key defaultValue: defaultValue]; objc_autoreleasePoolPop(pool); return ret; } - (bool)boolForPath: (OFString *)path defaultValue: (bool)defaultValue { void *pool = objc_autoreleasePoolPush(); OFString *category, *key; bool ret; [self of_getCategory: &category andKey: &key forPath: path]; ret = [[_INIFile categoryForName: category] boolForKey: key defaultValue: defaultValue]; objc_autoreleasePoolPop(pool); return ret; } - (float)floatForPath: (OFString *)path defaultValue: (float)defaultValue { void *pool = objc_autoreleasePoolPush(); OFString *category, *key; float ret; [self of_getCategory: &category andKey: &key forPath: path]; ret = [[_INIFile categoryForName: category] floatForKey: key defaultValue: defaultValue]; objc_autoreleasePoolPop(pool); return ret; } - (double)doubleForPath: (OFString *)path defaultValue: (double)defaultValue { void *pool = objc_autoreleasePoolPush(); OFString *category, *key; double ret; [self of_getCategory: &category andKey: &key forPath: path]; ret = [[_INIFile categoryForName: category] doubleForKey: key defaultValue: defaultValue]; objc_autoreleasePoolPop(pool); return ret; } - (OFArray *)arrayForPath: (OFString *)path { void *pool = objc_autoreleasePoolPush(); OFString *category, *key; OFArray *ret; [self of_getCategory: &category andKey: &key forPath: path]; ret = [[_INIFile categoryForName: category] arrayForKey: key]; [ret retain]; objc_autoreleasePoolPop(pool); return [ret autorelease]; } - (void)removeValueForPath: (OFString *)path { void *pool = objc_autoreleasePoolPush(); OFString *category, *key; [self of_getCategory: &category andKey: &key forPath: path]; [[_INIFile categoryForName: category] removeValueForKey: key]; objc_autoreleasePoolPop(pool); } - (void)save { [_INIFile writeToFile: _filePath]; } @end |
Added src/OFInvertedCharacterSet.h version [e78ee993d6].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | /* * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, * 2018, 2019 * Jonathan Schleifer <js@heap.zone> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #import "OFCharacterSet.h" OF_ASSUME_NONNULL_BEGIN @interface OFInvertedCharacterSet: OFCharacterSet { OFCharacterSet *_characterSet; bool (*_characterIsMember)(id, SEL, of_unichar_t); } - (instancetype)of_initWithCharacterSet: (OFCharacterSet *)characterSet OF_METHOD_FAMILY(init); @end OF_ASSUME_NONNULL_END |
Added src/OFInvertedCharacterSet.m version [df368518f8].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 | /* * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, * 2018, 2019 * Jonathan Schleifer <js@heap.zone> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #import "OFInvertedCharacterSet.h" #import "OFString.h" #import "OFOutOfRangeException.h" @implementation OFInvertedCharacterSet - (instancetype)init { OF_INVALID_INIT_METHOD } - (instancetype)of_initWithCharacterSet: (OFCharacterSet *)characterSet { self = [super init]; _characterSet = [characterSet retain]; _characterIsMember = (bool (*)(id, SEL, of_unichar_t)) [_characterSet methodForSelector: @selector(characterIsMember:)]; return self; } - (void)dealloc { [_characterSet release]; [super dealloc]; } - (bool)characterIsMember: (of_unichar_t)character { return !_characterIsMember(_characterSet, @selector(characterIsMember:), character); } - (OFCharacterSet *)invertedSet { return [[_characterSet retain] autorelease]; } @end |
Modified src/OFKernelEventObserver.m from [68149c85a6] to [b61a7255dc].
︙ | ︙ | |||
21 22 23 24 25 26 27 28 29 30 31 32 | #include <errno.h> #import "OFKernelEventObserver.h" #import "OFKernelEventObserver+Private.h" #import "OFArray.h" #import "OFData.h" #import "OFStream.h" #import "OFStream+Private.h" #ifndef OF_HAVE_PIPE # import "OFStreamSocket.h" #endif | > > > > < < < < | | | | | 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 | #include <errno.h> #import "OFKernelEventObserver.h" #import "OFKernelEventObserver+Private.h" #import "OFArray.h" #import "OFData.h" #import "OFDate.h" #ifdef OF_HAVE_THREADS # import "OFMutex.h" #endif #import "OFStream.h" #import "OFStream+Private.h" #ifndef OF_HAVE_PIPE # import "OFStreamSocket.h" #endif #ifdef HAVE_KQUEUE # import "OFKqueueKernelEventObserver.h" #endif #ifdef HAVE_EPOLL # import "OFEpollKernelEventObserver.h" #endif #ifdef HAVE_POLL # import "OFPollKernelEventObserver.h" #endif #ifdef HAVE_SELECT # import "OFSelectKernelEventObserver.h" #endif #import "OFInitializationFailedException.h" #import "OFInvalidArgumentException.h" #import "OFOutOfRangeException.h" #import "socket.h" |
︙ | ︙ | |||
81 82 83 84 85 86 87 | return [[[self alloc] init] autorelease]; } + (instancetype)alloc { if (self == [OFKernelEventObserver class]) #if defined(HAVE_KQUEUE) | | | | | | 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 | return [[[self alloc] init] autorelease]; } + (instancetype)alloc { if (self == [OFKernelEventObserver class]) #if defined(HAVE_KQUEUE) return [OFKqueueKernelEventObserver alloc]; #elif defined(HAVE_EPOLL) return [OFEpollKernelEventObserver alloc]; #elif defined(HAVE_POLL) return [OFPollKernelEventObserver alloc]; #elif defined(HAVE_SELECT) return [OFSelectKernelEventObserver alloc]; #else # error No kqueue / epoll / poll / select found! #endif return [super alloc]; } |
︙ | ︙ |
Deleted src/OFKernelEventObserver_epoll.h version [cb8e611f95].
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted src/OFKernelEventObserver_epoll.m version [c7d873c63a].
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted src/OFKernelEventObserver_kqueue.h version [e672c854db].
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted src/OFKernelEventObserver_kqueue.m version [48331f17e7].
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted src/OFKernelEventObserver_poll.h version [68e1cc67aa].
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted src/OFKernelEventObserver_poll.m version [e0fcf68d56].
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted src/OFKernelEventObserver_select.h version [eebc599a17].
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted src/OFKernelEventObserver_select.m version [02729f3714].
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Added src/OFKqueueKernelEventObserver.h version [93173a129b].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | /* * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, * 2018, 2019 * Jonathan Schleifer <js@heap.zone> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #import "OFKernelEventObserver.h" OF_ASSUME_NONNULL_BEGIN @class OFMutableArray OF_GENERIC(ObjectType); @interface OFKqueueKernelEventObserver: OFKernelEventObserver { int _kernelQueue; } @end OF_ASSUME_NONNULL_END |
Added src/OFKqueueKernelEventObserver.m version [436780f050].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 | /* * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, * 2018, 2019 * Jonathan Schleifer <js@heap.zone> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #include <assert.h> #include <errno.h> #include <math.h> #ifdef HAVE_FCNTL_H # include <fcntl.h> #endif #include "unistd_wrapper.h" #include <sys/types.h> #include <sys/event.h> #include <sys/time.h> #import "OFKqueueKernelEventObserver.h" #import "OFArray.h" #import "OFKernelEventObserver.h" #import "OFKernelEventObserver+Private.h" #ifdef OF_HAVE_THREADS # import "OFMutex.h" #endif #import "OFInitializationFailedException.h" #import "OFObserveFailedException.h" #import "OFOutOfRangeException.h" #define EVENTLIST_SIZE 64 @implementation OFKqueueKernelEventObserver - (instancetype)init { self = [super init]; @try { struct kevent event; #ifdef HAVE_KQUEUE1 if ((_kernelQueue = kqueue1(O_CLOEXEC)) == -1) @throw [OFInitializationFailedException exceptionWithClass: self.class]; #else int flags; if ((_kernelQueue = kqueue()) == -1) @throw [OFInitializationFailedException exceptionWithClass: self.class]; if ((flags = fcntl(_kernelQueue, F_GETFD, 0)) != -1) fcntl(_kernelQueue, F_SETFD, flags | FD_CLOEXEC); #endif EV_SET(&event, _cancelFD[0], EVFILT_READ, EV_ADD, 0, 0, 0); if (kevent(_kernelQueue, &event, 1, NULL, 0, NULL) != 0) @throw [OFInitializationFailedException exceptionWithClass: self.class]; } @catch (id e) { [self release]; @throw e; } return self; } - (void)dealloc { close(_kernelQueue); [super dealloc]; } - (void)of_addObjectForReading: (id <OFReadyForReadingObserving>)object { struct kevent event; memset(&event, 0, sizeof(event)); event.ident = object.fileDescriptorForReading; event.filter = EVFILT_READ; event.flags = EV_ADD; #ifndef OF_NETBSD event.udata = object; #else event.udata = (intptr_t)object; #endif if (kevent(_kernelQueue, &event, 1, NULL, 0, NULL) != 0) @throw [OFObserveFailedException exceptionWithObserver: self errNo: errno]; } - (void)of_addObjectForWriting: (id <OFReadyForWritingObserving>)object { struct kevent event; memset(&event, 0, sizeof(event)); event.ident = object.fileDescriptorForWriting; event.filter = EVFILT_WRITE; event.flags = EV_ADD; #ifndef OF_NETBSD event.udata = object; #else event.udata = (intptr_t)object; #endif if (kevent(_kernelQueue, &event, 1, NULL, 0, NULL) != 0) @throw [OFObserveFailedException exceptionWithObserver: self errNo: errno]; } - (void)of_removeObjectForReading: (id <OFReadyForReadingObserving>)object { struct kevent event; memset(&event, 0, sizeof(event)); event.ident = object.fileDescriptorForReading; event.filter = EVFILT_READ; event.flags = EV_DELETE; if (kevent(_kernelQueue, &event, 1, NULL, 0, NULL) != 0) @throw [OFObserveFailedException exceptionWithObserver: self errNo: errno]; } - (void)of_removeObjectForWriting: (id <OFReadyForWritingObserving>)object { struct kevent event; memset(&event, 0, sizeof(event)); event.ident = object.fileDescriptorForWriting; event.filter = EVFILT_WRITE; event.flags = EV_DELETE; if (kevent(_kernelQueue, &event, 1, NULL, 0, NULL) != 0) @throw [OFObserveFailedException exceptionWithObserver: self errNo: errno]; } - (void)observeForTimeInterval: (of_time_interval_t)timeInterval { struct timespec timeout; struct kevent eventList[EVENTLIST_SIZE]; int events; [self of_processQueue]; if ([self of_processReadBuffers]) return; timeout.tv_sec = (time_t)timeInterval; timeout.tv_nsec = lrint((timeInterval - timeout.tv_sec) * 1000000000); events = kevent(_kernelQueue, NULL, 0, eventList, EVENTLIST_SIZE, (timeInterval != -1 ? &timeout : NULL)); if (events < 0) @throw [OFObserveFailedException exceptionWithObserver: self errNo: errno]; for (int i = 0; i < events; i++) { void *pool; if (eventList[i].flags & EV_ERROR) @throw [OFObserveFailedException exceptionWithObserver: self errNo: (int)eventList[i].data]; if (eventList[i].ident == (uintptr_t)_cancelFD[0]) { char buffer; assert(eventList[i].filter == EVFILT_READ); OF_ENSURE(read(_cancelFD[0], &buffer, 1) == 1); continue; } pool = objc_autoreleasePoolPush(); switch (eventList[i].filter) { case EVFILT_READ: if ([_delegate respondsToSelector: @selector(objectIsReadyForReading:)]) [_delegate objectIsReadyForReading: (id)eventList[i].udata]; break; case EVFILT_WRITE: if ([_delegate respondsToSelector: @selector(objectIsReadyForWriting:)]) [_delegate objectIsReadyForWriting: (id)eventList[i].udata]; break; default: assert(0); } objc_autoreleasePoolPop(pool); } } @end |
Modified src/OFLHAArchive.m from [ba6f864ebc] to [e91adc15fc].
︙ | ︙ | |||
19 20 21 22 23 24 25 | #import "OFLHAArchive.h" #import "OFLHAArchiveEntry.h" #import "OFLHAArchiveEntry+Private.h" #ifdef OF_HAVE_FILES # import "OFFile.h" #endif | | | | | 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 | #import "OFLHAArchive.h" #import "OFLHAArchiveEntry.h" #import "OFLHAArchiveEntry+Private.h" #ifdef OF_HAVE_FILES # import "OFFile.h" #endif #import "OFLHADecompressingStream.h" #import "OFStream.h" #import "OFSeekableStream.h" #import "OFString.h" #import "crc16.h" #import "OFChecksumMismatchException.h" #import "OFInvalidArgumentException.h" #import "OFNotImplementedException.h" #import "OFNotOpenException.h" #import "OFOutOfRangeException.h" #import "OFTruncatedDataException.h" #import "OFWriteFailedException.h" @interface OFLHAArchiveFileReadStream: OFStream <OFReadyForReadingObserving> { OFStream *_stream, *_decompressedStream; OFLHAArchiveEntry *_entry; uint32_t _toRead, _bytesConsumed; uint16_t _CRC16; bool _atEndOfStream, _skipped; } - (instancetype)of_initWithStream: (OFStream *)stream entry: (OFLHAArchiveEntry *)entry; - (void)of_skip; @end @interface OFLHAArchiveFileWriteStream: OFStream <OFReadyForWritingObserving> { OFMutableLHAArchiveEntry *_entry; of_string_encoding_t _encoding; OFSeekableStream *_stream; of_offset_t _headerOffset; uint32_t _bytesWritten; uint16_t _CRC16; |
︙ | ︙ | |||
162 163 164 165 166 167 168 | OFLHAArchiveEntry *entry; char header[21]; size_t headerLen; if (_mode != OF_LHA_ARCHIVE_MODE_READ) @throw [OFInvalidArgumentException exception]; | | | 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 | OFLHAArchiveEntry *entry; char header[21]; size_t headerLen; if (_mode != OF_LHA_ARCHIVE_MODE_READ) @throw [OFInvalidArgumentException exception]; [(OFLHAArchiveFileReadStream *)_lastReturnedStream of_skip]; [_lastReturnedStream close]; [_lastReturnedStream release]; _lastReturnedStream = nil; for (headerLen = 0; headerLen < 21;) { if (_stream.atEndOfStream) { if (headerLen == 0) |
︙ | ︙ | |||
187 188 189 190 191 192 193 | } entry = [[[OFLHAArchiveEntry alloc] of_initWithHeader: header stream: _stream encoding: _encoding] autorelease]; | | | | 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 | } entry = [[[OFLHAArchiveEntry alloc] of_initWithHeader: header stream: _stream encoding: _encoding] autorelease]; _lastReturnedStream = [[OFLHAArchiveFileReadStream alloc] of_initWithStream: _stream entry: entry]; return entry; } - (OFStream <OFReadyForReadingObserving> *)streamForReadingCurrentEntry { if (_mode != OF_LHA_ARCHIVE_MODE_READ) @throw [OFInvalidArgumentException exception]; if (_lastReturnedStream == nil) @throw [OFInvalidArgumentException exception]; return [[(OFLHAArchiveFileReadStream *)_lastReturnedStream retain] autorelease]; } - (OFStream <OFReadyForWritingObserving> *) streamForWritingEntry: (OFLHAArchiveEntry *)entry { OFString *compressionMethod; |
︙ | ︙ | |||
226 227 228 229 230 231 232 | @throw [OFNotImplementedException exceptionWithSelector: _cmd object: self]; [_lastReturnedStream close]; [_lastReturnedStream release]; _lastReturnedStream = nil; | | | | | | | | 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 | @throw [OFNotImplementedException exceptionWithSelector: _cmd object: self]; [_lastReturnedStream close]; [_lastReturnedStream release]; _lastReturnedStream = nil; _lastReturnedStream = [[OFLHAArchiveFileWriteStream alloc] of_initWithStream: (OFSeekableStream *)_stream entry: entry encoding: _encoding]; return [[(OFLHAArchiveFileWriteStream *)_lastReturnedStream retain] autorelease]; } - (void)close { if (_stream == nil) return; [_lastReturnedStream close]; [_lastReturnedStream release]; _lastReturnedStream = nil; [_stream release]; _stream = nil; } @end @implementation OFLHAArchiveFileReadStream - (instancetype)of_initWithStream: (OFStream *)stream entry: (OFLHAArchiveEntry *)entry { self = [super init]; @try { OFString *compressionMethod; _stream = [stream retain]; compressionMethod = entry.compressionMethod; if ([compressionMethod isEqual: @"-lh4-"] || [compressionMethod isEqual: @"-lh5-"]) _decompressedStream = [[OFLHADecompressingStream alloc] of_initWithStream: stream distanceBits: 4 dictionaryBits: 14]; else if ([compressionMethod isEqual: @"-lh6-"]) _decompressedStream = [[OFLHADecompressingStream alloc] of_initWithStream: stream distanceBits: 5 dictionaryBits: 16]; else if ([compressionMethod isEqual: @"-lh7-"]) _decompressedStream = [[OFLHADecompressingStream alloc] of_initWithStream: stream distanceBits: 5 dictionaryBits: 17]; else _decompressedStream = [stream retain]; _entry = [entry copy]; |
︙ | ︙ | |||
379 380 381 382 383 384 385 | toRead = _toRead; /* * Get the number of consumed bytes and directly read from the * compressed stream, to make skipping much faster. */ if ([_decompressedStream isKindOfClass: | | | | | > | | 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 | toRead = _toRead; /* * Get the number of consumed bytes and directly read from the * compressed stream, to make skipping much faster. */ if ([_decompressedStream isKindOfClass: [OFLHADecompressingStream class]]) { OFLHADecompressingStream *decompressingStream = (OFLHADecompressingStream *)_decompressedStream; [decompressingStream close]; toRead = _entry.compressedSize - decompressingStream->_bytesConsumed; stream = _stream; } if ([stream isKindOfClass: [OFSeekableStream class]] && (sizeof(of_offset_t) > 4 || toRead < INT32_MAX)) [(OFSeekableStream *)stream seekToOffset: (of_offset_t)toRead |
︙ | ︙ | |||
424 425 426 427 428 429 430 | [_decompressedStream release]; _decompressedStream = nil; [super close]; } @end | | | 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 | [_decompressedStream release]; _decompressedStream = nil; [super close]; } @end @implementation OFLHAArchiveFileWriteStream - (instancetype)of_initWithStream: (OFSeekableStream *)stream entry: (OFLHAArchiveEntry *)entry encoding: (of_string_encoding_t)encoding { self = [super init]; @try { |
︙ | ︙ |
Deleted src/OFLHAArchive_LHStream.h version [3e10c9b21e].
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted src/OFLHAArchive_LHStream.m version [53f546e890].
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Added src/OFLHADecompressingStream.h version [1fd5de7afc].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | /* * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, * 2018, 2019 * Jonathan Schleifer <js@heap.zone> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #import "OFStream.h" OF_ASSUME_NONNULL_BEGIN #define OF_LHA_DECOMPRESSING_STREAM_BUFFER_SIZE 4096 @interface OFLHADecompressingStream: OFStream { @public OFStream *_stream; uint8_t _distanceBits, _dictionaryBits; unsigned char _buffer[OF_LHA_DECOMPRESSING_STREAM_BUFFER_SIZE]; uint32_t _bytesConsumed; uint16_t _bufferIndex, _bufferLength; uint8_t _byte; uint8_t _bitIndex, _savedBitsLength; uint16_t _savedBits; unsigned char *_slidingWindow; uint32_t _slidingWindowIndex, _slidingWindowMask; int _state; uint16_t _symbolsLeft; struct of_huffman_tree *_Nullable _codeLenTree, *_Nullable _litLenTree; struct of_huffman_tree *_Nullable _distTree, *_Nullable _treeIter; uint16_t _codesCount, _codesReceived; bool _currentIsExtendedLength, _skip; uint8_t *_Nullable _codesLengths; uint16_t _length; uint32_t _distance; } - (instancetype)of_initWithStream: (OFStream *)stream distanceBits: (uint8_t)distanceBits dictionaryBits: (uint8_t)dictionaryBits; @end OF_ASSUME_NONNULL_END |
Added src/OFLHADecompressingStream.m version [f1d167ee49].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 | /* * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, * 2018, 2019 * Jonathan Schleifer <js@heap.zone> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #include <assert.h> #import "OFLHADecompressingStream.h" #import "OFKernelEventObserver.h" #import "huffman_tree.h" #import "OFInvalidFormatException.h" #import "OFNotOpenException.h" enum state { STATE_BLOCK_HEADER, STATE_CODE_LEN_CODES_COUNT, STATE_CODE_LEN_TREE, STATE_CODE_LEN_TREE_SINGLE, STATE_LITLEN_CODES_COUNT, STATE_LITLEN_TREE, STATE_LITLEN_TREE_SINGLE, STATE_DIST_CODES_COUNT, STATE_DIST_TREE, STATE_DIST_TREE_SINGLE, STATE_BLOCK_LITLEN, STATE_BLOCK_DIST_LENGTH, STATE_BLOCK_DIST_LENGTH_EXTRA, STATE_BLOCK_LEN_DIST_PAIR }; static OF_INLINE bool tryReadBits(OFLHADecompressingStream *stream, uint16_t *bits, uint8_t count) { uint16_t ret = stream->_savedBits; assert(stream->_savedBitsLength < count); for (uint_fast8_t i = stream->_savedBitsLength; i < count; i++) { if OF_UNLIKELY (stream->_bitIndex == 8) { if OF_LIKELY (stream->_bufferIndex < stream->_bufferLength) stream->_byte = stream->_buffer[stream->_bufferIndex++]; else { const size_t bufferLength = OF_LHA_DECOMPRESSING_STREAM_BUFFER_SIZE; size_t length = [stream->_stream readIntoBuffer: stream->_buffer length: bufferLength]; stream->_bytesConsumed += (uint32_t)length; if OF_UNLIKELY (length < 1) { stream->_savedBits = ret; stream->_savedBitsLength = i; return false; } stream->_byte = stream->_buffer[0]; stream->_bufferIndex = 1; stream->_bufferLength = (uint16_t)length; } stream->_bitIndex = 0; } ret = (ret << 1) | ((stream->_byte >> (7 - stream->_bitIndex++)) & 1); } stream->_savedBits = 0; stream->_savedBitsLength = 0; *bits = ret; return true; } @implementation OFLHADecompressingStream - (instancetype)of_initWithStream: (OFStream *)stream distanceBits: (uint8_t)distanceBits dictionaryBits: (uint8_t)dictionaryBits { self = [super init]; @try { _stream = [stream retain]; /* 0-7 address the bit, 8 means fetch next byte */ _bitIndex = 8; _distanceBits = distanceBits; _dictionaryBits = dictionaryBits; _slidingWindowMask = (1 << dictionaryBits) - 1; _slidingWindow = [self allocMemoryWithSize: _slidingWindowMask + 1]; memset(_slidingWindow, ' ', _slidingWindowMask + 1); } @catch (id e) { [self release]; @throw e; } return self; } - (void)dealloc { [self close]; if (_codeLenTree != NULL) of_huffman_tree_release(_codeLenTree); if (_litLenTree != NULL) of_huffman_tree_release(_litLenTree); if (_distTree != NULL) of_huffman_tree_release(_distTree); [super dealloc]; } - (size_t)lowlevelReadIntoBuffer: (void *)buffer_ length: (size_t)length { unsigned char *buffer = buffer_; uint16_t bits, value; size_t bytesWritten = 0; if (_stream == nil) @throw [OFNotOpenException exceptionWithObject: self]; if (_stream.atEndOfStream && _bufferLength - _bufferIndex == 0 && _state == STATE_BLOCK_HEADER) return 0; start: switch ((enum state)_state) { case STATE_BLOCK_HEADER: if OF_UNLIKELY (!tryReadBits(self, &bits, 16)) return bytesWritten; _symbolsLeft = bits; _state = STATE_CODE_LEN_CODES_COUNT; goto start; case STATE_CODE_LEN_CODES_COUNT: if OF_UNLIKELY (!tryReadBits(self, &bits, 5)) return bytesWritten; if OF_UNLIKELY (bits > 20) @throw [OFInvalidFormatException exception]; if OF_UNLIKELY (bits == 0) { _state = STATE_CODE_LEN_TREE_SINGLE; goto start; } _codesCount = bits; _codesReceived = 0; _codesLengths = [self allocZeroedMemoryWithSize: bits]; _skip = true; _state = STATE_CODE_LEN_TREE; goto start; case STATE_CODE_LEN_TREE: while (_codesReceived < _codesCount) { if OF_UNLIKELY (_currentIsExtendedLength) { if OF_UNLIKELY (!tryReadBits(self, &bits, 1)) return bytesWritten; if OF_UNLIKELY (bits == 0) { _codesReceived++; _currentIsExtendedLength = false; continue; } _codesLengths[_codesReceived]++; continue; } if OF_UNLIKELY (_codesReceived == 3 && _skip) { if OF_UNLIKELY (!tryReadBits(self, &bits, 2)) return bytesWritten; if OF_UNLIKELY (_codesReceived + bits > _codesCount) @throw [OFInvalidFormatException exception]; for (uint_fast8_t j = 0; j < bits; j++) _codesLengths[_codesReceived++] = 0; _skip = false; continue; } if OF_UNLIKELY (!tryReadBits(self, &bits, 3)) return bytesWritten; _codesLengths[_codesReceived] = bits; if OF_UNLIKELY (bits == 7) { _currentIsExtendedLength = true; continue; } else _codesReceived++; } _codeLenTree = of_huffman_tree_construct(_codesLengths, _codesCount); [self freeMemory: _codesLengths]; _state = STATE_LITLEN_CODES_COUNT; goto start; case STATE_CODE_LEN_TREE_SINGLE: if OF_UNLIKELY (!tryReadBits(self, &bits, 5)) return bytesWritten; _codeLenTree = of_huffman_tree_construct_single(bits); _state = STATE_LITLEN_CODES_COUNT; goto start; case STATE_LITLEN_CODES_COUNT: if OF_UNLIKELY (!tryReadBits(self, &bits, 9)) return bytesWritten; if OF_UNLIKELY (bits > 510) @throw [OFInvalidFormatException exception]; if OF_UNLIKELY (bits == 0) { of_huffman_tree_release(_codeLenTree); _codeLenTree = NULL; _state = STATE_LITLEN_TREE_SINGLE; goto start; } _codesCount = bits; _codesReceived = 0; _codesLengths = [self allocZeroedMemoryWithSize: bits]; _skip = false; _treeIter = _codeLenTree; _state = STATE_LITLEN_TREE; goto start; case STATE_LITLEN_TREE: while (_codesReceived < _codesCount) { if OF_UNLIKELY (_skip) { uint16_t skipCount; switch (_codesLengths[_codesReceived]) { case 0: skipCount = 1; break; case 1: if OF_UNLIKELY (!tryReadBits(self, &bits, 4)) return bytesWritten; skipCount = bits + 3; break; case 2: if OF_UNLIKELY (!tryReadBits(self, &bits, 9)) return bytesWritten; skipCount = bits + 20; break; default: OF_ENSURE(0); } if OF_UNLIKELY (_codesReceived + skipCount > _codesCount) @throw [OFInvalidFormatException exception]; for (uint_fast16_t j = 0; j < skipCount; j++) _codesLengths[_codesReceived++] = 0; _skip = false; continue; } if (!of_huffman_tree_walk(self, tryReadBits, &_treeIter, &value)) return bytesWritten; _treeIter = _codeLenTree; if (value < 3) { _codesLengths[_codesReceived] = value; _skip = true; } else _codesLengths[_codesReceived++] = value - 2; } _litLenTree = of_huffman_tree_construct(_codesLengths, _codesCount); [self freeMemory: _codesLengths]; of_huffman_tree_release(_codeLenTree); _codeLenTree = NULL; _state = STATE_DIST_CODES_COUNT; goto start; case STATE_LITLEN_TREE_SINGLE: if OF_UNLIKELY (!tryReadBits(self, &bits, 9)) return bytesWritten; _litLenTree = of_huffman_tree_construct_single(bits); _state = STATE_DIST_CODES_COUNT; goto start; case STATE_DIST_CODES_COUNT: if OF_UNLIKELY (!tryReadBits(self, &bits, _distanceBits)) return bytesWritten; if OF_UNLIKELY (bits > _dictionaryBits) @throw [OFInvalidFormatException exception]; if OF_UNLIKELY (bits == 0) { _state = STATE_DIST_TREE_SINGLE; goto start; } _codesCount = bits; _codesReceived = 0; _codesLengths = [self allocZeroedMemoryWithSize: bits]; _treeIter = _codeLenTree; _state = STATE_DIST_TREE; goto start; case STATE_DIST_TREE: while (_codesReceived < _codesCount) { if OF_UNLIKELY (_currentIsExtendedLength) { if OF_UNLIKELY (!tryReadBits(self, &bits, 1)) return bytesWritten; if OF_UNLIKELY (bits == 0) { _codesReceived++; _currentIsExtendedLength = false; continue; } _codesLengths[_codesReceived]++; continue; } if OF_UNLIKELY (!tryReadBits(self, &bits, 3)) return bytesWritten; _codesLengths[_codesReceived] = bits; if OF_UNLIKELY (bits == 7) { _currentIsExtendedLength = true; continue; } else _codesReceived++; } _distTree = of_huffman_tree_construct(_codesLengths, _codesCount); [self freeMemory: _codesLengths]; _treeIter = _litLenTree; _state = STATE_BLOCK_LITLEN; goto start; case STATE_DIST_TREE_SINGLE: if OF_UNLIKELY (!tryReadBits(self, &bits, _distanceBits)) return bytesWritten; _distTree = of_huffman_tree_construct_single(bits); _treeIter = _litLenTree; _state = STATE_BLOCK_LITLEN; goto start; case STATE_BLOCK_LITLEN: if OF_UNLIKELY (_symbolsLeft == 0) { of_huffman_tree_release(_litLenTree); of_huffman_tree_release(_distTree); _litLenTree = _distTree = NULL; _state = STATE_BLOCK_HEADER; /* * We must return here, as there is no indication * whether this was the last block. Whoever called this * method needs to check if everything has been read * already and only call read again if that is not the * case. * * We must also unread the buffer, in case this was the * last block and something else follows, e.g. another * LHA header. */ [_stream unreadFromBuffer: _buffer + _bufferIndex length: _bufferLength - _bufferIndex]; _bytesConsumed -= _bufferLength - _bufferIndex; _bufferIndex = _bufferLength = 0; return bytesWritten; } if OF_UNLIKELY (length == 0) return bytesWritten; if OF_UNLIKELY (!of_huffman_tree_walk(self, tryReadBits, &_treeIter, &value)) return bytesWritten; if OF_LIKELY (value < 256) { buffer[bytesWritten++] = value; length--; _slidingWindow[_slidingWindowIndex] = value; _slidingWindowIndex = (_slidingWindowIndex + 1) & _slidingWindowMask; _symbolsLeft--; _treeIter = _litLenTree; } else { _length = value - 253; _treeIter = _distTree; _state = STATE_BLOCK_DIST_LENGTH; } goto start; case STATE_BLOCK_DIST_LENGTH: if OF_UNLIKELY (!of_huffman_tree_walk(self, tryReadBits, &_treeIter, &value)) return bytesWritten; _distance = value; _state = (value < 2 ? STATE_BLOCK_LEN_DIST_PAIR : STATE_BLOCK_DIST_LENGTH_EXTRA); goto start; case STATE_BLOCK_DIST_LENGTH_EXTRA: if OF_UNLIKELY (!tryReadBits(self, &bits, _distance - 1)) return bytesWritten; _distance = bits + (1 << (_distance - 1)); _state = STATE_BLOCK_LEN_DIST_PAIR; goto start; case STATE_BLOCK_LEN_DIST_PAIR: for (uint_fast16_t i = 0; i < _length; i++) { uint32_t idx; if OF_UNLIKELY (length == 0) { _length -= i; return bytesWritten; } idx = (_slidingWindowIndex - _distance - 1) & _slidingWindowMask; value = _slidingWindow[idx]; buffer[bytesWritten++] = value; length--; _slidingWindow[_slidingWindowIndex] = value; _slidingWindowIndex = (_slidingWindowIndex + 1) & _slidingWindowMask; } _symbolsLeft--; _treeIter = _litLenTree; _state = STATE_BLOCK_LITLEN; goto start; } OF_UNREACHABLE } - (bool)lowlevelIsAtEndOfStream { if (_stream == nil) @throw [OFNotOpenException exceptionWithObject: self]; return (_stream.atEndOfStream && _bufferLength - _bufferIndex == 0 && _state == STATE_BLOCK_HEADER); } - (int)fileDescriptorForReading { return ((id <OFReadyForReadingObserving>)_stream) .fileDescriptorForReading; } - (bool)hasDataInReadBuffer { return (super.hasDataInReadBuffer || _stream.hasDataInReadBuffer || _bufferLength - _bufferIndex > 0); } - (void)close { /* Give back our buffer to the stream, in case it's shared */ [_stream unreadFromBuffer: _buffer + _bufferIndex length: _bufferLength - _bufferIndex]; _bytesConsumed -= _bufferLength - _bufferIndex; _bufferIndex = _bufferLength = 0; [_stream release]; _stream = nil; [super close]; } @end |
Modified src/OFMapTable+Private.h from [0db488d0c3] to [b8a57188f8].
︙ | ︙ | |||
15 16 17 18 19 20 21 | * file. */ #import "OFMapTable.h" OF_ASSUME_NONNULL_BEGIN | | | 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | * file. */ #import "OFMapTable.h" OF_ASSUME_NONNULL_BEGIN @interface OFMapTableEnumeratorWrapper: OFEnumerator { OFMapTableEnumerator *_enumerator; id _object; } - (instancetype)initWithEnumerator: (OFMapTableEnumerator *)enumerator object: (id)object; |
︙ | ︙ |
Modified src/OFMapTable.m from [566bcf99cb] to [916c94f96d].
︙ | ︙ | |||
722 723 724 725 726 727 728 | if (_position < _capacity) return &_buckets[_position++]->object; else return NULL; } @end | | | 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 | if (_position < _capacity) return &_buckets[_position++]->object; else return NULL; } @end @implementation OFMapTableEnumeratorWrapper - (instancetype)initWithEnumerator: (OFMapTableEnumerator *)enumerator object: (id)object { self = [super init]; _enumerator = [enumerator retain]; _object = [object retain]; |
︙ | ︙ |
Added src/OFMapTableDictionary.h version [c6f471998e].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | /* * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, * 2018, 2019 * Jonathan Schleifer <js@heap.zone> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #import "OFDictionary.h" OF_ASSUME_NONNULL_BEGIN @class OFMapTable; @class OFMapTableEnumerator; @interface OFMapTableDictionary: OFDictionary { OFMapTable *_mapTable; } - (instancetype)initWithCapacity: (size_t)capacity; @end OF_ASSUME_NONNULL_END |
Added src/OFMapTableDictionary.m version [d7532d8aaa].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 | /* * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, * 2018, 2019 * Jonathan Schleifer <js@heap.zone> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #include <assert.h> #import "OFMapTableDictionary.h" #import "OFArray.h" #import "OFMapTable+Private.h" #import "OFMapTable.h" #import "OFMutableMapTableDictionary.h" #import "OFString.h" #import "OFXMLElement.h" #import "OFEnumerationMutationException.h" #import "OFInvalidArgumentException.h" #import "OFInvalidFormatException.h" static void * copy(void *object) { return [(id)object copy]; } static void * retain(void *object) { return [(id)object retain]; } static void release(void *object) { [(id)object release]; } static uint32_t hash(void *object) { return [(id)object hash]; } static bool equal(void *object1, void *object2) { return [(id)object1 isEqual: (id)object2]; } static const of_map_table_functions_t keyFunctions = { .retain = copy, .release = release, .hash = hash, .equal = equal }; static const of_map_table_functions_t objectFunctions = { .retain = retain, .release = release, .hash = hash, .equal = equal }; @implementation OFMapTableDictionary - (instancetype)init { return [self initWithCapacity: 0]; } - (instancetype)initWithCapacity: (size_t)capacity { self = [super init]; @try { _mapTable = [[OFMapTable alloc] initWithKeyFunctions: keyFunctions objectFunctions: objectFunctions capacity: capacity]; } @catch (id e) { [self release]; @throw e; } return self; } - (instancetype)initWithDictionary: (OFDictionary *)dictionary { size_t count; if (dictionary == nil) return [self init]; if ([dictionary isKindOfClass: [OFMapTableDictionary class]] || [dictionary isKindOfClass: [OFMutableMapTableDictionary class]]) { self = [super init]; @try { OFMapTableDictionary *dictionary_ = (OFMapTableDictionary *)dictionary; _mapTable = [dictionary_->_mapTable copy]; } @catch (id e) { [self release]; @throw e; } return self; } @try { count = dictionary.count; } @catch (id e) { [self release]; @throw e; } self = [self initWithCapacity: count]; @try { void *pool = objc_autoreleasePoolPush(); OFEnumerator *keyEnumerator, *objectEnumerator; id key, object; keyEnumerator = [dictionary keyEnumerator]; objectEnumerator = [dictionary objectEnumerator]; while ((key = [keyEnumerator nextObject]) != nil && (object = [objectEnumerator nextObject]) != nil) [_mapTable setObject: object forKey: key]; objc_autoreleasePoolPop(pool); } @catch (id e) { [self release]; @throw e; } return self; } - (instancetype)initWithObject: (id)object forKey: (id)key { self = [self initWithCapacity: 1]; @try { [_mapTable setObject: object forKey: key]; } @catch (id e) { [self release]; @throw e; } return self; } - (instancetype)initWithObjects: (id const *)objects forKeys: (id const *)keys count: (size_t)count { self = [self initWithCapacity: count]; @try { size_t i; for (i = 0; i < count; i++) [_mapTable setObject: objects[i] forKey: keys[i]]; } @catch (id e) { [self release]; @throw e; } return self; } - (instancetype)initWithKey: (id)firstKey arguments: (va_list)arguments { self = [super init]; @try { va_list argumentsCopy; id key, object; size_t i, count; va_copy(argumentsCopy, arguments); if (firstKey == nil) @throw [OFInvalidArgumentException exception]; key = firstKey; if ((object = va_arg(arguments, id)) == nil) @throw [OFInvalidArgumentException exception]; count = 1; for (; va_arg(argumentsCopy, id) != nil; count++); if (count % 2 != 0) @throw [OFInvalidArgumentException exception]; count /= 2; _mapTable = [[OFMapTable alloc] initWithKeyFunctions: keyFunctions objectFunctions: objectFunctions capacity: count]; [_mapTable setObject: object forKey: key]; for (i = 1; i < count; i++) { key = va_arg(arguments, id); object = va_arg(arguments, id); if (key == nil || object == nil) @throw [OFInvalidArgumentException exception]; [_mapTable setObject: object forKey: key]; } } @catch (id e) { [self release]; @throw e; } return self; } - (instancetype)initWithSerialization: (OFXMLElement *)element { self = [super init]; @try { void *pool = objc_autoreleasePoolPush(); OFArray *keys, *objects; OFEnumerator *keyEnumerator, *objectEnumerator; OFXMLElement *keyElement, *objectElement; keys = [element elementsForName: @"key" namespace: OF_SERIALIZATION_NS]; objects = [element elementsForName: @"object" namespace: OF_SERIALIZATION_NS]; if (keys.count != objects.count) @throw [OFInvalidFormatException exception]; _mapTable = [[OFMapTable alloc] initWithKeyFunctions: keyFunctions objectFunctions: objectFunctions capacity: keys.count]; keyEnumerator = [keys objectEnumerator]; objectEnumerator = [objects objectEnumerator]; while ((keyElement = [keyEnumerator nextObject]) != nil && (objectElement = [objectEnumerator nextObject]) != nil) { void *pool2 = objc_autoreleasePoolPush(); OFXMLElement *key, *object; key = [keyElement elementsForNamespace: OF_SERIALIZATION_NS].firstObject; object = [objectElement elementsForNamespace: OF_SERIALIZATION_NS].firstObject; if (key == nil || object == nil) @throw [OFInvalidFormatException exception]; [_mapTable setObject: object.objectByDeserializing forKey: key.objectByDeserializing]; objc_autoreleasePoolPop(pool2); } objc_autoreleasePoolPop(pool); } @catch (id e) { [self release]; @throw e; } return self; } - (void)dealloc { [_mapTable release]; [super dealloc]; } - (id)objectForKey: (id)key { return [_mapTable objectForKey: key]; } - (size_t)count { return _mapTable.count; } - (bool)isEqual: (id)object { OFMapTableDictionary *dictionary; if (object == self) return true; if (![object isKindOfClass: [OFMapTableDictionary class]] && ![object isKindOfClass: [OFMutableMapTableDictionary class]]) return [super isEqual: object]; dictionary = (OFMapTableDictionary *)object; return [dictionary->_mapTable isEqual: _mapTable]; } - (bool)containsObject: (id)object { return [_mapTable containsObject: object]; } - (bool)containsObjectIdenticalTo: (id)object { return [_mapTable containsObjectIdenticalTo: object]; } - (OFArray *)allKeys { OFArray *ret; id *keys; size_t count; count = _mapTable.count; keys = [self allocMemoryWithSize: sizeof(*keys) count: count]; @try { void *pool = objc_autoreleasePoolPush(); OFMapTableEnumerator *enumerator; void **keyPtr; size_t i; i = 0; enumerator = [_mapTable keyEnumerator]; while ((keyPtr = [enumerator nextObject]) != NULL) { assert(i < count); keys[i++] = (id)*keyPtr; } objc_autoreleasePoolPop(pool); ret = [OFArray arrayWithObjects: keys count: count]; } @finally { [self freeMemory: keys]; } return ret; } - (OFArray *)allObjects { OFArray *ret; id *objects; size_t count; count = _mapTable.count; objects = [self allocMemoryWithSize: sizeof(*objects) count: count]; @try { void *pool = objc_autoreleasePoolPush(); OFMapTableEnumerator *enumerator; void **objectPtr; size_t i; i = 0; enumerator = [_mapTable objectEnumerator]; while ((objectPtr = [enumerator nextObject]) != NULL) { assert(i < count); objects[i++] = (id)*objectPtr; } objc_autoreleasePoolPop(pool); ret = [OFArray arrayWithObjects: objects count: count]; } @finally { [self freeMemory: objects]; } return ret; } - (OFEnumerator *)keyEnumerator { return [[[OFMapTableEnumeratorWrapper alloc] initWithEnumerator: [_mapTable keyEnumerator] object: self] autorelease]; } - (OFEnumerator *)objectEnumerator { return [[[OFMapTableEnumeratorWrapper alloc] initWithEnumerator: [_mapTable objectEnumerator] object: self] autorelease]; } - (int)countByEnumeratingWithState: (of_fast_enumeration_state_t *)state objects: (id *)objects count: (int)count { return [_mapTable countByEnumeratingWithState: state objects: objects count: count]; } #ifdef OF_HAVE_BLOCKS - (void)enumerateKeysAndObjectsUsingBlock: (of_dictionary_enumeration_block_t)block { @try { [_mapTable enumerateKeysAndObjectsUsingBlock: ^ (void *key, void *object, bool *stop) { block(key, object, stop); }]; } @catch (OFEnumerationMutationException *e) { @throw [OFEnumerationMutationException exceptionWithObject: self]; } } #endif - (uint32_t)hash { return _mapTable.hash; } @end |
Added src/OFMapTableSet.h version [955e132003].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | /* * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, * 2018, 2019 * Jonathan Schleifer <js@heap.zone> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #import "OFSet.h" OF_ASSUME_NONNULL_BEGIN @class OFMapTable; @interface OFMapTableSet: OFSet { OFMapTable *_mapTable; } - (instancetype)initWithCapacity: (size_t)capacity; @end OF_ASSUME_NONNULL_END |
Added src/OFMapTableSet.m version [d1ea04eb64].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 | /* * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, * 2018, 2019 * Jonathan Schleifer <js@heap.zone> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #import "OFMapTableSet.h" #import "OFArray.h" #import "OFCountedMapTableSet.h" #import "OFMapTable.h" #import "OFMapTable+Private.h" #import "OFMutableMapTableSet.h" #import "OFString.h" #import "OFXMLElement.h" #import "OFInvalidArgumentException.h" #import "OFEnumerationMutationException.h" static void * retain(void *object) { return [(id)object retain]; } static void release(void *object) { [(id)object release]; } static uint32_t hash(void *object) { return [(id)object hash]; } static bool equal(void *object1, void *object2) { return [(id)object1 isEqual: (id)object2]; } static const of_map_table_functions_t keyFunctions = { .retain = retain, .release = release, .hash = hash, .equal = equal }; static const of_map_table_functions_t objectFunctions = { NULL }; @implementation OFMapTableSet - (instancetype)init { return [self initWithCapacity: 0]; } - (instancetype)initWithCapacity: (size_t)capacity { self = [super init]; @try { _mapTable = [[OFMapTable alloc] initWithKeyFunctions: keyFunctions objectFunctions: objectFunctions capacity: capacity]; } @catch (id e) { [self release]; @throw e; } return self; } - (instancetype)initWithSet: (OFSet *)set { size_t count; if (set == nil) return [self init]; @try { count = set.count; } @catch (id e) { [self release]; @throw e; } self = [self initWithCapacity: count]; @try { for (id object in set) [_mapTable setObject: (void *)1 forKey: object]; } @catch (id e) { [self release]; @throw e; } return self; } - (instancetype)initWithArray: (OFArray *)array { size_t count; if (array == nil) return self; @try { count = array.count; } @catch (id e) { [self release]; @throw e; } self = [self initWithCapacity: count]; @try { for (id object in array) [_mapTable setObject: (void *)1 forKey: object]; } @catch (id e) { [self release]; @throw e; } return self; } - (instancetype)initWithObjects: (id const *)objects count: (size_t)count { self = [self initWithCapacity: count]; @try { for (size_t i = 0; i < count; i++) [_mapTable setObject: (void *)1 forKey: objects[i]]; } @catch (id e) { [self release]; @throw e; } return self; } - (instancetype)initWithObject: (id)firstObject arguments: (va_list)arguments { self = [super init]; @try { id object; va_list argumentsCopy; size_t count; va_copy(argumentsCopy, arguments); for (count = 1; va_arg(argumentsCopy, id) != nil; count++); _mapTable = [[OFMapTable alloc] initWithKeyFunctions: keyFunctions objectFunctions: objectFunctions capacity: count]; [_mapTable setObject: (void *)1 forKey: firstObject]; while ((object = va_arg(arguments, id)) != nil) [_mapTable setObject: (void *)1 forKey: object]; } @catch (id e) { [self release]; @throw e; } return self; } - (instancetype)initWithSerialization: (OFXMLElement *)element { self = [self init]; @try { void *pool = objc_autoreleasePoolPush(); if ((![element.name isEqual: @"OFSet"] && ![element.name isEqual: @"OFMutableSet"]) || ![element.namespace isEqual: OF_SERIALIZATION_NS]) @throw [OFInvalidArgumentException exception]; for (OFXMLElement *child in [element elementsForNamespace: OF_SERIALIZATION_NS]) { void *pool2 = objc_autoreleasePoolPush(); [_mapTable setObject: (void *)1 forKey: [child objectByDeserializing]]; objc_autoreleasePoolPop(pool2); } objc_autoreleasePoolPop(pool); } @catch (id e) { [self release]; @throw e; } return self; } - (void)dealloc { [_mapTable release]; [super dealloc]; } - (size_t)count { return [_mapTable count]; } - (bool)containsObject: (id)object { if (object == nil) return false; return ([_mapTable objectForKey: object] != nil); } - (bool)isEqual: (id)object { OFMapTableSet *set; if (object == self) return true; if (![object isKindOfClass: [OFMapTableSet class]] && ![object isKindOfClass: [OFMutableMapTableSet class]] && ![object isKindOfClass: [OFCountedMapTableSet class]]) return [super isEqual: object]; set = object; return [set->_mapTable isEqual: _mapTable]; } - (id)anyObject { void *pool = objc_autoreleasePoolPush(); void **objectPtr; id object; objectPtr = [[_mapTable keyEnumerator] nextObject]; if (objectPtr == NULL) { objc_autoreleasePoolPop(pool); return nil; } object = [(id)*objectPtr retain]; objc_autoreleasePoolPop(pool); return [object autorelease]; } - (OFEnumerator *)objectEnumerator { return [[[OFMapTableEnumeratorWrapper alloc] initWithEnumerator: [_mapTable keyEnumerator] object: self] autorelease]; } - (int)countByEnumeratingWithState: (of_fast_enumeration_state_t *)state objects: (id *)objects count: (int)count { return [_mapTable countByEnumeratingWithState: state objects: objects count: count]; } #ifdef OF_HAVE_BLOCKS - (void)enumerateObjectsUsingBlock: (of_set_enumeration_block_t)block { @try { [_mapTable enumerateKeysAndObjectsUsingBlock: ^ (void *key, void *object, bool *stop) { block(key, stop); }]; } @catch (OFEnumerationMutationException *e) { @throw [OFEnumerationMutationException exceptionWithObject: self]; } } #endif @end |
Added src/OFMutableAdjacentArray.h version [ba9ae1bdf2].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | /* * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, * 2018, 2019 * Jonathan Schleifer <js@heap.zone> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #import "OFArray.h" OF_ASSUME_NONNULL_BEGIN @class OFMutableData; @interface OFMutableAdjacentArray: OFMutableArray { OFMutableData *_array; unsigned long _mutations; } @end OF_ASSUME_NONNULL_END |
Added src/OFMutableAdjacentArray.m version [41904cfc7c].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 | /* * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, * 2018, 2019 * Jonathan Schleifer <js@heap.zone> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #include <string.h> #import "OFMutableAdjacentArray.h" #import "OFAdjacentArray.h" #import "OFData.h" #import "OFEnumerationMutationException.h" #import "OFInvalidArgumentException.h" #import "OFOutOfRangeException.h" @implementation OFMutableAdjacentArray + (void)initialize { if (self == [OFMutableAdjacentArray class]) [self inheritMethodsFromClass: [OFAdjacentArray class]]; } - (instancetype)initWithCapacity: (size_t)capacity { self = [super init]; @try { _array = [[OFMutableData alloc] initWithItemSize: sizeof(id) capacity: capacity]; } @catch (id e) { [self release]; @throw e; } return self; } - (void)addObject: (id)object { if (object == nil) @throw [OFInvalidArgumentException exception]; [_array addItem: &object]; [object retain]; _mutations++; } - (void)insertObject: (id)object atIndex: (size_t)idx { if (object == nil) @throw [OFInvalidArgumentException exception]; @try { [_array insertItem: &object atIndex: idx]; } @catch (OFOutOfRangeException *e) { @throw [OFOutOfRangeException exception]; } [object retain]; _mutations++; } - (void)insertObjectsFromArray: (OFArray *)array atIndex: (size_t)idx { id const *objects = array.objects; size_t count = array.count; @try { [_array insertItems: objects atIndex: idx count: count]; } @catch (OFOutOfRangeException *e) { @throw [OFOutOfRangeException exception]; } for (size_t i = 0; i < count; i++) [objects[i] retain]; _mutations++; } - (void)replaceObject: (id)oldObject withObject: (id)newObject { id *objects; size_t count; if (oldObject == nil || newObject == nil) @throw [OFInvalidArgumentException exception]; objects = _array.mutableItems; count = _array.count; for (size_t i = 0; i < count; i++) { if ([objects[i] isEqual: oldObject]) { [newObject retain]; [objects[i] release]; objects[i] = newObject; return; } } } - (void)replaceObjectAtIndex: (size_t)idx withObject: (id)object { id *objects; id oldObject; if (object == nil) @throw [OFInvalidArgumentException exception]; objects = _array.mutableItems; if (idx >= _array.count) @throw [OFOutOfRangeException exception]; oldObject = objects[idx]; objects[idx] = [object retain]; [oldObject release]; } - (void)replaceObjectIdenticalTo: (id)oldObject withObject: (id)newObject { id *objects; size_t count; if (oldObject == nil || newObject == nil) @throw [OFInvalidArgumentException exception]; objects = _array.mutableItems; count = _array.count; for (size_t i = 0; i < count; i++) { if (objects[i] == oldObject) { [newObject retain]; [objects[i] release]; objects[i] = newObject; return; } } } - (void)removeObject: (id)object { id const *objects; size_t count; if (object == nil) @throw [OFInvalidArgumentException exception]; objects = _array.items; count = _array.count; for (size_t i = 0; i < count; i++) { if ([objects[i] isEqual: object]) { object = objects[i]; [_array removeItemAtIndex: i]; _mutations++; [object release]; return; } } } - (void)removeObjectIdenticalTo: (id)object { id const *objects; size_t count; if (object == nil) @throw [OFInvalidArgumentException exception]; objects = _array.items; count = _array.count; for (size_t i = 0; i < count; i++) { if (objects[i] == object) { [_array removeItemAtIndex: i]; _mutations++; [object release]; return; } } } - (void)removeObjectAtIndex: (size_t)idx { #ifndef __clang_analyzer__ id object = [self objectAtIndex: idx]; [_array removeItemAtIndex: idx]; [object release]; _mutations++; #endif } - (void)removeAllObjects { id const *objects = _array.items; size_t count = _array.count; for (size_t i = 0; i < count; i++) [objects[i] release]; [_array removeAllItems]; } - (void)removeObjectsInRange: (of_range_t)range { id const *objects = _array.items; size_t count = _array.count; id *copy; if (range.length > SIZE_MAX - range.location || range.location >= count || range.length > count - range.location) @throw [OFOutOfRangeException exception]; copy = [self allocMemoryWithSize: sizeof(*copy) count: range.length]; memcpy(copy, objects + range.location, range.length * sizeof(id)); @try { [_array removeItemsInRange: range]; _mutations++; for (size_t i = 0; i < range.length; i++) [copy[i] release]; } @finally { [self freeMemory: copy]; } } - (void)removeLastObject { #ifndef __clang_analyzer__ size_t count = _array.count; id object; if (count == 0) return; object = [self objectAtIndex: count - 1]; [_array removeLastItem]; [object release]; _mutations++; #endif } - (void)exchangeObjectAtIndex: (size_t)idx1 withObjectAtIndex: (size_t)idx2 { id *objects = _array.mutableItems; size_t count = _array.count; id tmp; if (idx1 >= count || idx2 >= count) @throw [OFOutOfRangeException exception]; tmp = objects[idx1]; objects[idx1] = objects[idx2]; objects[idx2] = tmp; } - (void)reverse { id *objects = _array.mutableItems; size_t i, j, count = _array.count; if (count == 0 || count == 1) return; for (i = 0, j = count - 1; i < j; i++, j--) { id tmp = objects[i]; objects[i] = objects[j]; objects[j] = tmp; } } - (int)countByEnumeratingWithState: (of_fast_enumeration_state_t *)state objects: (id *)objects count: (int)count_ { size_t count = _array.count; if (count > INT_MAX) { /* * Use the implementation from OFArray (OFMutableArray does not * have one), which is slower, but can enumerate in chunks, and * set the mutations pointer. */ int ret = [super countByEnumeratingWithState: state objects: objects count: count_]; state->mutationsPtr = &_mutations; return ret; } if (state->state >= count) return 0; state->state = (unsigned long)count; state->itemsPtr = _array.items; state->mutationsPtr = &_mutations; return (int)count; } - (OFEnumerator *)objectEnumerator { return [[[OFArrayEnumerator alloc] initWithArray: self mutationsPtr: &_mutations] autorelease]; } #ifdef OF_HAVE_BLOCKS - (void)enumerateObjectsUsingBlock: (of_array_enumeration_block_t)block { id const *objects = _array.items; size_t count = _array.count; bool stop = false; unsigned long mutations = _mutations; for (size_t i = 0; i < count && !stop; i++) { if (_mutations != mutations) @throw [OFEnumerationMutationException exceptionWithObject: self]; block(objects[i], i, &stop); } } - (void)replaceObjectsUsingBlock: (of_array_replace_block_t)block { id *objects = _array.mutableItems; size_t count = _array.count; unsigned long mutations = _mutations; for (size_t i = 0; i < count; i++) { id new; if (_mutations != mutations) @throw [OFEnumerationMutationException exceptionWithObject: self]; new = block(objects[i], i); if (new == nil) @throw [OFInvalidArgumentException exception]; if (new != objects[i]) { [objects[i] release]; objects[i] = [new retain]; } } } #endif - (void)makeImmutable { object_setClass(self, [OFAdjacentArray class]); } @end |
Modified src/OFMutableArray.m from [d1d4c770ab] to [2a019fd7ef].
︙ | ︙ | |||
19 20 21 22 23 24 25 | #include <stdlib.h> #include <string.h> #include <assert.h> #import "OFMutableArray.h" | | | | 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | #include <stdlib.h> #include <string.h> #include <assert.h> #import "OFMutableArray.h" #import "OFMutableAdjacentArray.h" #import "OFEnumerationMutationException.h" #import "OFInvalidArgumentException.h" #import "OFOutOfRangeException.h" static struct { Class isa; } placeholder; @interface OFMutableArrayPlaceholder: OFMutableArray @end static of_comparison_result_t compare(id left, id right, SEL selector) { of_comparison_result_t (*comparator)(id, SEL, id) = (of_comparison_result_t (*)(id, SEL, id)) |
︙ | ︙ | |||
134 135 136 137 138 139 140 | options); left = i + 1; } } #endif | | | | | | | | | | | | | | 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 | options); left = i + 1; } } #endif @implementation OFMutableArrayPlaceholder - (instancetype)init { return (id)[[OFMutableAdjacentArray alloc] init]; } - (instancetype)initWithCapacity: (size_t)capacity { return (id)[[OFMutableAdjacentArray alloc] initWithCapacity: capacity]; } - (instancetype)initWithObject: (id)object { return (id)[[OFMutableAdjacentArray alloc] initWithObject: object]; } - (instancetype)initWithObjects: (id)firstObject, ... { id ret; va_list arguments; va_start(arguments, firstObject); ret = [[OFMutableAdjacentArray alloc] initWithObject: firstObject arguments: arguments]; va_end(arguments); return ret; } - (instancetype)initWithObject: (id)firstObject arguments: (va_list)arguments { return (id)[[OFMutableAdjacentArray alloc] initWithObject: firstObject arguments: arguments]; } - (instancetype)initWithArray: (OFArray *)array { return (id)[[OFMutableAdjacentArray alloc] initWithArray: array]; } - (instancetype)initWithObjects: (id const *)objects count: (size_t)count { return (id)[[OFMutableAdjacentArray alloc] initWithObjects: objects count: count]; } - (instancetype)initWithSerialization: (OFXMLElement *)element { return (id)[[OFMutableAdjacentArray alloc] initWithSerialization: element]; } - (instancetype)retain { return self; } |
︙ | ︙ | |||
212 213 214 215 216 217 218 | } @end @implementation OFMutableArray + (void)initialize { if (self == [OFMutableArray class]) | | | 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 | } @end @implementation OFMutableArray + (void)initialize { if (self == [OFMutableArray class]) placeholder.isa = [OFMutableArrayPlaceholder class]; } + (instancetype)alloc { if (self == [OFMutableArray class]) return (id)&placeholder; |
︙ | ︙ |
Deleted src/OFMutableArray_adjacent.h version [d287aa090f].
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted src/OFMutableArray_adjacent.m version [e7c93457b6].
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Modified src/OFMutableDictionary.m from [08e850f34a] to [ddff1f3203].
︙ | ︙ | |||
15 16 17 18 19 20 21 | * file. */ #include "config.h" #include <stdlib.h> | | | | | | | | < | | < | | | < | | < | | | | | 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 | * file. */ #include "config.h" #include <stdlib.h> #import "OFMutableMapTableDictionary.h" #import "OFArray.h" #import "OFString.h" static struct { Class isa; } placeholder; @interface OFMutableDictionaryPlaceholder: OFDictionary @end @implementation OFMutableDictionaryPlaceholder - (instancetype)init { return (id)[[OFMutableMapTableDictionary alloc] init]; } - (instancetype)initWithDictionary: (OFDictionary *)dictionary { return (id)[[OFMutableMapTableDictionary alloc] initWithDictionary: dictionary]; } - (instancetype)initWithObject: (id)object forKey: (id)key { return (id)[[OFMutableMapTableDictionary alloc] initWithObject: object forKey: key]; } - (instancetype)initWithObjects: (OFArray *)objects forKeys: (OFArray *)keys { return (id)[[OFMutableMapTableDictionary alloc] initWithObjects: objects forKeys: keys]; } - (instancetype)initWithObjects: (id const *)objects forKeys: (id const *)keys count: (size_t)count { return (id)[[OFMutableMapTableDictionary alloc] initWithObjects: objects forKeys: keys count: count]; } - (instancetype)initWithKeysAndObjects: (id)firstKey, ... { id ret; va_list arguments; va_start(arguments, firstKey); ret = (id)[[OFMutableMapTableDictionary alloc] initWithKey: firstKey arguments: arguments]; va_end(arguments); return ret; } - (instancetype)initWithKey: (id)firstKey arguments: (va_list)arguments { return (id)[[OFMutableMapTableDictionary alloc] initWithKey: firstKey arguments: arguments]; } - (instancetype)initWithSerialization: (OFXMLElement *)element { return (id)[[OFMutableMapTableDictionary alloc] initWithSerialization: element]; } - (instancetype)initWithCapacity: (size_t)capacity { return (id)[[OFMutableMapTableDictionary alloc] initWithCapacity: capacity]; } - (instancetype)retain { return self; } |
︙ | ︙ | |||
121 122 123 124 125 126 127 | } @end @implementation OFMutableDictionary + (void)initialize { if (self == [OFMutableDictionary class]) | | | 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 | } @end @implementation OFMutableDictionary + (void)initialize { if (self == [OFMutableDictionary class]) placeholder.isa = [OFMutableDictionaryPlaceholder class]; } + (instancetype)alloc { if (self == [OFMutableDictionary class]) return (id)&placeholder; |
︙ | ︙ |
Deleted src/OFMutableDictionary_hashtable.h version [90645d6539].
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted src/OFMutableDictionary_hashtable.m version [3b94c67f1c].
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Added src/OFMutableMapTableDictionary.h version [dec5e52f1e].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | /* * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, * 2018, 2019 * Jonathan Schleifer <js@heap.zone> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #import "OFDictionary.h" OF_ASSUME_NONNULL_BEGIN @class OFMapTable; @interface OFMutableMapTableDictionary: OFMutableDictionary { OFMapTable *_mapTable; } @end OF_ASSUME_NONNULL_END |
Added src/OFMutableMapTableDictionary.m version [beb7d8528f].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 | /* * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, * 2018, 2019 * Jonathan Schleifer <js@heap.zone> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #include <string.h> #import "OFMutableMapTableDictionary.h" #import "OFMapTable.h" #import "OFMapTableDictionary.h" #import "OFEnumerationMutationException.h" #import "OFOutOfRangeException.h" @implementation OFMutableMapTableDictionary + (void)initialize { if (self == [OFMutableMapTableDictionary class]) [self inheritMethodsFromClass: [OFMapTableDictionary class]]; } - (void)setObject: (id)object forKey: (id)key { [_mapTable setObject: object forKey: key]; } - (void)removeObjectForKey: (id)key { [_mapTable removeObjectForKey: key]; } - (void)removeAllObjects { [_mapTable removeAllObjects]; } #ifdef OF_HAVE_BLOCKS - (void)replaceObjectsUsingBlock: (of_dictionary_replace_block_t)block { @try { [_mapTable replaceObjectsUsingBlock: ^ void *(void *key, void *object) { return block(key, object); }]; } @catch (OFEnumerationMutationException *e) { @throw [OFEnumerationMutationException exceptionWithObject: self]; } } #endif - (void)makeImmutable { object_setClass(self, [OFMapTableDictionary class]); } @end |
Added src/OFMutableMapTableSet.h version [59911fabdb].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | /* * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, * 2018, 2019 * Jonathan Schleifer <js@heap.zone> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #import "OFMutableSet.h" OF_ASSUME_NONNULL_BEGIN @class OFMapTable; @interface OFMutableMapTableSet: OFMutableSet { OFMapTable *_mapTable; } @end OF_ASSUME_NONNULL_END |
Added src/OFMutableMapTableSet.m version [8e4d43c0b1].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 | /* * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, * 2018, 2019 * Jonathan Schleifer <js@heap.zone> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #import "OFMutableMapTableSet.h" #import "OFMapTableSet.h" #import "OFMapTable.h" @implementation OFMutableMapTableSet + (void)initialize { if (self == [OFMutableMapTableSet class]) [self inheritMethodsFromClass: [OFMapTableSet class]]; } - (void)addObject: (id)object { [_mapTable setObject: (void *)1 forKey: object]; } - (void)removeObject: (id)object { [_mapTable removeObjectForKey: object]; } - (void)removeAllObjects { [_mapTable removeAllObjects]; } - (void)makeImmutable { object_setClass(self, [OFMapTableSet class]); } @end |
Modified src/OFMutableSet.m from [5d818f447d] to [faab6f9ba1].
︙ | ︙ | |||
18 19 20 21 22 23 24 | #include "config.h" #include <stdlib.h> #include <assert.h> #import "OFMutableSet.h" | | | | | | | | | | | | | | | | 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 | #include "config.h" #include <stdlib.h> #include <assert.h> #import "OFMutableSet.h" #import "OFMutableMapTableSet.h" static struct { Class isa; } placeholder; @interface OFMutableSetPlaceholder: OFMutableSet @end @implementation OFMutableSetPlaceholder - (instancetype)init { return (id)[[OFMutableMapTableSet alloc] init]; } - (instancetype)initWithSet: (OFSet *)set { return (id)[[OFMutableMapTableSet alloc] initWithSet: set]; } - (instancetype)initWithArray: (OFArray *)array { return (id)[[OFMutableMapTableSet alloc] initWithArray: array]; } - (instancetype)initWithObjects: (id)firstObject, ... { id ret; va_list arguments; va_start(arguments, firstObject); ret = [[OFMutableMapTableSet alloc] initWithObject: firstObject arguments: arguments]; va_end(arguments); return ret; } - (instancetype)initWithObjects: (id const *)objects count: (size_t)count { return (id)[[OFMutableMapTableSet alloc] initWithObjects: objects count: count]; } - (instancetype)initWithObject: (id)firstObject arguments: (va_list)arguments { return (id)[[OFMutableMapTableSet alloc] initWithObject: firstObject arguments: arguments]; } - (instancetype)initWithSerialization: (OFXMLElement *)element { return (id)[[OFMutableMapTableSet alloc] initWithSerialization: element]; } - (instancetype)initWithCapacity: (size_t)capacity { return (id)[[OFMutableMapTableSet alloc] initWithCapacity: capacity]; } - (instancetype)retain { return self; } |
︙ | ︙ | |||
105 106 107 108 109 110 111 | } @end @implementation OFMutableSet + (void)initialize { if (self == [OFMutableSet class]) | | | 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 | } @end @implementation OFMutableSet + (void)initialize { if (self == [OFMutableSet class]) placeholder.isa = [OFMutableSetPlaceholder class]; } + (instancetype)alloc { if (self == [OFMutableSet class]) return (id)&placeholder; |
︙ | ︙ |
Deleted src/OFMutableSet_hashtable.h version [08dedbe8e6].
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted src/OFMutableSet_hashtable.m version [ce8bebb2d0].
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Modified src/OFMutableString.m from [3ed2ba1cf6] to [3833fffedc].
︙ | ︙ | |||
18 19 20 21 22 23 24 | #include "config.h" #include <stdarg.h> #include <stdlib.h> #include <string.h> #import "OFString.h" | | | | | < | | | | | < | | | | | | | | < | | < | | | | | | < | | < | | | | | | | | | | < | | 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 | #include "config.h" #include <stdarg.h> #include <stdlib.h> #include <string.h> #import "OFString.h" #import "OFMutableUTF8String.h" #import "OFInvalidArgumentException.h" #import "OFInvalidFormatException.h" #import "OFOutOfRangeException.h" #import "of_asprintf.h" #import "unicode.h" static struct { Class isa; } placeholder; @interface OFMutableStringPlaceholder: OFMutableString @end @implementation OFMutableStringPlaceholder - (instancetype)init { return (id)[[OFMutableUTF8String alloc] init]; } - (instancetype)initWithUTF8String: (const char *)UTF8String { return (id)[[OFMutableUTF8String alloc] initWithUTF8String: UTF8String]; } - (instancetype)initWithUTF8String: (const char *)UTF8String length: (size_t)UTF8StringLength { return (id)[[OFMutableUTF8String alloc] initWithUTF8String: UTF8String length: UTF8StringLength]; } - (instancetype)initWithCString: (const char *)cString encoding: (of_string_encoding_t)encoding { return (id)[[OFMutableUTF8String alloc] initWithCString: cString encoding: encoding]; } - (instancetype)initWithCString: (const char *)cString encoding: (of_string_encoding_t)encoding length: (size_t)cStringLength { return (id)[[OFMutableUTF8String alloc] initWithCString: cString encoding: encoding length: cStringLength]; } - (instancetype)initWithString: (OFString *)string { return (id)[[OFMutableUTF8String alloc] initWithString: string]; } - (instancetype)initWithCharacters: (const of_unichar_t *)characters length: (size_t)length { return (id)[[OFMutableUTF8String alloc] initWithCharacters: characters length: length]; } - (instancetype)initWithUTF16String: (const of_char16_t *)string { return (id)[[OFMutableUTF8String alloc] initWithUTF16String: string]; } - (instancetype)initWithUTF16String: (const of_char16_t *)string length: (size_t)length { return (id)[[OFMutableUTF8String alloc] initWithUTF16String: string length: length]; } - (instancetype)initWithUTF16String: (const of_char16_t *)string byteOrder: (of_byte_order_t)byteOrder { return (id)[[OFMutableUTF8String alloc] initWithUTF16String: string byteOrder: byteOrder]; } - (instancetype)initWithUTF16String: (const of_char16_t *)string length: (size_t)length byteOrder: (of_byte_order_t)byteOrder { return (id)[[OFMutableUTF8String alloc] initWithUTF16String: string length: length byteOrder: byteOrder]; } - (instancetype)initWithUTF32String: (const of_char32_t *)string { return (id)[[OFMutableUTF8String alloc] initWithUTF32String: string]; } - (instancetype)initWithUTF32String: (const of_char32_t *)string length: (size_t)length { return (id)[[OFMutableUTF8String alloc] initWithUTF32String: string length: length]; } - (instancetype)initWithUTF32String: (const of_char32_t *)string byteOrder: (of_byte_order_t)byteOrder { return (id)[[OFMutableUTF8String alloc] initWithUTF32String: string byteOrder: byteOrder]; } - (instancetype)initWithUTF32String: (const of_char32_t *)string length: (size_t)length byteOrder: (of_byte_order_t)byteOrder { return (id)[[OFMutableUTF8String alloc] initWithUTF32String: string length: length byteOrder: byteOrder]; } - (instancetype)initWithFormat: (OFConstantString *)format, ... { id ret; va_list arguments; va_start(arguments, format); ret = [[OFMutableUTF8String alloc] initWithFormat: format arguments: arguments]; va_end(arguments); return ret; } - (instancetype)initWithFormat: (OFConstantString *)format arguments: (va_list)arguments { return (id)[[OFMutableUTF8String alloc] initWithFormat: format arguments: arguments]; } #ifdef OF_HAVE_FILES - (instancetype)initWithContentsOfFile: (OFString *)path { return (id)[[OFMutableUTF8String alloc] initWithContentsOfFile: path]; } - (instancetype)initWithContentsOfFile: (OFString *)path encoding: (of_string_encoding_t)encoding { return (id)[[OFMutableUTF8String alloc] initWithContentsOfFile: path encoding: encoding]; } #endif #if defined(OF_HAVE_FILES) || defined(OF_HAVE_SOCKETS) - (instancetype)initWithContentsOfURL: (OFURL *)URL { return (id)[[OFMutableUTF8String alloc] initWithContentsOfURL: URL]; } - (instancetype)initWithContentsOfURL: (OFURL *)URL encoding: (of_string_encoding_t)encoding { return (id)[[OFMutableUTF8String alloc] initWithContentsOfURL: URL encoding: encoding]; } #endif - (instancetype)initWithSerialization: (OFXMLElement *)element { return (id)[[OFMutableUTF8String alloc] initWithSerialization: element]; } - (instancetype)retain { return self; } |
︙ | ︙ | |||
223 224 225 226 227 228 229 | } @end @implementation OFMutableString + (void)initialize { if (self == [OFMutableString class]) | | | 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 | } @end @implementation OFMutableString + (void)initialize { if (self == [OFMutableString class]) placeholder.isa = [OFMutableStringPlaceholder class]; } + (instancetype)alloc { if (self == [OFMutableString class]) return (id)&placeholder; |
︙ | ︙ |
Deleted src/OFMutableString_UTF8.h version [113ab46a5f].
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted src/OFMutableString_UTF8.m version [8884971f0c].
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Added src/OFMutableUTF8String.h version [039b0313df].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | /* * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, * 2018, 2019 * Jonathan Schleifer <js@heap.zone> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #import "OFMutableString.h" #import "OFUTF8String.h" OF_ASSUME_NONNULL_BEGIN @interface OFMutableUTF8String: OFMutableString { @public struct of_string_utf8_ivars *restrict _s; struct of_string_utf8_ivars _storage; } @end OF_ASSUME_NONNULL_END |
Added src/OFMutableUTF8String.m version [e22aad1130].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 | /* * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, * 2018, 2019 * Jonathan Schleifer <js@heap.zone> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #include <stdarg.h> #include <stdlib.h> #include <string.h> #include <assert.h> #import "OFMutableUTF8String.h" #import "OFString.h" #import "OFUTF8String.h" #import "OFInvalidArgumentException.h" #import "OFInvalidEncodingException.h" #import "OFInvalidFormatException.h" #import "OFOutOfMemoryException.h" #import "OFOutOfRangeException.h" #import "of_asprintf.h" #import "unicode.h" @implementation OFMutableUTF8String + (void)initialize { if (self == [OFMutableUTF8String class]) [self inheritMethodsFromClass: [OFUTF8String class]]; } - (instancetype)initWithUTF8StringNoCopy: (char *)UTF8String freeWhenDone: (bool)freeWhenDone { @try { self = [self initWithUTF8String: UTF8String]; } @finally { if (freeWhenDone) free(UTF8String); } return self; } - (instancetype)initWithUTF8StringNoCopy: (char *)UTF8String length: (size_t)UTF8StringLength freeWhenDone: (bool)freeWhenDone { @try { self = [self initWithUTF8String: UTF8String length: UTF8StringLength]; } @finally { if (freeWhenDone) free(UTF8String); } return self; } - (void)of_convertWithWordStartTable: (const of_unichar_t *const[])startTable wordMiddleTable: (const of_unichar_t *const[])middleTable wordStartTableSize: (size_t)startTableSize wordMiddleTableSize: (size_t)middleTableSize { of_unichar_t *unicodeString; size_t unicodeLen, newCStringLength; size_t i, j; char *newCString; bool isStart = true; if (!_s->isUTF8) { uint8_t t; const of_unichar_t *const *table; assert(startTableSize >= 1 && middleTableSize >= 1); _s->hashed = false; for (i = 0; i < _s->cStringLength; i++) { if (isStart) table = startTable; else table = middleTable; isStart = of_ascii_isspace(_s->cString[i]); if ((t = table[0][(uint8_t)_s->cString[i]]) != 0) _s->cString[i] = t; } return; } unicodeLen = self.length; unicodeString = [self allocMemoryWithSize: sizeof(of_unichar_t) count: unicodeLen]; i = j = 0; newCStringLength = 0; while (i < _s->cStringLength) { const of_unichar_t *const *table; size_t tableSize; of_unichar_t c; ssize_t cLen; if (isStart) { table = startTable; tableSize = middleTableSize; } else { table = middleTable; tableSize = middleTableSize; } cLen = of_string_utf8_decode(_s->cString + i, _s->cStringLength - i, &c); if (cLen <= 0 || c > 0x10FFFF) { [self freeMemory: unicodeString]; @throw [OFInvalidEncodingException exception]; } isStart = of_ascii_isspace(c); if (c >> 8 < tableSize) { of_unichar_t tc = table[c >> 8][c & 0xFF]; if (tc) c = tc; } unicodeString[j++] = c; if (c < 0x80) newCStringLength++; else if (c < 0x800) newCStringLength += 2; else if (c < 0x10000) newCStringLength += 3; else if (c < 0x110000) newCStringLength += 4; else { [self freeMemory: unicodeString]; @throw [OFInvalidEncodingException exception]; } i += cLen; } @try { newCString = [self allocMemoryWithSize: newCStringLength + 1]; } @catch (id e) { [self freeMemory: unicodeString]; @throw e; } j = 0; for (i = 0; i < unicodeLen; i++) { size_t d; if ((d = of_string_utf8_encode(unicodeString[i], newCString + j)) == 0) { [self freeMemory: unicodeString]; [self freeMemory: newCString]; @throw [OFInvalidEncodingException exception]; } j += d; } assert(j == newCStringLength); newCString[j] = 0; [self freeMemory: unicodeString]; [self freeMemory: _s->cString]; _s->hashed = false; _s->cString = newCString; _s->cStringLength = newCStringLength; /* * Even though cStringLength can change, length cannot, therefore no * need to change it. */ } - (void)setCharacter: (of_unichar_t)character atIndex: (size_t)idx { char buffer[4]; of_unichar_t c; size_t lenNew; ssize_t lenOld; if (_s->isUTF8) idx = of_string_utf8_get_position(_s->cString, idx, _s->cStringLength); if (idx >= _s->cStringLength) @throw [OFOutOfRangeException exception]; /* Shortcut if old and new character both are ASCII */ if (character < 0x80 && !(_s->cString[idx] & 0x80)) { _s->hashed = false; _s->cString[idx] = character; return; } if ((lenNew = of_string_utf8_encode(character, buffer)) == 0) @throw [OFInvalidEncodingException exception]; if ((lenOld = of_string_utf8_decode(_s->cString + idx, _s->cStringLength - idx, &c)) <= 0) @throw [OFInvalidEncodingException exception]; _s->hashed = false; if (lenNew == (size_t)lenOld) memcpy(_s->cString + idx, buffer, lenNew); else if (lenNew > (size_t)lenOld) { _s->cString = [self resizeMemory: _s->cString size: _s->cStringLength - lenOld + lenNew + 1]; memmove(_s->cString + idx + lenNew, _s->cString + idx + lenOld, _s->cStringLength - idx - lenOld); memcpy(_s->cString + idx, buffer, lenNew); _s->cStringLength -= lenOld; _s->cStringLength += lenNew; _s->cString[_s->cStringLength] = '\0'; if (character >= 0x80) _s->isUTF8 = true; } else if (lenNew < (size_t)lenOld) { memmove(_s->cString + idx + lenNew, _s->cString + idx + lenOld, _s->cStringLength - idx - lenOld); memcpy(_s->cString + idx, buffer, lenNew); _s->cStringLength -= lenOld; _s->cStringLength += lenNew; _s->cString[_s->cStringLength] = '\0'; if (character >= 0x80) _s->isUTF8 = true; @try { _s->cString = [self resizeMemory: _s->cString size: _s->cStringLength + 1]; } @catch (OFOutOfMemoryException *e) { /* We don't really care, as we only made it smaller */ } } } - (void)appendUTF8String: (const char *)UTF8String { size_t UTF8StringLength = strlen(UTF8String); size_t length; if (UTF8StringLength >= 3 && memcmp(UTF8String, "\xEF\xBB\xBF", 3) == 0) { UTF8String += 3; UTF8StringLength -= 3; } switch (of_string_utf8_check(UTF8String, UTF8StringLength, &length)) { case 1: _s->isUTF8 = true; break; case -1: @throw [OFInvalidEncodingException exception]; } _s->hashed = false; _s->cString = [self resizeMemory: _s->cString size: _s->cStringLength + UTF8StringLength + 1]; memcpy(_s->cString + _s->cStringLength, UTF8String, UTF8StringLength + 1); _s->cStringLength += UTF8StringLength; _s->length += length; } - (void)appendUTF8String: (const char *)UTF8String length: (size_t)UTF8StringLength { size_t length; if (UTF8StringLength >= 3 && memcmp(UTF8String, "\xEF\xBB\xBF", 3) == 0) { UTF8String += 3; UTF8StringLength -= 3; } switch (of_string_utf8_check(UTF8String, UTF8StringLength, &length)) { case 1: _s->isUTF8 = true; break; case -1: @throw [OFInvalidEncodingException exception]; } _s->hashed = false; _s->cString = [self resizeMemory: _s->cString size: _s->cStringLength + UTF8StringLength + 1]; memcpy(_s->cString + _s->cStringLength, UTF8String, UTF8StringLength); _s->cStringLength += UTF8StringLength; _s->length += length; _s->cString[_s->cStringLength] = 0; } - (void)appendCString: (const char *)cString encoding: (of_string_encoding_t)encoding { [self appendCString: cString encoding: encoding length: strlen(cString)]; } - (void)appendCString: (const char *)cString encoding: (of_string_encoding_t)encoding length: (size_t)cStringLength { if (encoding == OF_STRING_ENCODING_UTF_8) [self appendUTF8String: cString length: cStringLength]; else { void *pool = objc_autoreleasePoolPush(); [self appendString: [OFString stringWithCString: cString encoding: encoding length: cStringLength]]; objc_autoreleasePoolPop(pool); } } - (void)appendString: (OFString *)string { size_t UTF8StringLength; if (string == nil) @throw [OFInvalidArgumentException exception]; UTF8StringLength = string.UTF8StringLength; _s->hashed = false; _s->cString = [self resizeMemory: _s->cString size: _s->cStringLength + UTF8StringLength + 1]; memcpy(_s->cString + _s->cStringLength, string.UTF8String, UTF8StringLength); _s->cStringLength += UTF8StringLength; _s->length += string.length; _s->cString[_s->cStringLength] = 0; if ([string isKindOfClass: [OFUTF8String class]] || [string isKindOfClass: [OFMutableUTF8String class]]) { if (((OFUTF8String *)string)->_s->isUTF8) _s->isUTF8 = true; } else _s->isUTF8 = true; } - (void)appendCharacters: (const of_unichar_t *)characters length: (size_t)length { char *tmp; tmp = [self allocMemoryWithSize: (length * 4) + 1]; @try { size_t j = 0; bool isUTF8 = false; for (size_t i = 0; i < length; i++) { size_t len = of_string_utf8_encode(characters[i], tmp + j); if (len == 0) @throw [OFInvalidEncodingException exception]; if (len > 1) isUTF8 = true; j += len; } tmp[j] = '\0'; _s->hashed = false; _s->cString = [self resizeMemory: _s->cString size: _s->cStringLength + j + 1]; memcpy(_s->cString + _s->cStringLength, tmp, j + 1); _s->cStringLength += j; _s->length += length; if (isUTF8) _s->isUTF8 = true; } @finally { [self freeMemory: tmp]; } } - (void)appendFormat: (OFConstantString *)format arguments: (va_list)arguments { char *UTF8String; int UTF8StringLength; if (format == nil) @throw [OFInvalidArgumentException exception]; if ((UTF8StringLength = of_vasprintf(&UTF8String, format.UTF8String, arguments)) == -1) @throw [OFInvalidFormatException exception]; @try { [self appendUTF8String: UTF8String length: UTF8StringLength]; } @finally { free(UTF8String); } } - (void)reverse { size_t i, j; _s->hashed = false; /* We reverse all bytes and restore UTF-8 later, if necessary */ for (i = 0, j = _s->cStringLength - 1; i < _s->cStringLength / 2; i++, j--) { _s->cString[i] ^= _s->cString[j]; _s->cString[j] ^= _s->cString[i]; _s->cString[i] ^= _s->cString[j]; } if (!_s->isUTF8) return; for (i = 0; i < _s->cStringLength; i++) { /* ASCII */ if OF_LIKELY (!(_s->cString[i] & 0x80)) continue; /* A start byte can't happen first as we reversed everything */ if OF_UNLIKELY (_s->cString[i] & 0x40) @throw [OFInvalidEncodingException exception]; /* Next byte must not be ASCII */ if OF_UNLIKELY (_s->cStringLength < i + 1 || !(_s->cString[i + 1] & 0x80)) @throw [OFInvalidEncodingException exception]; /* Next byte is the start byte */ if OF_LIKELY (_s->cString[i + 1] & 0x40) { _s->cString[i] ^= _s->cString[i + 1]; _s->cString[i + 1] ^= _s->cString[i]; _s->cString[i] ^= _s->cString[i + 1]; i++; continue; } /* Second next byte must not be ASCII */ if OF_UNLIKELY (_s->cStringLength < i + 2 || !(_s->cString[i + 2] & 0x80)) @throw [OFInvalidEncodingException exception]; /* Second next byte is the start byte */ if OF_LIKELY (_s->cString[i + 2] & 0x40) { _s->cString[i] ^= _s->cString[i + 2]; _s->cString[i + 2] ^= _s->cString[i]; _s->cString[i] ^= _s->cString[i + 2]; i += 2; continue; } /* Third next byte must not be ASCII */ if OF_UNLIKELY (_s->cStringLength < i + 3 || !(_s->cString[i + 3] & 0x80)) @throw [OFInvalidEncodingException exception]; /* Third next byte is the start byte */ if OF_LIKELY (_s->cString[i + 3] & 0x40) { _s->cString[i] ^= _s->cString[i + 3]; _s->cString[i + 3] ^= _s->cString[i]; _s->cString[i] ^= _s->cString[i + 3]; _s->cString[i + 1] ^= _s->cString[i + 2]; _s->cString[i + 2] ^= _s->cString[i + 1]; _s->cString[i + 1] ^= _s->cString[i + 2]; i += 3; continue; } /* UTF-8 does not allow more than 4 bytes per character */ @throw [OFInvalidEncodingException exception]; } } - (void)insertString: (OFString *)string atIndex: (size_t)idx { size_t newCStringLength; if (idx > _s->length) @throw [OFOutOfRangeException exception]; if (_s->isUTF8) idx = of_string_utf8_get_position(_s->cString, idx, _s->cStringLength); newCStringLength = _s->cStringLength + string.UTF8StringLength; _s->hashed = false; _s->cString = [self resizeMemory: _s->cString size: newCStringLength + 1]; memmove(_s->cString + idx + string.UTF8StringLength, _s->cString + idx, _s->cStringLength - idx); memcpy(_s->cString + idx, string.UTF8String, string.UTF8StringLength); _s->cString[newCStringLength] = '\0'; _s->cStringLength = newCStringLength; _s->length += string.length; if ([string isKindOfClass: [OFUTF8String class]] || [string isKindOfClass: [OFMutableUTF8String class]]) { if (((OFUTF8String *)string)->_s->isUTF8) _s->isUTF8 = true; } else _s->isUTF8 = true; } - (void)deleteCharactersInRange: (of_range_t)range { size_t start = range.location; size_t end = range.location + range.length; if (range.length > SIZE_MAX - range.location || end > _s->length) @throw [OFOutOfRangeException exception]; if (_s->isUTF8) { start = of_string_utf8_get_position(_s->cString, start, _s->cStringLength); end = of_string_utf8_get_position(_s->cString, end, _s->cStringLength); } memmove(_s->cString + start, _s->cString + end, _s->cStringLength - end); _s->hashed = false; _s->length -= range.length; _s->cStringLength -= end - start; _s->cString[_s->cStringLength] = 0; @try { _s->cString = [self resizeMemory: _s->cString size: _s->cStringLength + 1]; } @catch (OFOutOfMemoryException *e) { /* We don't really care, as we only made it smaller */ } } - (void)replaceCharactersInRange: (of_range_t)range withString: (OFString *)replacement { size_t start = range.location; size_t end = range.location + range.length; size_t newCStringLength, newLength; if (replacement == nil) @throw [OFInvalidArgumentException exception]; if (range.length > SIZE_MAX - range.location || end > _s->length) @throw [OFOutOfRangeException exception]; newLength = _s->length - range.length + replacement.length; if (_s->isUTF8) { start = of_string_utf8_get_position(_s->cString, start, _s->cStringLength); end = of_string_utf8_get_position(_s->cString, end, _s->cStringLength); } newCStringLength = _s->cStringLength - (end - start) + replacement.UTF8StringLength; _s->hashed = false; /* * If the new string is bigger, we need to resize it first so we can * memmove() the rest of the string to the end. * * We must not resize the string if the new string is smaller, because * then we can't memmove() the rest of the string forward as the rest is * lost due to the resize! */ if (newCStringLength > _s->cStringLength) _s->cString = [self resizeMemory: _s->cString size: newCStringLength + 1]; memmove(_s->cString + start + replacement.UTF8StringLength, _s->cString + end, _s->cStringLength - end); memcpy(_s->cString + start, replacement.UTF8String, replacement.UTF8StringLength); _s->cString[newCStringLength] = '\0'; /* * If the new string is smaller, we can safely resize it now as we're * done with memmove(). */ if (newCStringLength < _s->cStringLength) _s->cString = [self resizeMemory: _s->cString size: newCStringLength + 1]; _s->cStringLength = newCStringLength; _s->length = newLength; if ([replacement isKindOfClass: [OFUTF8String class]] || [replacement isKindOfClass: [OFMutableUTF8String class]]) { if (((OFUTF8String *)replacement)->_s->isUTF8) _s->isUTF8 = true; } else _s->isUTF8 = true; } - (void)replaceOccurrencesOfString: (OFString *)string withString: (OFString *)replacement options: (int)options range: (of_range_t)range { const char *searchString = string.UTF8String; const char *replacementString = replacement.UTF8String; size_t searchLength = string.UTF8StringLength; size_t replacementLength = replacement.UTF8StringLength; size_t last, newCStringLength, newLength; char *newCString; if (string == nil || replacement == nil) @throw [OFInvalidArgumentException exception]; if (range.length > SIZE_MAX - range.location || range.location + range.length > self.length) @throw [OFOutOfRangeException exception]; if (_s->isUTF8) { range.location = of_string_utf8_get_position(_s->cString, range.location, _s->cStringLength); range.length = of_string_utf8_get_position( _s->cString + range.location, range.length, _s->cStringLength - range.location); } if (string.UTF8StringLength > range.length) return; newCString = NULL; newCStringLength = 0; newLength = _s->length; last = 0; for (size_t i = range.location; i <= range.length - searchLength; i++) { if (memcmp(_s->cString + i, searchString, searchLength) != 0) continue; @try { newCString = [self resizeMemory: newCString size: newCStringLength + i - last + replacementLength + 1]; } @catch (id e) { [self freeMemory: newCString]; @throw e; } memcpy(newCString + newCStringLength, _s->cString + last, i - last); memcpy(newCString + newCStringLength + i - last, replacementString, replacementLength); newCStringLength += i - last + replacementLength; newLength = newLength - string.length + replacement.length; i += searchLength - 1; last = i + 1; } @try { newCString = [self resizeMemory: newCString size: newCStringLength + _s->cStringLength - last + 1]; } @catch (id e) { [self freeMemory: newCString]; @throw e; } memcpy(newCString + newCStringLength, _s->cString + last, _s->cStringLength - last); newCStringLength += _s->cStringLength - last; newCString[newCStringLength] = 0; [self freeMemory: _s->cString]; _s->hashed = false; _s->cString = newCString; _s->cStringLength = newCStringLength; _s->length = newLength; if ([replacement isKindOfClass: [OFUTF8String class]] || [replacement isKindOfClass: [OFMutableUTF8String class]]) { if (((OFUTF8String *)replacement)->_s->isUTF8) _s->isUTF8 = true; } else _s->isUTF8 = true; } - (void)deleteLeadingWhitespaces { size_t i; for (i = 0; i < _s->cStringLength; i++) if (!of_ascii_isspace(_s->cString[i])) break; _s->hashed = false; _s->cStringLength -= i; _s->length -= i; memmove(_s->cString, _s->cString + i, _s->cStringLength); _s->cString[_s->cStringLength] = '\0'; @try { _s->cString = [self resizeMemory: _s->cString size: _s->cStringLength + 1]; } @catch (OFOutOfMemoryException *e) { /* We don't really care, as we only made it smaller */ } } - (void)deleteTrailingWhitespaces { size_t d; char *p; _s->hashed = false; d = 0; for (p = _s->cString + _s->cStringLength - 1; p >= _s->cString; p--) { if (!of_ascii_isspace(*p)) break; *p = '\0'; d++; } _s->cStringLength -= d; _s->length -= d; @try { _s->cString = [self resizeMemory: _s->cString size: _s->cStringLength + 1]; } @catch (OFOutOfMemoryException *e) { /* We don't really care, as we only made it smaller */ } } - (void)deleteEnclosingWhitespaces { size_t d, i; char *p; _s->hashed = false; d = 0; for (p = _s->cString + _s->cStringLength - 1; p >= _s->cString; p--) { if (!of_ascii_isspace(*p)) break; *p = '\0'; d++; } _s->cStringLength -= d; _s->length -= d; for (i = 0; i < _s->cStringLength; i++) if (!of_ascii_isspace(_s->cString[i])) break; _s->cStringLength -= i; _s->length -= i; memmove(_s->cString, _s->cString + i, _s->cStringLength); _s->cString[_s->cStringLength] = '\0'; @try { _s->cString = [self resizeMemory: _s->cString size: _s->cStringLength + 1]; } @catch (OFOutOfMemoryException *e) { /* We don't really care, as we only made it smaller */ } } - (void)makeImmutable { object_setClass(self, [OFUTF8String class]); } @end |
Added src/OFNonretainedObjectValue.h version [c355b53946].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | /* * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, * 2018, 2019 * Jonathan Schleifer <js@heap.zone> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #import "OFValue.h" OF_ASSUME_NONNULL_BEGIN @interface OFNonretainedObjectValue: OFValue { id _object; } @end OF_ASSUME_NONNULL_END |
Added src/OFNonretainedObjectValue.m version [ad388d34e4].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | /* * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, * 2018, 2019 * Jonathan Schleifer <js@heap.zone> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #import "OFNonretainedObjectValue.h" #import "OFMethodSignature.h" #import "OFOutOfRangeException.h" @implementation OFNonretainedObjectValue @synthesize nonretainedObjectValue = _object; - (instancetype)initWithNonretainedObject: (id)object { self = [super init]; _object = object; return self; } - (const char *)objCType { return @encode(id); } - (void)getValue: (void *)value size: (size_t)size { if (size != sizeof(_object)) @throw [OFOutOfRangeException exception]; memcpy(value, &_object, sizeof(_object)); } - (void *)pointerValue { return _object; } @end |
Added src/OFPointValue.h version [ee56f0af65].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | /* * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, * 2018, 2019 * Jonathan Schleifer <js@heap.zone> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #import "OFValue.h" OF_ASSUME_NONNULL_BEGIN @interface OFPointValue: OFValue { of_point_t _point; } @end OF_ASSUME_NONNULL_END |
Added src/OFPointValue.m version [82077c978b].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 | /* * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, * 2018, 2019 * Jonathan Schleifer <js@heap.zone> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #import "OFPointValue.h" #import "OFMethodSignature.h" #import "OFString.h" #import "OFOutOfRangeException.h" @implementation OFPointValue @synthesize pointValue = _point; - (instancetype)initWithPoint: (of_point_t)point { self = [super init]; _point = point; return self; } - (const char *)objCType { return @encode(of_point_t); } - (void)getValue: (void *)value size: (size_t)size { if (size != sizeof(_point)) @throw [OFOutOfRangeException exception]; memcpy(value, &_point, sizeof(_point)); } - (OFString *)description { return [OFString stringWithFormat: @"<OFValue: of_point_t { %f, %f }>", _point.x, _point.y]; } @end |
Added src/OFPointerValue.h version [c394de6a61].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | /* * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, * 2018, 2019 * Jonathan Schleifer <js@heap.zone> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #import "OFValue.h" OF_ASSUME_NONNULL_BEGIN @interface OFPointerValue: OFValue { void *_pointer; } @end OF_ASSUME_NONNULL_END |
Added src/OFPointerValue.m version [161d8433c0].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | /* * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, * 2018, 2019 * Jonathan Schleifer <js@heap.zone> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #import "OFPointerValue.h" #import "OFMethodSignature.h" #import "OFOutOfRangeException.h" @implementation OFPointerValue @synthesize pointerValue = _pointer; - (instancetype)initWithPointer: (const void *)pointer { self = [super init]; _pointer = (void *)pointer; return self; } - (const char *)objCType { return @encode(void *); } - (void)getValue: (void *)value size: (size_t)size { if (size != sizeof(_pointer)) @throw [OFOutOfRangeException exception]; memcpy(value, &_pointer, sizeof(_pointer)); } - (id)nonretainedObjectValue { return _pointer; } @end |
Added src/OFPollKernelEventObserver.h version [aa8c14235f].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | /* * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, * 2018, 2019 * Jonathan Schleifer <js@heap.zone> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #import "OFKernelEventObserver.h" OF_ASSUME_NONNULL_BEGIN @class OFMutableData; @interface OFPollKernelEventObserver: OFKernelEventObserver { OFMutableData *_FDs; int _maxFD; id __unsafe_unretained *_FDToObject; } @end OF_ASSUME_NONNULL_END |
Added src/OFPollKernelEventObserver.m version [4027980cc7].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 | /* * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, * 2018, 2019 * Jonathan Schleifer <js@heap.zone> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #define __NO_EXT_QNX #include "config.h" #include <assert.h> #include <errno.h> #ifdef HAVE_POLL_H # include <poll.h> #endif #import "OFPollKernelEventObserver.h" #import "OFData.h" #import "OFKernelEventObserver+Private.h" #import "OFKernelEventObserver.h" #import "OFObserveFailedException.h" #import "OFOutOfRangeException.h" #import "socket_helpers.h" #ifdef OF_WII # define pollfd pollsd # define fd socket #endif @implementation OFPollKernelEventObserver - (instancetype)init { self = [super init]; @try { struct pollfd p = { _cancelFD[0], POLLIN, 0 }; _FDs = [[OFMutableData alloc] initWithItemSize: sizeof(struct pollfd)]; [_FDs addItem: &p]; _maxFD = _cancelFD[0]; _FDToObject = [self allocMemoryWithSize: sizeof(id) count: (size_t)_maxFD + 1]; } @catch (id e) { [self release]; @throw e; } return self; } - (void)dealloc { [_FDs release]; [super dealloc]; } - (void)of_addObject: (id)object fileDescriptor: (int)fd events: (short)events { struct pollfd *FDs = _FDs.mutableItems; size_t count = _FDs.count; bool found = false; for (size_t i = 0; i < count; i++) { if (FDs[i].fd == fd) { FDs[i].events |= events; found = true; break; } } if (!found) { struct pollfd p = { fd, events, 0 }; if (fd > _maxFD) { _maxFD = fd; _FDToObject = [self resizeMemory: _FDToObject size: sizeof(id) count: (size_t)_maxFD + 1]; } _FDToObject[fd] = object; [_FDs addItem: &p]; } } - (void)of_removeObject: (id)object fileDescriptor: (int)fd events: (short)events { struct pollfd *FDs = _FDs.mutableItems; size_t nFDs = _FDs.count; for (size_t i = 0; i < nFDs; i++) { if (FDs[i].fd == fd) { FDs[i].events &= ~events; if (FDs[i].events == 0) { /* * TODO: Remove from and resize _FDToObject, * adjust _maxFD. */ [_FDs removeItemAtIndex: i]; } break; } } } - (void)of_addObjectForReading: (id <OFReadyForReadingObserving>)object { [self of_addObject: object fileDescriptor: object.fileDescriptorForReading events: POLLIN]; } - (void)of_addObjectForWriting: (id <OFReadyForWritingObserving>)object { [self of_addObject: object fileDescriptor: object.fileDescriptorForWriting events: POLLOUT]; } - (void)of_removeObjectForReading: (id <OFReadyForReadingObserving>)object { [self of_removeObject: object fileDescriptor: object.fileDescriptorForReading events: POLLIN]; } - (void)of_removeObjectForWriting: (id <OFReadyForWritingObserving>)object { [self of_removeObject: object fileDescriptor: object.fileDescriptorForWriting events: POLLOUT]; } - (void)observeForTimeInterval: (of_time_interval_t)timeInterval { struct pollfd *FDs; int events; size_t nFDs; [self of_processQueue]; if ([self of_processReadBuffers]) return; FDs = _FDs.mutableItems; nFDs = _FDs.count; #ifdef OPEN_MAX if (nFDs > OPEN_MAX) @throw [OFOutOfRangeException exception]; #endif events = poll(FDs, (nfds_t)nFDs, (int)(timeInterval != -1 ? timeInterval * 1000 : -1)); if (events < 0) @throw [OFObserveFailedException exceptionWithObserver: self errNo: errno]; for (size_t i = 0; i < nFDs; i++) { assert(FDs[i].fd <= _maxFD); if (FDs[i].revents & POLLIN) { void *pool; if (FDs[i].fd == _cancelFD[0]) { char buffer; #ifdef OF_HAVE_PIPE OF_ENSURE(read(_cancelFD[0], &buffer, 1) == 1); #else OF_ENSURE(recvfrom(_cancelFD[0], &buffer, 1, 0, NULL, NULL) == 1); #endif FDs[i].revents = 0; continue; } pool = objc_autoreleasePoolPush(); if ([_delegate respondsToSelector: @selector(objectIsReadyForReading:)]) [_delegate objectIsReadyForReading: _FDToObject[FDs[i].fd]]; objc_autoreleasePoolPop(pool); } if (FDs[i].revents & POLLOUT) { void *pool = objc_autoreleasePoolPush(); if ([_delegate respondsToSelector: @selector(objectIsReadyForWriting:)]) [_delegate objectIsReadyForWriting: _FDToObject[FDs[i].fd]]; objc_autoreleasePoolPop(pool); } FDs[i].revents = 0; } } @end |
Added src/OFRangeCharacterSet.h version [d6286761a3].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | /* * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, * 2018, 2019 * Jonathan Schleifer <js@heap.zone> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #import "OFCharacterSet.h" OF_ASSUME_NONNULL_BEGIN @interface OFRangeCharacterSet: OFCharacterSet { of_range_t _range; } @end OF_ASSUME_NONNULL_END |
Added src/OFRangeCharacterSet.m version [2a5bb72f8f].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | /* * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, * 2018, 2019 * Jonathan Schleifer <js@heap.zone> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #import "OFRangeCharacterSet.h" #import "OFString.h" #import "OFOutOfRangeException.h" @implementation OFRangeCharacterSet - (instancetype)init { OF_INVALID_INIT_METHOD } - (instancetype)initWithRange: (of_range_t)range { self = [super init]; @try { if (SIZE_MAX - range.location < range.length) @throw [OFOutOfRangeException exception]; _range = range; } @catch (id e) { [self release]; @throw e; } return self; } - (bool)characterIsMember: (of_unichar_t)character { return (character >= _range.location && character < _range.location + _range.length); } @end |
Added src/OFRangeValue.h version [485fced595].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | /* * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, * 2018, 2019 * Jonathan Schleifer <js@heap.zone> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #import "OFValue.h" OF_ASSUME_NONNULL_BEGIN @interface OFRangeValue: OFValue { of_range_t _range; } @end OF_ASSUME_NONNULL_END |
Added src/OFRangeValue.m version [be3ef80c2e].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 | /* * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, * 2018, 2019 * Jonathan Schleifer <js@heap.zone> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #import "OFRangeValue.h" #import "OFMethodSignature.h" #import "OFString.h" #import "OFOutOfRangeException.h" @implementation OFRangeValue @synthesize rangeValue = _range; - (instancetype)initWithRange: (of_range_t)range { self = [super init]; _range = range; return self; } - (const char *)objCType { return @encode(of_range_t); } - (void)getValue: (void *)value size: (size_t)size { if (size != sizeof(_range)) @throw [OFOutOfRangeException exception]; memcpy(value, &_range, sizeof(_range)); } - (OFString *)description { return [OFString stringWithFormat: @"<OFValue: of_range_t { %zu, %zu }>", _range.location, _range.length]; } @end |
Added src/OFRectangleValue.h version [e6635df87d].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | /* * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, * 2018, 2019 * Jonathan Schleifer <js@heap.zone> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #import "OFValue.h" OF_ASSUME_NONNULL_BEGIN @interface OFRectangleValue: OFValue { of_rectangle_t _rectangle; } @end OF_ASSUME_NONNULL_END |
Added src/OFRectangleValue.m version [db98ba72cf].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 | /* * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, * 2018, 2019 * Jonathan Schleifer <js@heap.zone> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #import "OFRectangleValue.h" #import "OFMethodSignature.h" #import "OFString.h" #import "OFOutOfRangeException.h" @implementation OFRectangleValue @synthesize rectangleValue = _rectangle; - (instancetype)initWithRectangle: (of_rectangle_t)rectangle { self = [super init]; _rectangle = rectangle; return self; } - (const char *)objCType { return @encode(of_rectangle_t); } - (void)getValue: (void *)value size: (size_t)size { if (size != sizeof(_rectangle)) @throw [OFOutOfRangeException exception]; memcpy(value, &_rectangle, sizeof(_rectangle)); } - (OFString *)description { return [OFString stringWithFormat: @"<OFValue: of_rectangle_t { %f, %f, %f, %f }>", _rectangle.origin.x, _rectangle.origin.y, _rectangle.size.width, _rectangle.size.height]; } @end |
Modified src/OFRunLoop+Private.h from [b6012d804d] to [4e253bdb74].
︙ | ︙ | |||
20 21 22 23 24 25 26 | #ifdef OF_HAVE_SOCKETS # import "OFTCPSocket.h" # import "OFUDPSocket.h" #endif OF_ASSUME_NONNULL_BEGIN | < < | 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | #ifdef OF_HAVE_SOCKETS # import "OFTCPSocket.h" # import "OFUDPSocket.h" #endif OF_ASSUME_NONNULL_BEGIN #ifdef OF_HAVE_SOCKETS @protocol OFTCPSocketDelegate_Private <OFObject> - (void)of_socketDidConnect: (OFTCPSocket *)socket exception: (nullable id)exception; @end #endif |
︙ | ︙ |
Modified src/OFRunLoop.m from [355a023a1d] to [67b18d3257].
︙ | ︙ | |||
43 44 45 46 47 48 49 | #ifdef OF_HAVE_SOCKETS # import "OFConnectionFailedException.h" #endif of_run_loop_mode_t of_run_loop_mode_default = @"of_run_loop_mode_default"; static OFRunLoop *mainRunLoop = nil; | | < < < < < > > > > > | | | | | | | | | | | | 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 | #ifdef OF_HAVE_SOCKETS # import "OFConnectionFailedException.h" #endif of_run_loop_mode_t of_run_loop_mode_default = @"of_run_loop_mode_default"; static OFRunLoop *mainRunLoop = nil; @interface OFRunLoopState: OFObject #ifdef OF_HAVE_SOCKETS <OFKernelEventObserverDelegate> #endif { @public OFSortedList OF_GENERIC(OFTimer *) *_timersQueue; #ifdef OF_HAVE_THREADS OFMutex *_timersQueueMutex; #endif #if defined(OF_HAVE_SOCKETS) OFKernelEventObserver *_kernelEventObserver; OFMutableDictionary *_readQueues, *_writeQueues; #elif defined(OF_HAVE_THREADS) OFCondition *_condition; #endif } @end @interface OFRunLoop () - (OFRunLoopState *)of_stateForMode: (of_run_loop_mode_t)mode create: (bool)create; @end #ifdef OF_HAVE_SOCKETS @interface OFRunLoopQueueItem: OFObject { @public id _delegate; } - (bool)handleObject: (id)object; @end @interface OFRunLoopReadQueueItem: OFRunLoopQueueItem { @public # ifdef OF_HAVE_BLOCKS of_stream_async_read_block_t _block; # endif void *_buffer; size_t _length; } @end @interface OFRunLoopExactReadQueueItem: OFRunLoopQueueItem { @public # ifdef OF_HAVE_BLOCKS of_stream_async_read_block_t _block; # endif void *_buffer; size_t _exactLength, _readLength; } @end @interface OFRunLoopReadLineQueueItem: OFRunLoopQueueItem { @public # ifdef OF_HAVE_BLOCKS of_stream_async_read_line_block_t _block; # endif of_string_encoding_t _encoding; } @end @interface OFRunLoopWriteDataQueueItem: OFRunLoopQueueItem { @public # ifdef OF_HAVE_BLOCKS of_stream_async_write_data_block_t _block; # endif OFData *_data; size_t _writtenLength; } @end @interface OFRunLoopWriteStringQueueItem: OFRunLoopQueueItem { @public # ifdef OF_HAVE_BLOCKS of_stream_async_write_string_block_t _block; # endif OFString *_string; of_string_encoding_t _encoding; size_t _writtenLength; } @end # if !defined(OF_WII) && !defined(OF_NINTENDO_3DS) @interface OFRunLoopConnectQueueItem: OFRunLoopQueueItem @end # endif @interface OFRunLoopAcceptQueueItem: OFRunLoopQueueItem { @public # ifdef OF_HAVE_BLOCKS of_tcp_socket_async_accept_block_t _block; # endif } @end @interface OFRunLoopUDPReceiveQueueItem: OFRunLoopQueueItem { @public # ifdef OF_HAVE_BLOCKS of_udp_socket_async_receive_block_t _block; # endif void *_buffer; size_t _length; } @end @interface OFRunLoopUDPSendQueueItem: OFRunLoopQueueItem { @public # ifdef OF_HAVE_BLOCKS of_udp_socket_async_send_data_block_t _block; # endif OFData *_data; of_socket_address_t _receiver; } @end #endif @implementation OFRunLoopState - (instancetype)init { self = [super init]; @try { _timersQueue = [[OFSortedList alloc] init]; |
︙ | ︙ | |||
215 216 217 218 219 220 221 | #ifdef OF_HAVE_SOCKETS - (void)objectIsReadyForReading: (id)object { /* * Retain the queue so that it doesn't disappear from us because the * handler called -[cancelAsyncRequests]. */ | | | 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 | #ifdef OF_HAVE_SOCKETS - (void)objectIsReadyForReading: (id)object { /* * Retain the queue so that it doesn't disappear from us because the * handler called -[cancelAsyncRequests]. */ OFList OF_GENERIC(OF_KINDOF(OFRunLoopReadQueueItem *)) *queue = [[_readQueues objectForKey: object] retain]; assert(queue != nil); @try { if (![queue.firstObject handleObject: object]) { of_list_object_t *listObject = queue.firstListObject; |
︙ | ︙ | |||
299 300 301 302 303 304 305 | [queue release]; } } #endif @end #ifdef OF_HAVE_SOCKETS | | | | 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 | [queue release]; } } #endif @end #ifdef OF_HAVE_SOCKETS @implementation OFRunLoopQueueItem - (bool)handleObject: (id)object { OF_UNRECOGNIZED_SELECTOR } - (void)dealloc { [_delegate release]; [super dealloc]; } @end @implementation OFRunLoopReadQueueItem - (bool)handleObject: (id)object { size_t length; id exception = nil; @try { length = [object readIntoBuffer: _buffer |
︙ | ︙ | |||
355 356 357 358 359 360 361 | [_block release]; [super dealloc]; } # endif @end | | | 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 | [_block release]; [super dealloc]; } # endif @end @implementation OFRunLoopExactReadQueueItem - (bool)handleObject: (id)object { size_t length; id exception = nil; @try { length = [object readIntoBuffer: (char *)_buffer + _readLength |
︙ | ︙ | |||
411 412 413 414 415 416 417 | [_block release]; [super dealloc]; } # endif @end | | | 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 | [_block release]; [super dealloc]; } # endif @end @implementation OFRunLoopReadLineQueueItem - (bool)handleObject: (id)object { OFString *line; id exception = nil; @try { line = [object tryReadLineWithEncoding: _encoding]; |
︙ | ︙ | |||
454 455 456 457 458 459 460 | [_block release]; [super dealloc]; } # endif @end | | | 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 | [_block release]; [super dealloc]; } # endif @end @implementation OFRunLoopWriteDataQueueItem - (bool)handleObject: (id)object { size_t length; id exception = nil; size_t dataLength = _data.count * _data.itemSize; OFData *newData, *oldData; |
︙ | ︙ | |||
526 527 528 529 530 531 532 | [_block release]; # endif [super dealloc]; } @end | | | 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 | [_block release]; # endif [super dealloc]; } @end @implementation OFRunLoopWriteStringQueueItem - (bool)handleObject: (id)object { size_t length; id exception = nil; size_t cStringLength = [_string cStringLengthWithEncoding: _encoding]; OFString *newString, *oldString; |
︙ | ︙ | |||
601 602 603 604 605 606 607 | # endif [super dealloc]; } @end # if !defined(OF_WII) && !defined(OF_NINTENDO_3DS) | | | 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 | # endif [super dealloc]; } @end # if !defined(OF_WII) && !defined(OF_NINTENDO_3DS) @implementation OFRunLoopConnectQueueItem - (bool)handleObject: (id)object { id exception = nil; int errNo; if ((errNo = [object of_socketError]) != 0) exception = [OFConnectionFailedException |
︙ | ︙ | |||
624 625 626 627 628 629 630 | exception: exception]; return false; } @end # endif | | | 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 | exception: exception]; return false; } @end # endif @implementation OFRunLoopAcceptQueueItem - (bool)handleObject: (id)object { OFTCPSocket *acceptedSocket; id exception = nil; @try { acceptedSocket = [object accept]; |
︙ | ︙ | |||
664 665 666 667 668 669 670 | [_block release]; [super dealloc]; } # endif @end | | | 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 | [_block release]; [super dealloc]; } # endif @end @implementation OFRunLoopUDPReceiveQueueItem - (bool)handleObject: (id)object { size_t length; of_socket_address_t address; id exception = nil; @try { |
︙ | ︙ | |||
709 710 711 712 713 714 715 | [_block release]; [super dealloc]; } # endif @end | | | 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 | [_block release]; [super dealloc]; } # endif @end @implementation OFRunLoopUDPSendQueueItem - (bool)handleObject: (id)object { id exception = nil; OFData *newData, *oldData; @try { [object sendBuffer: _data.items |
︙ | ︙ | |||
797 798 799 800 801 802 803 | mainRunLoop = [runLoop retain]; } #ifdef OF_HAVE_SOCKETS # define NEW_READ(type, object, mode) \ void *pool = objc_autoreleasePoolPush(); \ OFRunLoop *runLoop = [self currentRunLoop]; \ | | | | | | 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 | mainRunLoop = [runLoop retain]; } #ifdef OF_HAVE_SOCKETS # define NEW_READ(type, object, mode) \ void *pool = objc_autoreleasePoolPush(); \ OFRunLoop *runLoop = [self currentRunLoop]; \ OFRunLoopState *state = [runLoop of_stateForMode: mode \ create: true]; \ OFList *queue = [state->_readQueues objectForKey: object]; \ type *queueItem; \ \ if (queue == nil) { \ queue = [OFList list]; \ [state->_readQueues setObject: queue \ forKey: object]; \ } \ \ if (queue.count == 0) \ [state->_kernelEventObserver \ addObjectForReading: object]; \ \ queueItem = [[[type alloc] init] autorelease]; # define NEW_WRITE(type, object, mode) \ void *pool = objc_autoreleasePoolPush(); \ OFRunLoop *runLoop = [self currentRunLoop]; \ OFRunLoopState *state = [runLoop of_stateForMode: mode \ create: true]; \ OFList *queue = [state->_writeQueues objectForKey: object]; \ type *queueItem; \ \ if (queue == nil) { \ queue = [OFList list]; \ [state->_writeQueues setObject: queue \ forKey: object]; \ |
︙ | ︙ | |||
847 848 849 850 851 852 853 | length: (size_t)length mode: (of_run_loop_mode_t)mode # ifdef OF_HAVE_BLOCKS block: (of_stream_async_read_block_t)block # endif delegate: (id <OFStreamDelegate>)delegate { | | | 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 | length: (size_t)length mode: (of_run_loop_mode_t)mode # ifdef OF_HAVE_BLOCKS block: (of_stream_async_read_block_t)block # endif delegate: (id <OFStreamDelegate>)delegate { NEW_READ(OFRunLoopReadQueueItem, stream, mode) queueItem->_delegate = [delegate retain]; # ifdef OF_HAVE_BLOCKS queueItem->_block = [block copy]; # endif queueItem->_buffer = buffer; queueItem->_length = length; |
︙ | ︙ | |||
869 870 871 872 873 874 875 | exactLength: (size_t)exactLength mode: (of_run_loop_mode_t)mode # ifdef OF_HAVE_BLOCKS block: (of_stream_async_read_block_t)block # endif delegate: (id <OFStreamDelegate>)delegate { | | | | | | | | | 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 | exactLength: (size_t)exactLength mode: (of_run_loop_mode_t)mode # ifdef OF_HAVE_BLOCKS block: (of_stream_async_read_block_t)block # endif delegate: (id <OFStreamDelegate>)delegate { NEW_READ(OFRunLoopExactReadQueueItem, stream, mode) queueItem->_delegate = [delegate retain]; # ifdef OF_HAVE_BLOCKS queueItem->_block = [block copy]; # endif queueItem->_buffer = buffer; queueItem->_exactLength = exactLength; QUEUE_ITEM } + (void)of_addAsyncReadLineForStream: (OFStream <OFReadyForReadingObserving> *) stream encoding: (of_string_encoding_t)encoding mode: (of_run_loop_mode_t)mode # ifdef OF_HAVE_BLOCKS block: (of_stream_async_read_line_block_t)block # endif delegate: (id <OFStreamDelegate>)delegate { NEW_READ(OFRunLoopReadLineQueueItem, stream, mode) queueItem->_delegate = [delegate retain]; # ifdef OF_HAVE_BLOCKS queueItem->_block = [block copy]; # endif queueItem->_encoding = encoding; QUEUE_ITEM } + (void)of_addAsyncWriteForStream: (OFStream <OFReadyForWritingObserving> *) stream data: (OFData *)data mode: (of_run_loop_mode_t)mode # ifdef OF_HAVE_BLOCKS block: (of_stream_async_write_data_block_t)block # endif delegate: (id <OFStreamDelegate>)delegate { NEW_WRITE(OFRunLoopWriteDataQueueItem, stream, mode) queueItem->_delegate = [delegate retain]; # ifdef OF_HAVE_BLOCKS queueItem->_block = [block copy]; # endif queueItem->_data = [data copy]; QUEUE_ITEM } + (void)of_addAsyncWriteForStream: (OFStream <OFReadyForWritingObserving> *) stream string: (OFString *)string encoding: (of_string_encoding_t)encoding mode: (of_run_loop_mode_t)mode # ifdef OF_HAVE_BLOCKS block: (of_stream_async_write_string_block_t)block # endif delegate: (id <OFStreamDelegate>)delegate { NEW_WRITE(OFRunLoopWriteStringQueueItem, stream, mode) queueItem->_delegate = [delegate retain]; # ifdef OF_HAVE_BLOCKS queueItem->_block = [block copy]; # endif queueItem->_string = [string copy]; queueItem->_encoding = encoding; QUEUE_ITEM } # if !defined(OF_WII) && !defined(OF_NINTENDO_3DS) + (void)of_addAsyncConnectForTCPSocket: (OFTCPSocket *)stream mode: (of_run_loop_mode_t)mode delegate: (id <OFTCPSocketDelegate_Private>) delegate { NEW_WRITE(OFRunLoopConnectQueueItem, stream, mode) queueItem->_delegate = [delegate retain]; QUEUE_ITEM } # endif + (void)of_addAsyncAcceptForTCPSocket: (OFTCPSocket *)stream mode: (of_run_loop_mode_t)mode # ifdef OF_HAVE_BLOCKS block: (of_tcp_socket_async_accept_block_t)block # endif delegate: (id <OFTCPSocketDelegate>)delegate { NEW_READ(OFRunLoopAcceptQueueItem, stream, mode) queueItem->_delegate = [delegate retain]; # ifdef OF_HAVE_BLOCKS queueItem->_block = [block copy]; # endif QUEUE_ITEM } + (void)of_addAsyncReceiveForUDPSocket: (OFUDPSocket *)sock buffer: (void *)buffer length: (size_t)length mode: (of_run_loop_mode_t)mode # ifdef OF_HAVE_BLOCKS block: (of_udp_socket_async_receive_block_t) block # endif delegate: (id <OFUDPSocketDelegate>)delegate { NEW_READ(OFRunLoopUDPReceiveQueueItem, sock, mode) queueItem->_delegate = [delegate retain]; # ifdef OF_HAVE_BLOCKS queueItem->_block = [block copy]; # endif queueItem->_buffer = buffer; queueItem->_length = length; |
︙ | ︙ | |||
1006 1007 1008 1009 1010 1011 1012 | mode: (of_run_loop_mode_t)mode # ifdef OF_HAVE_BLOCKS block: (of_udp_socket_async_send_data_block_t) block # endif delegate: (id <OFUDPSocketDelegate>)delegate { | | | | | 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 | mode: (of_run_loop_mode_t)mode # ifdef OF_HAVE_BLOCKS block: (of_udp_socket_async_send_data_block_t) block # endif delegate: (id <OFUDPSocketDelegate>)delegate { NEW_WRITE(OFRunLoopUDPSendQueueItem, sock, mode) queueItem->_delegate = [delegate retain]; # ifdef OF_HAVE_BLOCKS queueItem->_block = [block copy]; # endif queueItem->_data = [data copy]; queueItem->_receiver = *receiver; QUEUE_ITEM } # undef NEW_READ # undef NEW_WRITE # undef QUEUE_ITEM + (void)of_cancelAsyncRequestsForObject: (id)object mode: (of_run_loop_mode_t)mode { void *pool = objc_autoreleasePoolPush(); OFRunLoop *runLoop = [self currentRunLoop]; OFRunLoopState *state = [runLoop of_stateForMode: mode create: false]; OFList *queue; if (state == nil) return; if ((queue = [state->_writeQueues objectForKey: object]) != nil) { assert(queue.count > 0); |
︙ | ︙ | |||
1068 1069 1070 1071 1072 1073 1074 | #endif - (instancetype)init { self = [super init]; @try { | | | | 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 | #endif - (instancetype)init { self = [super init]; @try { OFRunLoopState *state; _states = [[OFMutableDictionary alloc] init]; state = [[OFRunLoopState alloc] init]; @try { [_states setObject: state forKey: of_run_loop_mode_default]; } @finally { [state release]; } |
︙ | ︙ | |||
1101 1102 1103 1104 1105 1106 1107 | #ifdef OF_HAVE_THREADS [_statesMutex release]; #endif [super dealloc]; } | | | | | | 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 | #ifdef OF_HAVE_THREADS [_statesMutex release]; #endif [super dealloc]; } - (OFRunLoopState *)of_stateForMode: (of_run_loop_mode_t)mode create: (bool)create { OFRunLoopState *state; #ifdef OF_HAVE_THREADS [_statesMutex lock]; @try { #endif state = [_states objectForKey: mode]; if (create && state == nil) { state = [[OFRunLoopState alloc] init]; @try { [_states setObject: state forKey: mode]; } @finally { [state release]; } } |
︙ | ︙ | |||
1139 1140 1141 1142 1143 1144 1145 | [self addTimer: timer forMode: of_run_loop_mode_default]; } - (void)addTimer: (OFTimer *)timer forMode: (of_run_loop_mode_t)mode { | | | | 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 | [self addTimer: timer forMode: of_run_loop_mode_default]; } - (void)addTimer: (OFTimer *)timer forMode: (of_run_loop_mode_t)mode { OFRunLoopState *state = [self of_stateForMode: mode create: true]; #ifdef OF_HAVE_THREADS [state->_timersQueueMutex lock]; @try { #endif [state->_timersQueue insertObject: timer]; #ifdef OF_HAVE_THREADS |
︙ | ︙ | |||
1166 1167 1168 1169 1170 1171 1172 | [state->_condition signal]; #endif } - (void)of_removeTimer: (OFTimer *)timer forMode: (of_run_loop_mode_t)mode { | | | | 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 | [state->_condition signal]; #endif } - (void)of_removeTimer: (OFTimer *)timer forMode: (of_run_loop_mode_t)mode { OFRunLoopState *state = [self of_stateForMode: mode create: false]; if (state == nil) return; #ifdef OF_HAVE_THREADS [state->_timersQueueMutex lock]; @try { |
︙ | ︙ | |||
1212 1213 1214 1215 1216 1217 1218 | } - (void)runMode: (of_run_loop_mode_t)mode beforeDate: (OFDate *)deadline { void *pool = objc_autoreleasePoolPush(); of_run_loop_mode_t previousMode = _currentMode; | | | | 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 | } - (void)runMode: (of_run_loop_mode_t)mode beforeDate: (OFDate *)deadline { void *pool = objc_autoreleasePoolPush(); of_run_loop_mode_t previousMode = _currentMode; OFRunLoopState *state = [self of_stateForMode: mode create: false]; if (state == nil) return; _currentMode = mode; @try { OFDate *nextTimer; |
︙ | ︙ | |||
1328 1329 1330 1331 1332 1333 1334 | } @finally { _currentMode = previousMode; } } - (void)stop { | | | | 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 | } @finally { _currentMode = previousMode; } } - (void)stop { OFRunLoopState *state = [self of_stateForMode: of_run_loop_mode_default create: false]; _stop = true; if (state == nil) return; #if defined(OF_HAVE_SOCKETS) [state->_kernelEventObserver cancel]; #elif defined(OF_HAVE_THREADS) [state->_condition signal]; #endif } @end |
Added src/OFSelectKernelEventObserver.h version [4637ad2ef9].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | /* * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, * 2018, 2019 * Jonathan Schleifer <js@heap.zone> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "objfw-defs.h" #ifndef __STDC_LIMIT_MACROS # define __STDC_LIMIT_MACROS #endif #ifndef __STDC_CONSTANT_MACROS # define __STDC_CONSTANT_MACROS #endif #ifdef HAVE_SYS_SELECT_H # include <sys/select.h> #endif #import "OFKernelEventObserver.h" OF_ASSUME_NONNULL_BEGIN @interface OFSelectKernelEventObserver: OFKernelEventObserver { fd_set _readFDs, _writeFDs; int _maxFD; } @end OF_ASSUME_NONNULL_END |
Added src/OFSelectKernelEventObserver.m version [4d2c210634].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 | /* * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, * 2018, 2019 * Jonathan Schleifer <js@heap.zone> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #define __NO_EXT_QNX #include "config.h" #include "platform.h" #ifdef OF_WINDOWS /* Win32 has a ridiculous default of 64, even though it supports much more. */ # define FD_SETSIZE 1024 #endif #include <errno.h> #include <math.h> #include <string.h> #include <sys/time.h> #import "OFSelectKernelEventObserver.h" #import "OFArray.h" #import "OFKernelEventObserver+Private.h" #import "OFKernelEventObserver.h" #import "OFInitializationFailedException.h" #import "OFObserveFailedException.h" #import "OFOutOfRangeException.h" #import "socket_helpers.h" @implementation OFSelectKernelEventObserver - (instancetype)init { self = [super init]; #ifndef OF_WINDOWS if (_cancelFD[0] >= (int)FD_SETSIZE) @throw [OFInitializationFailedException exceptionWithClass: self.class]; #endif FD_ZERO(&_readFDs); FD_ZERO(&_writeFDs); FD_SET(_cancelFD[0], &_readFDs); if (_cancelFD[0] > INT_MAX) @throw [OFOutOfRangeException exception]; _maxFD = (int)_cancelFD[0]; return self; } - (void)of_addObjectForReading: (id <OFReadyForReadingObserving>)object { int fd = object.fileDescriptorForReading; if (fd < 0 || fd > INT_MAX - 1) @throw [OFOutOfRangeException exception]; #ifndef OF_WINDOWS if (fd >= (int)FD_SETSIZE) @throw [OFOutOfRangeException exception]; #endif if (fd > _maxFD) _maxFD = fd; FD_SET((of_socket_t)fd, &_readFDs); } - (void)of_addObjectForWriting: (id <OFReadyForWritingObserving>)object { int fd = object.fileDescriptorForWriting; if (fd < 0 || fd > INT_MAX - 1) @throw [OFOutOfRangeException exception]; #ifndef OF_WINDOWS if (fd >= (int)FD_SETSIZE) @throw [OFOutOfRangeException exception]; #endif if (fd > _maxFD) _maxFD = fd; FD_SET((of_socket_t)fd, &_writeFDs); } - (void)of_removeObjectForReading: (id <OFReadyForReadingObserving>)object { /* TODO: Adjust _maxFD */ int fd = object.fileDescriptorForReading; if (fd < 0) @throw [OFOutOfRangeException exception]; #ifndef OF_WINDOWS if (fd >= (int)FD_SETSIZE) @throw [OFOutOfRangeException exception]; #endif FD_CLR((of_socket_t)fd, &_readFDs); } - (void)of_removeObjectForWriting: (id <OFReadyForWritingObserving>)object { /* TODO: Adjust _maxFD */ int fd = object.fileDescriptorForWriting; if (fd < 0) @throw [OFOutOfRangeException exception]; #ifndef OF_WINDOWS if (fd >= (int)FD_SETSIZE) @throw [OFOutOfRangeException exception]; #endif FD_CLR((of_socket_t)fd, &_writeFDs); } - (void)observeForTimeInterval: (of_time_interval_t)timeInterval { id const *objects; fd_set readFDs; fd_set writeFDs; struct timeval timeout; int events; size_t count; [self of_processQueue]; if ([self of_processReadBuffers]) return; #ifdef FD_COPY FD_COPY(&_readFDs, &readFDs); FD_COPY(&_writeFDs, &writeFDs); #else readFDs = _readFDs; writeFDs = _writeFDs; #endif /* * We cast to int before assigning to tv_usec in order to avoid a * warning with Apple GCC on PowerPC. POSIX defines this as suseconds_t, * however, this is not available on Win32. As an int should always * satisfy the required range, we just cast to int. */ #ifndef OF_WINDOWS timeout.tv_sec = (time_t)timeInterval; #else timeout.tv_sec = (long)timeInterval; #endif timeout.tv_usec = (int)lrint((timeInterval - timeout.tv_sec) * 1000); events = select(_maxFD + 1, &readFDs, &writeFDs, NULL, (timeInterval != -1 ? &timeout : NULL)); if (events < 0) @throw [OFObserveFailedException exceptionWithObserver: self errNo: errno]; if (FD_ISSET(_cancelFD[0], &readFDs)) { char buffer; #ifdef OF_HAVE_PIPE OF_ENSURE(read(_cancelFD[0], &buffer, 1) == 1); #else OF_ENSURE(recvfrom(_cancelFD[0], (void *)&buffer, 1, 0, NULL, NULL) == 1); #endif } objects = _readObjects.objects; count = _readObjects.count; for (size_t i = 0; i < count; i++) { void *pool = objc_autoreleasePoolPush(); int fd = [objects[i] fileDescriptorForReading]; if (FD_ISSET((of_socket_t)fd, &readFDs) && [_delegate respondsToSelector: @selector(objectIsReadyForReading:)]) [_delegate objectIsReadyForReading: objects[i]]; objc_autoreleasePoolPop(pool); } objects = _writeObjects.objects; count = _writeObjects.count; for (size_t i = 0; i < count; i++) { void *pool = objc_autoreleasePoolPush(); int fd = [objects[i] fileDescriptorForWriting]; if (FD_ISSET((of_socket_t)fd, &writeFDs) && [_delegate respondsToSelector: @selector(objectIsReadyForWriting:)]) [_delegate objectIsReadyForWriting: objects[i]]; objc_autoreleasePoolPop(pool); } } @end |
Modified src/OFSet.m from [a05b34b142] to [9b44169159].
︙ | ︙ | |||
16 17 18 19 20 21 22 | */ #include "config.h" #include <stdlib.h> #import "OFSet.h" | | | | | | | | | | | | | | | | | | | 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 | */ #include "config.h" #include <stdlib.h> #import "OFSet.h" #import "OFArray.h" #import "OFMapTableSet.h" #import "OFNull.h" #import "OFString.h" #import "OFXMLElement.h" static struct { Class isa; } placeholder; @interface OFSetPlaceholder: OFSet @end @implementation OFSetPlaceholder - (instancetype)init { return (id)[[OFMapTableSet alloc] init]; } - (instancetype)initWithSet: (OFSet *)set { return (id)[[OFMapTableSet alloc] initWithSet: set]; } - (instancetype)initWithArray: (OFArray *)array { return (id)[[OFMapTableSet alloc] initWithArray: array]; } - (instancetype)initWithObjects: (id)firstObject, ... { id ret; va_list arguments; va_start(arguments, firstObject); ret = [[OFMapTableSet alloc] initWithObject: firstObject arguments: arguments]; va_end(arguments); return ret; } - (instancetype)initWithObjects: (id const *)objects count: (size_t)count { return (id)[[OFMapTableSet alloc] initWithObjects: objects count: count]; } - (instancetype)initWithObject: (id)firstObject arguments: (va_list)arguments { return (id)[[OFMapTableSet alloc] initWithObject: firstObject arguments: arguments]; } - (instancetype)initWithSerialization: (OFXMLElement *)element { return (id)[[OFMapTableSet alloc] initWithSerialization: element]; } - (instancetype)retain { return self; } |
︙ | ︙ | |||
101 102 103 104 105 106 107 | } @end @implementation OFSet + (void)initialize { if (self == [OFSet class]) | | | 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 | } @end @implementation OFSet + (void)initialize { if (self == [OFSet class]) placeholder.isa = [OFSetPlaceholder class]; } + (instancetype)alloc { if (self == [OFSet class]) return (id)&placeholder; |
︙ | ︙ |
Deleted src/OFSet_hashtable.h version [6fd5558fe2].
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted src/OFSet_hashtable.m version [58bc1233e4].
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Modified src/OFSettings.m from [541f2a44aa] to [f9222a1d34].
︙ | ︙ | |||
14 15 16 17 18 19 20 | * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #import "OFSettings.h" | | | | 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #import "OFSettings.h" #import "OFINIFileSettings.h" #import "OFString.h" @implementation OFSettings @synthesize applicationName = _applicationName; + (instancetype)alloc { if (self == [OFSettings class]) return [OFINIFileSettings alloc]; return [super alloc]; } + (instancetype)settingsWithApplicationName: (OFString *)applicationName { return [[[self alloc] |
︙ | ︙ |
Deleted src/OFSettings_INIFile.h version [846389819b].
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted src/OFSettings_INIFile.m version [4d0ca9211c].
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Modified src/OFStdIOStream.m from [29dc6410b2] to [7b4906ae53].
︙ | ︙ | |||
29 30 31 32 33 34 35 | #endif #import "OFStdIOStream.h" #import "OFStdIOStream+Private.h" #import "OFDate.h" #import "OFApplication.h" #ifdef OF_WINDOWS | | | 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | #endif #import "OFStdIOStream.h" #import "OFStdIOStream+Private.h" #import "OFDate.h" #import "OFApplication.h" #ifdef OF_WINDOWS # include "OFWin32ConsoleStdIOStream.h" #endif #import "OFInitializationFailedException.h" #import "OFNotOpenException.h" #import "OFOutOfRangeException.h" #import "OFReadFailedException.h" #import "OFWriteFailedException.h" |
︙ | ︙ | |||
51 52 53 54 55 56 57 | # include <proto/exec.h> # include <proto/dos.h> #endif /* References for static linking */ #ifdef OF_WINDOWS void | | | | 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 | # include <proto/exec.h> # include <proto/dos.h> #endif /* References for static linking */ #ifdef OF_WINDOWS void _reference_to_OFWin32ConsoleStdIOStream(void) { [OFWin32ConsoleStdIOStream class]; } #endif #ifdef OF_AMIGAOS4 extern struct ExecIFace *IExec; static struct Library *DOSBase = NULL; static struct DOSIFace *IDOS = NULL; |
︙ | ︙ |
Deleted src/OFStdIOStream_Win32Console.h version [03ed6af464].
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted src/OFStdIOStream_Win32Console.m version [7e7d715431].
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Modified src/OFString.m from [8cbfa26fc2] to [3f6a4254de].
︙ | ︙ | |||
27 28 29 30 31 32 33 | # include <locale.h> #endif #ifdef HAVE_XLOCALE_H # include <xlocale.h> #endif #import "OFString.h" | < < > > | 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 | # include <locale.h> #endif #ifdef HAVE_XLOCALE_H # include <xlocale.h> #endif #import "OFString.h" #import "OFArray.h" #import "OFCharacterSet.h" #import "OFData.h" #import "OFDictionary.h" #ifdef OF_HAVE_FILES # import "OFFile.h" # import "OFFileManager.h" #endif #import "OFLocale.h" #import "OFStream.h" #import "OFURL.h" #import "OFURLHandler.h" #import "OFUTF8String+Private.h" #import "OFUTF8String.h" #import "OFXMLElement.h" #import "OFInitializationFailedException.h" #import "OFInvalidArgumentException.h" #import "OFInvalidEncodingException.h" #import "OFInvalidFormatException.h" #import "OFNotImplementedException.h" |
︙ | ︙ | |||
90 91 92 93 94 95 96 | lossy: (bool)lossy; - (const char *)of_cStringWithEncoding: (of_string_encoding_t)encoding lossy: (bool)lossy; - (OFString *)of_JSONRepresentationWithOptions: (int)options depth: (size_t)depth; @end | | | 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 | lossy: (bool)lossy; - (const char *)of_cStringWithEncoding: (of_string_encoding_t)encoding lossy: (bool)lossy; - (OFString *)of_JSONRepresentationWithOptions: (int)options depth: (size_t)depth; @end @interface OFStringPlaceholder: OFString @end extern bool of_unicode_to_iso_8859_2(const of_unichar_t *, unsigned char *, size_t, bool); extern bool of_unicode_to_iso_8859_3(const of_unichar_t *, unsigned char *, size_t, bool); extern bool of_unicode_to_iso_8859_15(const of_unichar_t *, unsigned char *, |
︙ | ︙ | |||
363 364 365 366 367 368 369 | objc_autoreleasePoolPop(pool); return ret; } #endif | | | | < | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 | objc_autoreleasePoolPop(pool); return ret; } #endif @implementation OFStringPlaceholder - (instancetype)init { return (id)[[OFUTF8String alloc] init]; } - (instancetype)initWithUTF8String: (const char *)UTF8String { id string; size_t length; void *storage; length = strlen(UTF8String); string = of_alloc_object([OFUTF8String class], length + 1, 1, &storage); return (id)[string of_initWithUTF8String: UTF8String length: length storage: storage]; } - (instancetype)initWithUTF8String: (const char *)UTF8String length: (size_t)UTF8StringLength { id string; void *storage; string = of_alloc_object([OFUTF8String class], UTF8StringLength + 1, 1, &storage); return (id)[string of_initWithUTF8String: UTF8String length: UTF8StringLength storage: storage]; } - (instancetype)initWithUTF8StringNoCopy: (char *)UTF8String freeWhenDone: (bool)freeWhenDone { return (id)[[OFUTF8String alloc] initWithUTF8StringNoCopy: UTF8String freeWhenDone: freeWhenDone]; } - (instancetype)initWithUTF8StringNoCopy: (char *)UTF8String length: (size_t)UTF8StringLength freeWhenDone: (bool)freeWhenDone { return (id)[[OFUTF8String alloc] initWithUTF8StringNoCopy: UTF8String length: UTF8StringLength freeWhenDone: freeWhenDone]; } - (instancetype)initWithCString: (const char *)cString encoding: (of_string_encoding_t)encoding { if (encoding == OF_STRING_ENCODING_UTF_8) { id string; size_t length; void *storage; length = strlen(cString); string = of_alloc_object([OFUTF8String class], length + 1, 1, &storage); return (id)[string of_initWithUTF8String: cString length: length storage: storage]; } return (id)[[OFUTF8String alloc] initWithCString: cString encoding: encoding]; } - (instancetype)initWithCString: (const char *)cString encoding: (of_string_encoding_t)encoding length: (size_t)cStringLength { if (encoding == OF_STRING_ENCODING_UTF_8) { id string; void *storage; string = of_alloc_object([OFUTF8String class], cStringLength + 1, 1, &storage); return (id)[string of_initWithUTF8String: cString length: cStringLength storage: storage]; } return (id)[[OFUTF8String alloc] initWithCString: cString encoding: encoding length: cStringLength]; } - (instancetype)initWithData: (OFData *)data encoding: (of_string_encoding_t)encoding { return (id)[[OFUTF8String alloc] initWithData: data encoding: encoding]; } - (instancetype)initWithString: (OFString *)string { return (id)[[OFUTF8String alloc] initWithString: string]; } - (instancetype)initWithCharacters: (const of_unichar_t *)string length: (size_t)length { return (id)[[OFUTF8String alloc] initWithCharacters: string length: length]; } - (instancetype)initWithUTF16String: (const of_char16_t *)string { return (id)[[OFUTF8String alloc] initWithUTF16String: string]; } - (instancetype)initWithUTF16String: (const of_char16_t *)string length: (size_t)length { return (id)[[OFUTF8String alloc] initWithUTF16String: string length: length]; } - (instancetype)initWithUTF16String: (const of_char16_t *)string byteOrder: (of_byte_order_t)byteOrder { return (id)[[OFUTF8String alloc] initWithUTF16String: string byteOrder: byteOrder]; } - (instancetype)initWithUTF16String: (const of_char16_t *)string length: (size_t)length byteOrder: (of_byte_order_t)byteOrder { return (id)[[OFUTF8String alloc] initWithUTF16String: string length: length byteOrder: byteOrder]; } - (instancetype)initWithUTF32String: (const of_char32_t *)string { return (id)[[OFUTF8String alloc] initWithUTF32String: string]; } - (instancetype)initWithUTF32String: (const of_char32_t *)string length: (size_t)length { return (id)[[OFUTF8String alloc] initWithUTF32String: string length: length]; } - (instancetype)initWithUTF32String: (const of_char32_t *)string byteOrder: (of_byte_order_t)byteOrder { return (id)[[OFUTF8String alloc] initWithUTF32String: string byteOrder: byteOrder]; } - (instancetype)initWithUTF32String: (const of_char32_t *)string length: (size_t)length byteOrder: (of_byte_order_t)byteOrder { return (id)[[OFUTF8String alloc] initWithUTF32String: string length: length byteOrder: byteOrder]; } - (instancetype)initWithFormat: (OFConstantString *)format, ... { id ret; va_list arguments; va_start(arguments, format); ret = [[OFUTF8String alloc] initWithFormat: format arguments: arguments]; va_end(arguments); return ret; } - (instancetype)initWithFormat: (OFConstantString *)format arguments: (va_list)arguments { return (id)[[OFUTF8String alloc] initWithFormat: format arguments: arguments]; } #ifdef OF_HAVE_FILES - (instancetype)initWithContentsOfFile: (OFString *)path { return (id)[[OFUTF8String alloc] initWithContentsOfFile: path]; } - (instancetype)initWithContentsOfFile: (OFString *)path encoding: (of_string_encoding_t)encoding { return (id)[[OFUTF8String alloc] initWithContentsOfFile: path encoding: encoding]; } #endif #if defined(OF_HAVE_FILES) || defined(OF_HAVE_SOCKETS) - (instancetype)initWithContentsOfURL: (OFURL *)URL { return (id)[[OFUTF8String alloc] initWithContentsOfURL: URL]; } - (instancetype)initWithContentsOfURL: (OFURL *)URL encoding: (of_string_encoding_t)encoding { return (id)[[OFUTF8String alloc] initWithContentsOfURL: URL encoding: encoding]; } #endif - (instancetype)initWithSerialization: (OFXMLElement *)element { return (id)[[OFUTF8String alloc] initWithSerialization: element]; } - (instancetype)retain { return self; } |
︙ | ︙ | |||
612 613 614 615 616 617 618 | @implementation OFString + (void)initialize { if (self != [OFString class]) return; | | | 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 | @implementation OFString + (void)initialize { if (self != [OFString class]) return; placeholder.isa = [OFStringPlaceholder class]; #if defined(HAVE_STRTOF_L) || defined(HAVE_STRTOD_L) if ((cLocale = newlocale(LC_ALL_MASK, "C", NULL)) == NULL) @throw [OFInitializationFailedException exceptionWithClass: self]; #endif } |
︙ | ︙ |
Deleted src/OFString_UTF8+Private.h version [10d3266c02].
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted src/OFString_UTF8.h version [24a96aaf1e].
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted src/OFString_UTF8.m version [c33b1359c4].
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Added src/OFSubarray.h version [85e9ff86dd].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | /* * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, * 2018, 2019 * Jonathan Schleifer <js@heap.zone> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #import "OFArray.h" OF_ASSUME_NONNULL_BEGIN @interface OFSubarray: OFArray { OFArray *_array; of_range_t _range; } + (instancetype)arrayWithArray: (OFArray *)array range: (of_range_t)range; - (instancetype)initWithArray: (OFArray *)array range: (of_range_t)range; @end OF_ASSUME_NONNULL_END |
Added src/OFSubarray.m version [f57b86e965].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 | /* * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, * 2018, 2019 * Jonathan Schleifer <js@heap.zone> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #import "OFSubarray.h" #import "OFOutOfRangeException.h" @implementation OFSubarray + (instancetype)arrayWithArray: (OFArray *)array range: (of_range_t)range { return [[[self alloc] initWithArray: array range: range] autorelease]; } - (instancetype)initWithArray: (OFArray *)array range: (of_range_t)range { self = [super init]; @try { /* Should usually be retain, as it's useless with a copy */ _array = [array copy]; _range = range; } @catch (id e) { [self release]; @throw e; } return self; } - (void)dealloc { [_array release]; [super dealloc]; } - (size_t)count { return _range.length; } - (id)objectAtIndex: (size_t)idx { if (idx >= _range.length) @throw [OFOutOfRangeException exception]; return [_array objectAtIndex: idx + _range.location]; } - (void)getObjects: (id *)buffer inRange: (of_range_t)range { if (range.length > SIZE_MAX - range.location || range.location + range.length > _range.length) @throw [OFOutOfRangeException exception]; range.location += _range.location; [_array getObjects: buffer inRange: range]; } - (size_t)indexOfObject: (id)object { size_t idx = [_array indexOfObject: object]; if (idx < _range.location) return OF_NOT_FOUND; idx -= _range.location; if (idx >= _range.length) return OF_NOT_FOUND; return idx; } - (size_t)indexOfObjectIdenticalTo: (id)object { size_t idx = [_array indexOfObjectIdenticalTo: object]; if (idx < _range.location) return OF_NOT_FOUND; idx -= _range.location; if (idx >= _range.length) return OF_NOT_FOUND; return idx; } - (OFArray *)objectsInRange: (of_range_t)range { if (range.length > SIZE_MAX - range.location || range.location + range.length > _range.length) @throw [OFOutOfRangeException exception]; range.location += _range.location; return [_array objectsInRange: range]; } @end |
Modified src/OFTCPSocket.m from [34fdf0c261] to [bfc7e59ebf].
︙ | ︙ | |||
62 63 64 65 66 67 68 | @"of_tcp_socket_connect_mode"; Class of_tls_socket_class = Nil; static OFString *defaultSOCKS5Host = nil; static uint16_t defaultSOCKS5Port = 1080; | | | 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 | @"of_tcp_socket_connect_mode"; Class of_tls_socket_class = Nil; static OFString *defaultSOCKS5Host = nil; static uint16_t defaultSOCKS5Port = 1080; @interface OFTCPSocketAsyncConnectDelegate: OFObject <OFTCPSocketDelegate, OFTCPSocketDelegate_Private, OFDNSResolverDelegate> { OFTCPSocket *_socket; OFString *_host; uint16_t _port; OFString *_SOCKS5Host; uint16_t _SOCKS5Port; |
︙ | ︙ | |||
110 111 112 113 114 115 116 | #endif - (void)didConnect; - (void)tryNextAddressWithRunLoopMode: (of_run_loop_mode_t)runLoopMode; - (void)startWithRunLoopMode: (of_run_loop_mode_t)runLoopMode; - (void)sendSOCKS5Request; @end | | | | 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 | #endif - (void)didConnect; - (void)tryNextAddressWithRunLoopMode: (of_run_loop_mode_t)runLoopMode; - (void)startWithRunLoopMode: (of_run_loop_mode_t)runLoopMode; - (void)sendSOCKS5Request; @end @interface OFTCPSocketConnectDelegate: OFObject <OFTCPSocketDelegate> { @public bool _done; id _exception; } @end @implementation OFTCPSocketAsyncConnectDelegate - (instancetype)initWithSocket: (OFTCPSocket *)sock host: (OFString *)host port: (uint16_t)port SOCKS5Host: (OFString *)SOCKS5Host SOCKS5Port: (uint16_t)SOCKS5Port delegate: (id <OFTCPSocketDelegate>)delegate { |
︙ | ︙ | |||
576 577 578 579 580 581 582 | default: assert(0); return nil; } } @end | | | 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 | default: assert(0); return nil; } } @end @implementation OFTCPSocketConnectDelegate - (void)dealloc { [_exception release]; [super dealloc]; } |
︙ | ︙ | |||
707 708 709 710 711 712 713 | #endif - (void)connectToHost: (OFString *)host port: (uint16_t)port { void *pool = objc_autoreleasePoolPush(); id <OFTCPSocketDelegate> delegate = [_delegate retain]; | | | | 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 | #endif - (void)connectToHost: (OFString *)host port: (uint16_t)port { void *pool = objc_autoreleasePoolPush(); id <OFTCPSocketDelegate> delegate = [_delegate retain]; OFTCPSocketConnectDelegate *connectDelegate = [[[OFTCPSocketConnectDelegate alloc] init] autorelease]; OFRunLoop *runLoop = [OFRunLoop currentRunLoop]; self.delegate = connectDelegate; [self asyncConnectToHost: host port: port runLoopMode: connectRunLoopMode]; |
︙ | ︙ | |||
746 747 748 749 750 751 752 | - (void)asyncConnectToHost: (OFString *)host port: (uint16_t)port runLoopMode: (of_run_loop_mode_t)runLoopMode { void *pool = objc_autoreleasePoolPush(); | | | 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 | - (void)asyncConnectToHost: (OFString *)host port: (uint16_t)port runLoopMode: (of_run_loop_mode_t)runLoopMode { void *pool = objc_autoreleasePoolPush(); [[[[OFTCPSocketAsyncConnectDelegate alloc] initWithSocket: self host: host port: port SOCKS5Host: _SOCKS5Host SOCKS5Port: _SOCKS5Port delegate: _delegate] autorelease] startWithRunLoopMode: runLoopMode]; |
︙ | ︙ | |||
776 777 778 779 780 781 782 | - (void)asyncConnectToHost: (OFString *)host port: (uint16_t)port runLoopMode: (of_run_loop_mode_t)runLoopMode block: (of_tcp_socket_async_connect_block_t)block { void *pool = objc_autoreleasePoolPush(); | | | 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 | - (void)asyncConnectToHost: (OFString *)host port: (uint16_t)port runLoopMode: (of_run_loop_mode_t)runLoopMode block: (of_tcp_socket_async_connect_block_t)block { void *pool = objc_autoreleasePoolPush(); [[[[OFTCPSocketAsyncConnectDelegate alloc] initWithSocket: self host: host port: port SOCKS5Host: _SOCKS5Host SOCKS5Port: _SOCKS5Port block: block] autorelease] startWithRunLoopMode: runLoopMode]; |
︙ | ︙ |
Modified src/OFTarArchive.m from [b446679d60] to [bd5d8687ca].
︙ | ︙ | |||
30 31 32 33 34 35 36 | #import "OFInvalidArgumentException.h" #import "OFInvalidFormatException.h" #import "OFNotOpenException.h" #import "OFOutOfRangeException.h" #import "OFTruncatedDataException.h" #import "OFWriteFailedException.h" | | | | 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 | #import "OFInvalidArgumentException.h" #import "OFInvalidFormatException.h" #import "OFNotOpenException.h" #import "OFOutOfRangeException.h" #import "OFTruncatedDataException.h" #import "OFWriteFailedException.h" @interface OFTarArchiveFileReadStream: OFStream <OFReadyForReadingObserving> { OFTarArchiveEntry *_entry; OFStream *_stream; uint64_t _toRead; bool _atEndOfStream, _skipped; } - (instancetype)of_initWithStream: (OFStream *)stream entry: (OFTarArchiveEntry *)entry; - (void)of_skip; @end @interface OFTarArchiveFileWriteStream: OFStream <OFReadyForWritingObserving> { OFTarArchiveEntry *_entry; OFStream *_stream; uint64_t _toWrite; } - (instancetype)of_initWithStream: (OFStream *)stream |
︙ | ︙ | |||
173 174 175 176 177 178 179 | uint32_t u32[512 / sizeof(uint32_t)]; } buffer; bool empty = true; if (_mode != OF_TAR_ARCHIVE_MODE_READ) @throw [OFInvalidArgumentException exception]; | | | 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 | uint32_t u32[512 / sizeof(uint32_t)]; } buffer; bool empty = true; if (_mode != OF_TAR_ARCHIVE_MODE_READ) @throw [OFInvalidArgumentException exception]; [(OFTarArchiveFileReadStream *)_lastReturnedStream of_skip]; [_lastReturnedStream close]; [_lastReturnedStream release]; _lastReturnedStream = nil; if (_stream.atEndOfStream) return nil; |
︙ | ︙ | |||
203 204 205 206 207 208 209 | return nil; } entry = [[[OFTarArchiveEntry alloc] of_initWithHeader: buffer.c encoding: _encoding] autorelease]; | | | | 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 | return nil; } entry = [[[OFTarArchiveEntry alloc] of_initWithHeader: buffer.c encoding: _encoding] autorelease]; _lastReturnedStream = [[OFTarArchiveFileReadStream alloc] of_initWithStream: _stream entry: entry]; return entry; } - (OFStream <OFReadyForReadingObserving> *)streamForReadingCurrentEntry { if (_mode != OF_TAR_ARCHIVE_MODE_READ) @throw [OFInvalidArgumentException exception]; if (_lastReturnedStream == nil) @throw [OFInvalidArgumentException exception]; return [[(OFTarArchiveFileReadStream *)_lastReturnedStream retain] autorelease]; } - (OFStream <OFReadyForWritingObserving> *) streamForWritingEntry: (OFTarArchiveEntry *)entry { void *pool; |
︙ | ︙ | |||
240 241 242 243 244 245 246 | [_lastReturnedStream close]; [_lastReturnedStream release]; _lastReturnedStream = nil; [entry of_writeToStream: _stream encoding: _encoding]; | | | | 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 | [_lastReturnedStream close]; [_lastReturnedStream release]; _lastReturnedStream = nil; [entry of_writeToStream: _stream encoding: _encoding]; _lastReturnedStream = [[OFTarArchiveFileWriteStream alloc] of_initWithStream: _stream entry: entry]; objc_autoreleasePoolPop(pool); return [[(OFTarArchiveFileWriteStream *)_lastReturnedStream retain] autorelease]; } - (void)close { if (_stream == nil) return; |
︙ | ︙ | |||
272 273 274 275 276 277 278 | } [_stream release]; _stream = nil; } @end | | | 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 | } [_stream release]; _stream = nil; } @end @implementation OFTarArchiveFileReadStream - (instancetype)of_initWithStream: (OFStream *)stream entry: (OFTarArchiveEntry *)entry { self = [super init]; @try { _entry = [entry copy]; |
︙ | ︙ | |||
405 406 407 408 409 410 411 | exactLength: (size_t)(512 - (size % 512))]; } _skipped = true; } @end | | | 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 | exactLength: (size_t)(512 - (size % 512))]; } _skipped = true; } @end @implementation OFTarArchiveFileWriteStream - (instancetype)of_initWithStream: (OFStream *)stream entry: (OFTarArchiveEntry *)entry { self = [super init]; @try { _entry = [entry copy]; |
︙ | ︙ |
Modified src/OFURL.m from [7aef38f501] to [a31da3127a].
︙ | ︙ | |||
24 25 26 27 28 29 30 | #import "OFArray.h" #import "OFNumber.h" #import "OFString.h" #import "OFXMLElement.h" #ifdef OF_HAVE_FILES # import "OFFileManager.h" | | | | | | | < | 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 | #import "OFArray.h" #import "OFNumber.h" #import "OFString.h" #import "OFXMLElement.h" #ifdef OF_HAVE_FILES # import "OFFileManager.h" # import "OFFileURLHandler.h" #endif #import "OFInvalidArgumentException.h" #import "OFInvalidFormatException.h" #import "OFOutOfMemoryException.h" static OFCharacterSet *URLAllowedCharacterSet = nil; static OFCharacterSet *URLSchemeAllowedCharacterSet = nil; static OFCharacterSet *URLPathAllowedCharacterSet = nil; static OFCharacterSet *URLQueryOrFragmentAllowedCharacterSet = nil; @interface OFURLAllowedCharacterSetBase: OFCharacterSet - (instancetype)of_init OF_METHOD_FAMILY(init); @end @interface OFURLAllowedCharacterSet: OFURLAllowedCharacterSetBase + (OFCharacterSet *)URLAllowedCharacterSet; @end @interface OFURLSchemeAllowedCharacterSet: OFURLAllowedCharacterSetBase + (OFCharacterSet *)URLSchemeAllowedCharacterSet; @end @interface OFURLPathAllowedCharacterSet: OFURLAllowedCharacterSetBase + (OFCharacterSet *)URLPathAllowedCharacterSet; @end @interface OFURLQueryOrFragmentAllowedCharacterSet: OFURLAllowedCharacterSetBase + (OFCharacterSet *)URLQueryOrFragmentAllowedCharacterSet; @end #ifdef OF_HAVE_FILES static OFString * pathToURLPath(OFString *path) { |
︙ | ︙ | |||
136 137 138 139 140 141 142 | return [path substringWithRange: of_range(1, path.length - 1)]; # else return path; # endif } #endif | | | | 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 | return [path substringWithRange: of_range(1, path.length - 1)]; # else return path; # endif } #endif @interface OFInvertedCharacterSetWithoutPercent: OFCharacterSet { OFCharacterSet *_characterSet; bool (*_characterIsMember)(id, SEL, of_unichar_t); } - (instancetype)of_initWithCharacterSet: (OFCharacterSet *)characterSet OF_METHOD_FAMILY(init); @end @implementation OFURLAllowedCharacterSetBase - (instancetype)init { OF_INVALID_INIT_METHOD } - (instancetype)of_init { |
︙ | ︙ | |||
177 178 179 180 181 182 183 | - (unsigned int)retainCount { return OF_RETAIN_COUNT_MAX; } @end | | | | | 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 | - (unsigned int)retainCount { return OF_RETAIN_COUNT_MAX; } @end @implementation OFURLAllowedCharacterSet + (void)initialize { if (self != [OFURLAllowedCharacterSet class]) return; URLAllowedCharacterSet = [[OFURLAllowedCharacterSet alloc] of_init]; } + (OFCharacterSet *)URLAllowedCharacterSet { return URLAllowedCharacterSet; } |
︙ | ︙ | |||
219 220 221 222 223 224 225 | return true; default: return false; } } @end | | | | | 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 | return true; default: return false; } } @end @implementation OFURLSchemeAllowedCharacterSet + (void)initialize { if (self != [OFURLSchemeAllowedCharacterSet class]) return; URLSchemeAllowedCharacterSet = [[OFURLSchemeAllowedCharacterSet alloc] of_init]; } + (OFCharacterSet *)URLSchemeAllowedCharacterSet { return URLSchemeAllowedCharacterSet; } |
︙ | ︙ | |||
250 251 252 253 254 255 256 | return true; default: return false; } } @end | | | | | 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 | return true; default: return false; } } @end @implementation OFURLPathAllowedCharacterSet + (void)initialize { if (self != [OFURLPathAllowedCharacterSet class]) return; URLPathAllowedCharacterSet = [[OFURLPathAllowedCharacterSet alloc] of_init]; } + (OFCharacterSet *)URLPathAllowedCharacterSet { return URLPathAllowedCharacterSet; } |
︙ | ︙ | |||
296 297 298 299 300 301 302 | return true; default: return false; } } @end | | | | | 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 | return true; default: return false; } } @end @implementation OFURLQueryOrFragmentAllowedCharacterSet + (void)initialize { if (self != [OFURLQueryOrFragmentAllowedCharacterSet class]) return; URLQueryOrFragmentAllowedCharacterSet = [[OFURLQueryOrFragmentAllowedCharacterSet alloc] of_init]; } + (OFCharacterSet *)URLQueryOrFragmentAllowedCharacterSet { return URLQueryOrFragmentAllowedCharacterSet; } |
︙ | ︙ | |||
343 344 345 346 347 348 349 | return true; default: return false; } } @end | | | 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 | return true; default: return false; } } @end @implementation OFInvertedCharacterSetWithoutPercent - (instancetype)init { OF_INVALID_INIT_METHOD } - (instancetype)of_initWithCharacterSet: (OFCharacterSet *)characterSet { |
︙ | ︙ | |||
379 380 381 382 383 384 385 | @end void of_url_verify_escaped(OFString *string, OFCharacterSet *characterSet) { void *pool = objc_autoreleasePoolPush(); | | | | | | | | | | 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 | @end void of_url_verify_escaped(OFString *string, OFCharacterSet *characterSet) { void *pool = objc_autoreleasePoolPush(); characterSet = [[[OFInvertedCharacterSetWithoutPercent alloc] of_initWithCharacterSet: characterSet] autorelease]; if ([string indexOfCharacterFromSet: characterSet] != OF_NOT_FOUND) @throw [OFInvalidFormatException exception]; objc_autoreleasePoolPop(pool); } @implementation OFCharacterSet (URLCharacterSets) + (OFCharacterSet *)URLSchemeAllowedCharacterSet { return [OFURLSchemeAllowedCharacterSet URLSchemeAllowedCharacterSet]; } + (OFCharacterSet *)URLHostAllowedCharacterSet { return [OFURLAllowedCharacterSet URLAllowedCharacterSet]; } + (OFCharacterSet *)URLUserAllowedCharacterSet { return [OFURLAllowedCharacterSet URLAllowedCharacterSet]; } + (OFCharacterSet *)URLPasswordAllowedCharacterSet { return [OFURLAllowedCharacterSet URLAllowedCharacterSet]; } + (OFCharacterSet *)URLPathAllowedCharacterSet { return [OFURLPathAllowedCharacterSet URLPathAllowedCharacterSet]; } + (OFCharacterSet *)URLQueryAllowedCharacterSet { return [OFURLQueryOrFragmentAllowedCharacterSet URLQueryOrFragmentAllowedCharacterSet]; } + (OFCharacterSet *)URLFragmentAllowedCharacterSet { return [OFURLQueryOrFragmentAllowedCharacterSet URLQueryOrFragmentAllowedCharacterSet]; } @end @implementation OFURL + (instancetype)URL { |
︙ | ︙ | |||
700 701 702 703 704 705 706 | @try { void *pool = objc_autoreleasePoolPush(); #if defined(OF_WINDOWS) || defined(OF_MSDOS) isDirectory = ([path hasSuffix: @"\\"] || [path hasSuffix: @"/"] || | | | | | 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 | @try { void *pool = objc_autoreleasePoolPush(); #if defined(OF_WINDOWS) || defined(OF_MSDOS) isDirectory = ([path hasSuffix: @"\\"] || [path hasSuffix: @"/"] || [OFFileURLHandler of_directoryExistsAtPath: path]); #elif defined(OF_AMIGAOS) isDirectory = ([path hasSuffix: @"/"] || [path hasSuffix: @":"] || [OFFileURLHandler of_directoryExistsAtPath: path]); #else isDirectory = ([path hasSuffix: @"/"] || [OFFileURLHandler of_directoryExistsAtPath: path]); #endif objc_autoreleasePoolPop(pool); } @catch (id e) { [self release]; @throw e; } |
︙ | ︙ |
Modified src/OFURLHandler.m from [c82ad13c9f] to [b2b4473deb].
︙ | ︙ | |||
23 24 25 26 27 28 29 | #import "OFURL.h" #ifdef OF_HAVE_THREADS # import "OFMutex.h" #endif #ifdef OF_HAVE_FILES | | | | 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | #import "OFURL.h" #ifdef OF_HAVE_THREADS # import "OFMutex.h" #endif #ifdef OF_HAVE_FILES # import "OFFileURLHandler.h" #endif #if defined(OF_HAVE_SOCKETS) && defined(OF_HAVE_THREADS) # import "OFHTTPURLHandler.h" #endif static OFMutableDictionary OF_GENERIC(OFString *, OFURLHandler *) *handlers; #ifdef OF_HAVE_THREADS static OFMutex *mutex; #endif |
︙ | ︙ | |||
48 49 50 51 52 53 54 | handlers = [[OFMutableDictionary alloc] init]; #ifdef OF_HAVE_THREADS mutex = [[OFMutex alloc] init]; #endif #ifdef OF_HAVE_FILES | | | | | 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 | handlers = [[OFMutableDictionary alloc] init]; #ifdef OF_HAVE_THREADS mutex = [[OFMutex alloc] init]; #endif #ifdef OF_HAVE_FILES [self registerClass: [OFFileURLHandler class] forScheme: @"file"]; #endif #if defined(OF_HAVE_SOCKETS) && defined(OF_HAVE_THREADS) [self registerClass: [OFHTTPURLHandler class] forScheme: @"http"]; [self registerClass: [OFHTTPURLHandler class] forScheme: @"https"]; #endif } + (bool)registerClass: (Class)class forScheme: (OFString *)scheme { |
︙ | ︙ |
Deleted src/OFURLHandler_HTTP.h version [c5c03d3a28].
|
| < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted src/OFURLHandler_HTTP.m version [0eae88285c].
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted src/OFURLHandler_file.h version [b22221e576].
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted src/OFURLHandler_file.m version [c1234df85c].
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Added src/OFUTF8String+Private.h version [c83c9de901].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | /* * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, * 2018, 2019 * Jonathan Schleifer <js@heap.zone> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #import "OFUTF8String.h" OF_ASSUME_NONNULL_BEGIN @interface OFUTF8String () - (instancetype)of_initWithUTF8String: (const char *)UTF8String length: (size_t)UTF8StringLength storage: (char *)storage OF_METHOD_FAMILY(init); @end OF_ASSUME_NONNULL_END |
Added src/OFUTF8String.h version [27bd544b4e].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 | /* * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, * 2018, 2019 * Jonathan Schleifer <js@heap.zone> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #import "OFString.h" OF_ASSUME_NONNULL_BEGIN @interface OFUTF8String: OFString { @public /* * A pointer to the actual data. * * Since constant strings don't have `_storage`, they have to allocate * it on the first access. Strings created at runtime just set the * pointer to `&_storage`. */ struct of_string_utf8_ivars { char *cString; size_t cStringLength; bool isUTF8; size_t length; bool hashed; uint32_t hash; char *_Nullable freeWhenDone; } *restrict _s; struct of_string_utf8_ivars _storage; } @end #ifdef __cplusplus extern "C" { #endif extern int of_string_utf8_check(const char *, size_t, size_t *); extern size_t of_string_utf8_get_index(const char *, size_t); extern size_t of_string_utf8_get_position(const char *, size_t, size_t); #ifdef __cplusplus } #endif OF_ASSUME_NONNULL_END |
Added src/OFUTF8String.m version [d63b819646].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 | /* * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, * 2018, 2019 * Jonathan Schleifer <js@heap.zone> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #include <stdarg.h> #include <stdlib.h> #include <string.h> #ifdef OF_HAVE_SYS_TYPES_H # include <sys/types.h> #endif #import "OFUTF8String.h" #import "OFUTF8String+Private.h" #import "OFArray.h" #import "OFMutableUTF8String.h" #import "OFInitializationFailedException.h" #import "OFInvalidArgumentException.h" #import "OFInvalidEncodingException.h" #import "OFInvalidFormatException.h" #import "OFOutOfMemoryException.h" #import "OFOutOfRangeException.h" #import "of_asprintf.h" #import "unicode.h" extern const of_char16_t of_iso_8859_2_table[]; extern const size_t of_iso_8859_2_table_offset; extern const of_char16_t of_iso_8859_3_table[]; extern const size_t of_iso_8859_3_table_offset; extern const of_char16_t of_iso_8859_15_table[]; extern const size_t of_iso_8859_15_table_offset; extern const of_char16_t of_windows_1251_table[]; extern const size_t of_windows_1251_table_offset; extern const of_char16_t of_windows_1252_table[]; extern const size_t of_windows_1252_table_offset; extern const of_char16_t of_codepage_437_table[]; extern const size_t of_codepage_437_table_offset; extern const of_char16_t of_codepage_850_table[]; extern const size_t of_codepage_850_table_offset; extern const of_char16_t of_codepage_858_table[]; extern const size_t of_codepage_858_table_offset; extern const of_char16_t of_mac_roman_table[]; extern const size_t of_mac_roman_table_offset; extern const of_char16_t of_koi8_r_table[]; extern const size_t of_koi8_r_table_offset; extern const of_char16_t of_koi8_u_table[]; extern const size_t of_koi8_u_table_offset; static inline int memcasecmp(const char *first, const char *second, size_t length) { for (size_t i = 0; i < length; i++) { unsigned char f = first[i]; unsigned char s = second[i]; f = of_ascii_toupper(f); s = of_ascii_toupper(s); if (f > s) return OF_ORDERED_DESCENDING; if (f < s) return OF_ORDERED_ASCENDING; } return OF_ORDERED_SAME; } int of_string_utf8_check(const char *UTF8String, size_t UTF8Length, size_t *length) { size_t tmpLength = UTF8Length; int isUTF8 = 0; for (size_t i = 0; i < UTF8Length; i++) { /* No sign of UTF-8 here */ if OF_LIKELY (!(UTF8String[i] & 0x80)) continue; isUTF8 = 1; /* We're missing a start byte here */ if OF_UNLIKELY (!(UTF8String[i] & 0x40)) return -1; /* 2 byte sequences for code points 0 - 127 are forbidden */ if OF_UNLIKELY ((UTF8String[i] & 0x7E) == 0x40) return -1; /* We have at minimum a 2 byte character -> check next byte */ if OF_UNLIKELY (UTF8Length <= i + 1 || (UTF8String[i + 1] & 0xC0) != 0x80) return -1; /* Check if we have at minimum a 3 byte character */ if OF_LIKELY (!(UTF8String[i] & 0x20)) { i++; tmpLength--; continue; } /* We have at minimum a 3 byte char -> check second next byte */ if OF_UNLIKELY (UTF8Length <= i + 2 || (UTF8String[i + 2] & 0xC0) != 0x80) return -1; /* Check if we have a 4 byte character */ if OF_LIKELY (!(UTF8String[i] & 0x10)) { i += 2; tmpLength -= 2; continue; } /* We have a 4 byte character -> check third next byte */ if OF_UNLIKELY (UTF8Length <= i + 3 || (UTF8String[i + 3] & 0xC0) != 0x80) return -1; /* * Just in case, check if there's a 5th character, which is * forbidden by UTF-8 */ if OF_UNLIKELY (UTF8String[i] & 0x08) return -1; i += 3; tmpLength -= 3; } if (length != NULL) *length = tmpLength; return isUTF8; } size_t of_string_utf8_get_index(const char *string, size_t position) { size_t idx = position; for (size_t i = 0; i < position; i++) if OF_UNLIKELY ((string[i] & 0xC0) == 0x80) idx--; return idx; } size_t of_string_utf8_get_position(const char *string, size_t idx, size_t length) { for (size_t i = 0; i <= idx; i++) if OF_UNLIKELY ((string[i] & 0xC0) == 0x80) if (++idx > length) @throw [OFInvalidFormatException exception]; return idx; } @implementation OFUTF8String - (instancetype)init { self = [super init]; @try { _s = &_storage; _s->cString = [self allocMemoryWithSize: 1]; _s->cString[0] = '\0'; } @catch (id e) { [self release]; @throw e; } return self; } - (instancetype)of_initWithUTF8String: (const char *)UTF8String length: (size_t)UTF8StringLength storage: (char *)storage { self = [super init]; @try { if (UTF8StringLength >= 3 && memcmp(UTF8String, "\xEF\xBB\xBF", 3) == 0) { UTF8String += 3; UTF8StringLength -= 3; } _s = &_storage; _s->cString = storage; _s->cStringLength = UTF8StringLength; switch (of_string_utf8_check(UTF8String, UTF8StringLength, &_s->length)) { case 1: _s->isUTF8 = true; break; case -1: @throw [OFInvalidEncodingException exception]; } memcpy(_s->cString, UTF8String, UTF8StringLength); _s->cString[UTF8StringLength] = 0; } @catch (id e) { [self release]; @throw e; } return self; } - (instancetype)initWithCString: (const char *)cString encoding: (of_string_encoding_t)encoding length: (size_t)cStringLength { self = [super init]; @try { const of_char16_t *table; size_t tableOffset, j; if (encoding == OF_STRING_ENCODING_UTF_8 && cStringLength >= 3 && memcmp(cString, "\xEF\xBB\xBF", 3) == 0) { cString += 3; cStringLength -= 3; } _s = &_storage; _s->cString = [self allocMemoryWithSize: cStringLength + 1]; _s->cStringLength = cStringLength; if (encoding == OF_STRING_ENCODING_UTF_8 || encoding == OF_STRING_ENCODING_ASCII) { switch (of_string_utf8_check(cString, cStringLength, &_s->length)) { case 1: if (encoding == OF_STRING_ENCODING_ASCII) @throw [OFInvalidEncodingException exception]; _s->isUTF8 = true; break; case -1: @throw [OFInvalidEncodingException exception]; } memcpy(_s->cString, cString, cStringLength); _s->cString[cStringLength] = 0; return self; } /* All other encodings we support are single byte encodings */ _s->length = cStringLength; if (encoding == OF_STRING_ENCODING_ISO_8859_1) { j = 0; for (size_t i = 0; i < cStringLength; i++) { char buffer[4]; size_t bytes; if (!(cString[i] & 0x80)) { _s->cString[j++] = cString[i]; continue; } _s->isUTF8 = true; bytes = of_string_utf8_encode( (uint8_t)cString[i], buffer); if (bytes == 0) @throw [OFInvalidEncodingException exception]; _s->cStringLength += bytes - 1; _s->cString = [self resizeMemory: _s->cString size: _s->cStringLength + 1]; memcpy(_s->cString + j, buffer, bytes); j += bytes; } _s->cString[_s->cStringLength] = 0; return self; } switch (encoding) { #define CASE(encoding, var) \ case encoding: \ table = var; \ tableOffset = var##_offset; \ break; #ifdef HAVE_ISO_8859_2 CASE(OF_STRING_ENCODING_ISO_8859_2, of_iso_8859_2_table) #endif #ifdef HAVE_ISO_8859_3 CASE(OF_STRING_ENCODING_ISO_8859_3, of_iso_8859_3_table) #endif #ifdef HAVE_ISO_8859_15 CASE(OF_STRING_ENCODING_ISO_8859_15, of_iso_8859_15_table) #endif #ifdef HAVE_WINDOWS_1251 CASE(OF_STRING_ENCODING_WINDOWS_1251, of_windows_1251_table) #endif #ifdef HAVE_WINDOWS_1252 CASE(OF_STRING_ENCODING_WINDOWS_1252, of_windows_1252_table) #endif #ifdef HAVE_CODEPAGE_437 CASE(OF_STRING_ENCODING_CODEPAGE_437, of_codepage_437_table) #endif #ifdef HAVE_CODEPAGE_850 CASE(OF_STRING_ENCODING_CODEPAGE_850, of_codepage_850_table) #endif #ifdef HAVE_CODEPAGE_858 CASE(OF_STRING_ENCODING_CODEPAGE_858, of_codepage_858_table) #endif #ifdef HAVE_MAC_ROMAN CASE(OF_STRING_ENCODING_MAC_ROMAN, of_mac_roman_table) #endif #ifdef HAVE_KOI8_R CASE(OF_STRING_ENCODING_KOI8_R, of_koi8_r_table) #endif #ifdef HAVE_KOI8_U CASE(OF_STRING_ENCODING_KOI8_U, of_koi8_u_table) #endif #undef CASE default: @throw [OFInvalidEncodingException exception]; } j = 0; for (size_t i = 0; i < cStringLength; i++) { unsigned char character = (unsigned char)cString[i]; of_unichar_t unichar; char buffer[4]; size_t byteLength; if (character < tableOffset) { _s->cString[j++] = cString[i]; continue; } unichar = table[character - tableOffset]; if (unichar == 0xFFFF) @throw [OFInvalidEncodingException exception]; _s->isUTF8 = true; byteLength = of_string_utf8_encode(unichar, buffer); if (byteLength == 0) @throw [OFInvalidEncodingException exception]; _s->cStringLength += byteLength - 1; _s->cString = [self resizeMemory: _s->cString size: _s->cStringLength + 1]; memcpy(_s->cString + j, buffer, byteLength); j += byteLength; } _s->cString[_s->cStringLength] = 0; } @catch (id e) { [self release]; @throw e; } return self; } - (instancetype)initWithUTF8StringNoCopy: (char *)UTF8String freeWhenDone: (bool)freeWhenDone { return [self initWithUTF8StringNoCopy: UTF8String length: strlen(UTF8String) freeWhenDone: freeWhenDone]; } - (instancetype)initWithUTF8StringNoCopy: (char *)UTF8String length: (size_t)UTF8StringLength freeWhenDone: (bool)freeWhenDone { @try { self = [super init]; } @catch (id e) { if (freeWhenDone) free(UTF8String); @throw e; } @try { _s = &_storage; if (freeWhenDone) _s->freeWhenDone = UTF8String; if (UTF8StringLength >= 3 && memcmp(UTF8String, "\xEF\xBB\xBF", 3) == 0) { UTF8String += 3; UTF8StringLength -= 3; } _s->cString = (char *)UTF8String; _s->cStringLength = UTF8StringLength; switch (of_string_utf8_check(UTF8String, UTF8StringLength, &_s->length)) { case 1: _s->isUTF8 = true; break; case -1: @throw [OFInvalidEncodingException exception]; } } @catch (id e) { [self release]; @throw e; } return self; } - (instancetype)initWithString: (OFString *)string { self = [super init]; @try { _s = &_storage; _s->cStringLength = string.UTF8StringLength; if ([string isKindOfClass: [OFUTF8String class]] || [string isKindOfClass: [OFMutableUTF8String class]]) _s->isUTF8 = ((OFUTF8String *)string)->_s->isUTF8; else _s->isUTF8 = true; _s->length = string.length; _s->cString = [self allocMemoryWithSize: _s->cStringLength + 1]; memcpy(_s->cString, string.UTF8String, _s->cStringLength + 1); } @catch (id e) { [self release]; @throw e; } return self; } - (instancetype)initWithCharacters: (const of_unichar_t *)characters length: (size_t)length { self = [super init]; @try { size_t j; _s = &_storage; _s->cString = [self allocMemoryWithSize: (length * 4) + 1]; _s->length = length; j = 0; for (size_t i = 0; i < length; i++) { size_t len = of_string_utf8_encode(characters[i], _s->cString + j); if (len == 0) @throw [OFInvalidEncodingException exception]; if (len > 1) _s->isUTF8 = true; j += len; } _s->cString[j] = '\0'; _s->cStringLength = j; @try { _s->cString = [self resizeMemory: _s->cString size: j + 1]; } @catch (OFOutOfMemoryException *e) { /* We don't care, as we only tried to make it smaller */ } } @catch (id e) { [self release]; @throw e; } return self; } - (instancetype)initWithUTF16String: (const of_char16_t *)string length: (size_t)length byteOrder: (of_byte_order_t)byteOrder { self = [super init]; @try { size_t j; bool swap = false; if (length > 0 && *string == 0xFEFF) { string++; length--; } else if (length > 0 && *string == 0xFFFE) { swap = true; string++; length--; } else if (byteOrder != OF_BYTE_ORDER_NATIVE) swap = true; _s = &_storage; _s->cString = [self allocMemoryWithSize: (length * 4) + 1]; _s->length = length; j = 0; for (size_t i = 0; i < length; i++) { of_unichar_t character = (swap ? OF_BSWAP16(string[i]) : string[i]); size_t len; /* Missing high surrogate */ if ((character & 0xFC00) == 0xDC00) @throw [OFInvalidEncodingException exception]; if ((character & 0xFC00) == 0xD800) { of_char16_t nextCharacter; if (length <= i + 1) @throw [OFInvalidEncodingException exception]; nextCharacter = (swap ? OF_BSWAP16(string[i + 1]) : string[i + 1]); if ((nextCharacter & 0xFC00) != 0xDC00) @throw [OFInvalidEncodingException exception]; character = (((character & 0x3FF) << 10) | (nextCharacter & 0x3FF)) + 0x10000; i++; _s->length--; } len = of_string_utf8_encode(character, _s->cString + j); if (len == 0) @throw [OFInvalidEncodingException exception]; if (len > 1) _s->isUTF8 = true; j += len; } _s->cString[j] = '\0'; _s->cStringLength = j; @try { _s->cString = [self resizeMemory: _s->cString size: j + 1]; } @catch (OFOutOfMemoryException *e) { /* We don't care, as we only tried to make it smaller */ } } @catch (id e) { [self release]; @throw e; } return self; } - (instancetype)initWithUTF32String: (const of_char32_t *)characters length: (size_t)length byteOrder: (of_byte_order_t)byteOrder { self = [super init]; @try { size_t j; bool swap = false; if (length > 0 && *characters == 0xFEFF) { characters++; length--; } else if (length > 0 && *characters == 0xFFFE0000) { swap = true; characters++; length--; } else if (byteOrder != OF_BYTE_ORDER_NATIVE) swap = true; _s = &_storage; _s->cString = [self allocMemoryWithSize: (length * 4) + 1]; _s->length = length; j = 0; for (size_t i = 0; i < length; i++) { char buffer[4]; size_t len = of_string_utf8_encode( (swap ? OF_BSWAP32(characters[i]) : characters[i]), buffer); switch (len) { case 1: _s->cString[j++] = buffer[0]; break; case 2: case 3: case 4: _s->isUTF8 = true; memcpy(_s->cString + j, buffer, len); j += len; break; default: @throw [OFInvalidEncodingException exception]; } } _s->cString[j] = '\0'; _s->cStringLength = j; @try { _s->cString = [self resizeMemory: _s->cString size: j + 1]; } @catch (OFOutOfMemoryException *e) { /* We don't care, as we only tried to make it smaller */ } } @catch (id e) { [self release]; @throw e; } return self; } - (instancetype)initWithFormat: (OFConstantString *)format arguments: (va_list)arguments { self = [super init]; @try { char *tmp; int cStringLength; if (format == nil) @throw [OFInvalidArgumentException exception]; _s = &_storage; if ((cStringLength = of_vasprintf(&tmp, format.UTF8String, arguments)) == -1) @throw [OFInvalidFormatException exception]; _s->cStringLength = cStringLength; @try { switch (of_string_utf8_check(tmp, cStringLength, &_s->length)) { case 1: _s->isUTF8 = true; break; case -1: @throw [OFInvalidEncodingException exception]; } _s->cString = [self allocMemoryWithSize: cStringLength + 1]; memcpy(_s->cString, tmp, cStringLength + 1); } @finally { free(tmp); } } @catch (id e) { [self release]; @throw e; } return self; } - (void)dealloc { if (_s != NULL && _s->freeWhenDone != NULL) free(_s->freeWhenDone); [super dealloc]; } - (size_t)getCString: (char *)cString maxLength: (size_t)maxLength encoding: (of_string_encoding_t)encoding { switch (encoding) { case OF_STRING_ENCODING_ASCII: if (_s->isUTF8) @throw [OFInvalidEncodingException exception]; /* intentional fall-through */ case OF_STRING_ENCODING_UTF_8: if (_s->cStringLength + 1 > maxLength) @throw [OFOutOfRangeException exception]; memcpy(cString, _s->cString, _s->cStringLength + 1); return _s->cStringLength; default: return [super getCString: cString maxLength: maxLength encoding: encoding]; } } - (const char *)cStringWithEncoding: (of_string_encoding_t)encoding { switch (encoding) { case OF_STRING_ENCODING_ASCII: if (_s->isUTF8) @throw [OFInvalidEncodingException exception]; /* intentional fall-through */ case OF_STRING_ENCODING_UTF_8: return _s->cString; default: return [super cStringWithEncoding: encoding]; } } - (const char *)UTF8String { return _s->cString; } - (size_t)length { return _s->length; } - (size_t)cStringLengthWithEncoding: (of_string_encoding_t)encoding { switch (encoding) { case OF_STRING_ENCODING_UTF_8: case OF_STRING_ENCODING_ASCII: return _s->cStringLength; default: return [super cStringLengthWithEncoding: encoding]; } } - (size_t)UTF8StringLength { return _s->cStringLength; } - (bool)isEqual: (id)object { OFUTF8String *otherString; if (object == self) return true; if (![object isKindOfClass: [OFString class]]) return false; otherString = object; if (otherString.UTF8StringLength != _s->cStringLength || otherString.length != _s->length) return false; if (([otherString isKindOfClass: [OFUTF8String class]] || [otherString isKindOfClass: [OFMutableUTF8String class]]) && _s->hashed && otherString->_s->hashed && _s->hash != otherString->_s->hash) return false; if (strcmp(_s->cString, otherString.UTF8String) != 0) return false; return true; } - (of_comparison_result_t)compare: (id <OFComparing>)object { OFString *otherString; size_t otherCStringLength, minimumCStringLength; int compare; if (object == self) return OF_ORDERED_SAME; if (![(id)object isKindOfClass: [OFString class]]) @throw [OFInvalidArgumentException exception]; otherString = (OFString *)object; otherCStringLength = otherString.UTF8StringLength; minimumCStringLength = (_s->cStringLength > otherCStringLength ? otherCStringLength : _s->cStringLength); if ((compare = memcmp(_s->cString, otherString.UTF8String, minimumCStringLength)) == 0) { if (_s->cStringLength > otherCStringLength) return OF_ORDERED_DESCENDING; if (_s->cStringLength < otherCStringLength) return OF_ORDERED_ASCENDING; return OF_ORDERED_SAME; } if (compare > 0) return OF_ORDERED_DESCENDING; else return OF_ORDERED_ASCENDING; } - (of_comparison_result_t)caseInsensitiveCompare: (OFString *)otherString { const char *otherCString; size_t otherCStringLength, minimumCStringLength; #ifdef OF_HAVE_UNICODE_TABLES size_t i, j; #endif int compare; if (otherString == self) return OF_ORDERED_SAME; if (![otherString isKindOfClass: [OFString class]]) @throw [OFInvalidArgumentException exception]; otherCString = otherString.UTF8String; otherCStringLength = otherString.UTF8StringLength; #ifdef OF_HAVE_UNICODE_TABLES if (!_s->isUTF8) { #endif minimumCStringLength = (_s->cStringLength > otherCStringLength ? otherCStringLength : _s->cStringLength); if ((compare = memcasecmp(_s->cString, otherCString, minimumCStringLength)) == 0) { if (_s->cStringLength > otherCStringLength) return OF_ORDERED_DESCENDING; if (_s->cStringLength < otherCStringLength) return OF_ORDERED_ASCENDING; return OF_ORDERED_SAME; } if (compare > 0) return OF_ORDERED_DESCENDING; else return OF_ORDERED_ASCENDING; #ifdef OF_HAVE_UNICODE_TABLES } i = j = 0; while (i < _s->cStringLength && j < otherCStringLength) { of_unichar_t c1, c2; ssize_t l1, l2; l1 = of_string_utf8_decode(_s->cString + i, _s->cStringLength - i, &c1); l2 = of_string_utf8_decode(otherCString + j, otherCStringLength - j, &c2); if (l1 <= 0 || l2 <= 0 || c1 > 0x10FFFF || c2 > 0x10FFFF) @throw [OFInvalidEncodingException exception]; if (c1 >> 8 < OF_UNICODE_CASEFOLDING_TABLE_SIZE) { of_unichar_t tc = of_unicode_casefolding_table[c1 >> 8][c1 & 0xFF]; if (tc) c1 = tc; } if (c2 >> 8 < OF_UNICODE_CASEFOLDING_TABLE_SIZE) { of_unichar_t tc = of_unicode_casefolding_table[c2 >> 8][c2 & 0xFF]; if (tc) c2 = tc; } if (c1 > c2) return OF_ORDERED_DESCENDING; if (c1 < c2) return OF_ORDERED_ASCENDING; i += l1; j += l2; } if (_s->cStringLength - i > otherCStringLength - j) return OF_ORDERED_DESCENDING; else if (_s->cStringLength - i < otherCStringLength - j) return OF_ORDERED_ASCENDING; #endif return OF_ORDERED_SAME; } - (uint32_t)hash { uint32_t hash; if (_s->hashed) return _s->hash; OF_HASH_INIT(hash); for (size_t i = 0; i < _s->cStringLength; i++) { of_unichar_t c; ssize_t length; if ((length = of_string_utf8_decode(_s->cString + i, _s->cStringLength - i, &c)) <= 0) @throw [OFInvalidEncodingException exception]; OF_HASH_ADD(hash, (c & 0xFF0000) >> 16); OF_HASH_ADD(hash, (c & 0x00FF00) >> 8); OF_HASH_ADD(hash, c & 0x0000FF); i += length - 1; } OF_HASH_FINALIZE(hash); _s->hash = hash; _s->hashed = true; return hash; } - (of_unichar_t)characterAtIndex: (size_t)idx { of_unichar_t character; if (idx >= _s->length) @throw [OFOutOfRangeException exception]; if (!_s->isUTF8) return _s->cString[idx]; idx = of_string_utf8_get_position(_s->cString, idx, _s->cStringLength); if (of_string_utf8_decode(_s->cString + idx, _s->cStringLength - idx, &character) <= 0) @throw [OFInvalidEncodingException exception]; return character; } - (void)getCharacters: (of_unichar_t *)buffer inRange: (of_range_t)range { /* TODO: Could be slightly optimized */ void *pool = objc_autoreleasePoolPush(); const of_unichar_t *characters = self.characters; if (range.length > SIZE_MAX - range.location || range.location + range.length > _s->length) @throw [OFOutOfRangeException exception]; memcpy(buffer, characters + range.location, range.length * sizeof(of_unichar_t)); objc_autoreleasePoolPop(pool); } - (of_range_t)rangeOfString: (OFString *)string options: (int)options range: (of_range_t)range { const char *cString = string.UTF8String; size_t cStringLength = string.UTF8StringLength; size_t rangeLocation, rangeLength; if (range.length > SIZE_MAX - range.location || range.location + range.length > _s->length) @throw [OFOutOfRangeException exception]; if (_s->isUTF8) { rangeLocation = of_string_utf8_get_position( _s->cString, range.location, _s->cStringLength); rangeLength = of_string_utf8_get_position( _s->cString + rangeLocation, range.length, _s->cStringLength - rangeLocation); } else { rangeLocation = range.location; rangeLength = range.length; } if (cStringLength == 0) return of_range(0, 0); if (cStringLength > rangeLength) return of_range(OF_NOT_FOUND, 0); if (options & OF_STRING_SEARCH_BACKWARDS) { for (size_t i = rangeLength - cStringLength;; i--) { if (memcmp(_s->cString + rangeLocation + i, cString, cStringLength) == 0) { range.location += of_string_utf8_get_index( _s->cString + rangeLocation, i); range.length = string.length; return range; } /* Did not match and we're at the last char */ if (i == 0) return of_range(OF_NOT_FOUND, 0); } } else { for (size_t i = 0; i <= rangeLength - cStringLength; i++) { if (memcmp(_s->cString + rangeLocation + i, cString, cStringLength) == 0) { range.location += of_string_utf8_get_index( _s->cString + rangeLocation, i); range.length = string.length; return range; } } } return of_range(OF_NOT_FOUND, 0); } - (bool)containsString: (OFString *)string { const char *cString = string.UTF8String; size_t cStringLength = string.UTF8StringLength; if (cStringLength == 0) return true; if (cStringLength > _s->cStringLength) return false; for (size_t i = 0; i <= _s->cStringLength - cStringLength; i++) if (memcmp(_s->cString + i, cString, cStringLength) == 0) return true; return false; } - (OFString *)substringWithRange: (of_range_t)range { size_t start = range.location; size_t end = range.location + range.length; if (range.length > SIZE_MAX - range.location || end > _s->length) @throw [OFOutOfRangeException exception]; if (_s->isUTF8) { start = of_string_utf8_get_position(_s->cString, start, _s->cStringLength); end = of_string_utf8_get_position(_s->cString, end, _s->cStringLength); } return [OFString stringWithUTF8String: _s->cString + start length: end - start]; } - (bool)hasPrefix: (OFString *)prefix { size_t cStringLength = prefix.UTF8StringLength; if (cStringLength > _s->cStringLength) return false; return (memcmp(_s->cString, prefix.UTF8String, cStringLength) == 0); } - (bool)hasSuffix: (OFString *)suffix { size_t cStringLength = suffix.UTF8StringLength; if (cStringLength > _s->cStringLength) return false; return (memcmp(_s->cString + (_s->cStringLength - cStringLength), suffix.UTF8String, cStringLength) == 0); } - (OFArray *)componentsSeparatedByString: (OFString *)delimiter options: (int)options { void *pool; OFMutableArray *array; const char *cString = delimiter.UTF8String; size_t cStringLength = delimiter.UTF8StringLength; bool skipEmpty = (options & OF_STRING_SKIP_EMPTY); size_t last; OFString *component; array = [OFMutableArray array]; pool = objc_autoreleasePoolPush(); if (cStringLength > _s->cStringLength) { [array addObject: [[self copy] autorelease]]; objc_autoreleasePoolPop(pool); return array; } last = 0; for (size_t i = 0; i <= _s->cStringLength - cStringLength; i++) { if (memcmp(_s->cString + i, cString, cStringLength) != 0) continue; component = [OFString stringWithUTF8String: _s->cString + last length: i - last]; if (!skipEmpty || component.length > 0) [array addObject: component]; i += cStringLength - 1; last = i + 1; } component = [OFString stringWithUTF8String: _s->cString + last]; if (!skipEmpty || component.length > 0) [array addObject: component]; [array makeImmutable]; objc_autoreleasePoolPop(pool); return array; } - (const of_unichar_t *)characters { OFObject *object = [[[OFObject alloc] init] autorelease]; of_unichar_t *ret; size_t i, j; ret = [object allocMemoryWithSize: sizeof(of_unichar_t) count: _s->length]; i = j = 0; while (i < _s->cStringLength) { of_unichar_t c; ssize_t cLen; cLen = of_string_utf8_decode(_s->cString + i, _s->cStringLength - i, &c); if (cLen <= 0 || c > 0x10FFFF) @throw [OFInvalidEncodingException exception]; ret[j++] = c; i += cLen; } return ret; } - (const of_char32_t *)UTF32StringWithByteOrder: (of_byte_order_t)byteOrder { OFObject *object = [[[OFObject alloc] init] autorelease]; of_char32_t *ret; size_t i, j; ret = [object allocMemoryWithSize: sizeof(of_unichar_t) count: _s->length + 1]; i = j = 0; while (i < _s->cStringLength) { of_unichar_t c; ssize_t cLen; cLen = of_string_utf8_decode(_s->cString + i, _s->cStringLength - i, &c); if (cLen <= 0 || c > 0x10FFFF) @throw [OFInvalidEncodingException exception]; if (byteOrder != OF_BYTE_ORDER_NATIVE) ret[j++] = OF_BSWAP32(c); else ret[j++] = c; i += cLen; } ret[j] = 0; return ret; } #ifdef OF_HAVE_BLOCKS - (void)enumerateLinesUsingBlock: (of_string_line_enumeration_block_t)block { void *pool; const char *cString = _s->cString; const char *last = cString; bool stop = false, lastCarriageReturn = false; while (!stop && *cString != 0) { if (lastCarriageReturn && *cString == '\n') { lastCarriageReturn = false; cString++; last++; continue; } if (*cString == '\n' || *cString == '\r') { pool = objc_autoreleasePoolPush(); block([OFString stringWithUTF8String: last length: cString - last], &stop); last = cString + 1; objc_autoreleasePoolPop(pool); } lastCarriageReturn = (*cString == '\r'); cString++; } pool = objc_autoreleasePoolPush(); if (!stop) block([OFString stringWithUTF8String: last length: cString - last], &stop); objc_autoreleasePoolPop(pool); } #endif @end |
Modified src/OFValue.m from [a898bac105] to [50d6956f54].
︙ | ︙ | |||
12 13 14 15 16 17 18 | * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #import "OFValue.h" | | | | | | | | | | | | | | | | | | | | | | 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 | * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #import "OFValue.h" #import "OFBytesValue.h" #import "OFDimensionValue.h" #import "OFMethodSignature.h" #import "OFNonretainedObjectValue.h" #import "OFPointValue.h" #import "OFPointerValue.h" #import "OFRangeValue.h" #import "OFRectangleValue.h" #import "OFString.h" #import "OFOutOfMemoryException.h" static struct { Class isa; } placeholder; @interface OFValuePlaceholder: OFValue @end @implementation OFValuePlaceholder - (instancetype)initWithBytes: (const void *)bytes objCType: (const char *)objCType { return (id)[[OFBytesValue alloc] initWithBytes: bytes objCType: objCType]; } - (instancetype)initWithPointer: (const void *)pointer { return (id)[[OFPointerValue alloc] initWithPointer: pointer]; } - (instancetype)initWithNonretainedObject: (id)object { return (id)[[OFNonretainedObjectValue alloc] initWithNonretainedObject: object]; } - (instancetype)initWithRange: (of_range_t)range { return (id)[[OFRangeValue alloc] initWithRange: range]; } - (instancetype)initWithPoint: (of_point_t)point { return (id)[[OFPointValue alloc] initWithPoint: point]; } - (instancetype)initWithDimension: (of_dimension_t)dimension { return (id)[[OFDimensionValue alloc] initWithDimension: dimension]; } - (instancetype)initWithRectangle: (of_rectangle_t)rectangle { return (id)[[OFRectangleValue alloc] initWithRectangle: rectangle]; } @end @implementation OFValue + (void)initialize { if (self == [OFValue class]) placeholder.isa = [OFValuePlaceholder class]; } + (instancetype)alloc { if (self == [OFValue class]) return (id)&placeholder; |
︙ | ︙ |
Deleted src/OFValue_bytes.h version [06a74f5b2c].
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted src/OFValue_bytes.m version [ca214b523a].
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted src/OFValue_dimension.h version [c4857d96df].
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted src/OFValue_dimension.m version [71a8287280].
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted src/OFValue_nonretainedObject.h version [df1e3dd58b].
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted src/OFValue_nonretainedObject.m version [3f6538dacb].
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted src/OFValue_point.h version [537c754eec].
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted src/OFValue_point.m version [d27843a207].
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted src/OFValue_pointer.h version [4f1749dc2d].
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted src/OFValue_pointer.m version [08168fec98].
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted src/OFValue_range.h version [8d6c6fd2cc].
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted src/OFValue_range.m version [c57cda6e6e].
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted src/OFValue_rectangle.h version [b8fdb386fa].
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted src/OFValue_rectangle.m version [e29102c8fc].
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Added src/OFWin32ConsoleStdIOStream.h version [f6d4919bb8].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | /* * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, * 2018, 2019 * Jonathan Schleifer <js@heap.zone> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #define OF_STDIO_STREAM_WIN32CONSOLE_H #import "OFStdIOStream.h" OF_ASSUME_NONNULL_BEGIN @interface OFWin32ConsoleStdIOStream: OFStdIOStream { HANDLE _handle; of_char16_t _incompleteUTF16Surrogate; char _incompleteUTF8Surrogate[4]; size_t _incompleteUTF8SurrogateLen; } @end OF_ASSUME_NONNULL_END |
Added src/OFWin32ConsoleStdIOStream.m version [2b42023382].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 | /* * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, * 2018, 2019 * Jonathan Schleifer <js@heap.zone> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ /* * This file tries to make writing UTF-8 strings to the console "just work" on * Windows. * * While Windows does provide a way to change the codepage of the console to * UTF-8, unfortunately, different Windows versions handle that differently. * For example, on Windows XP, when using Windows XP's console, changing the * codepage to UTF-8 mostly breaks write() and completely breaks read(): * write() suddenly returns the number of characters - instead of bytes - * written and read() just returns 0 as soon as a Unicode character is being * read. * * Therefore, instead of just using the UTF-8 codepage, this captures all reads * and writes to of_std{in,out,err} on the low level, interprets the buffer as * UTF-8 and converts to / from UTF-16 to use ReadConsoleW() / WriteConsoleW(). * Doing so is safe, as the console only supports text anyway and thus it does * not matter if binary gets garbled by the conversion (e.g. because invalid * UTF-8 gets converted to U+FFFD). * * In order to not do this when redirecting input / output to a file (as the * file would then be read / written in the wrong encoding and break reading / * writing binary), it checks that the handle is indeed a console. */ #define OF_STDIO_STREAM_WIN32_CONSOLE_M #include "config.h" #include <assert.h> #include <errno.h> #include <io.h> #import "OFWin32ConsoleStdIOStream.h" #import "OFData.h" #import "OFStdIOStream+Private.h" #import "OFString.h" #import "OFInvalidArgumentException.h" #import "OFInvalidEncodingException.h" #import "OFOutOfRangeException.h" #import "OFReadFailedException.h" #import "OFWriteFailedException.h" #include <windows.h> @implementation OFWin32ConsoleStdIOStream + (void)load { int fd; if (self != [OFWin32ConsoleStdIOStream class]) return; if ((fd = _fileno(stdin)) >= 0) of_stdin = [[OFWin32ConsoleStdIOStream_ alloc] of_initWithFileDescriptor: fd]; if ((fd = _fileno(stdout)) >= 0) of_stdout = [[OFWin32ConsoleStdIOStream alloc] of_initWithFileDescriptor: fd]; if ((fd = _fileno(stderr)) >= 0) of_stderr = [[OFWin32ConsoleStdIOStream alloc] of_initWithFileDescriptor: fd]; } - (instancetype)of_initWithFileDescriptor: (int)fd { self = [super of_initWithFileDescriptor: fd]; @try { DWORD mode; _handle = (HANDLE)_get_osfhandle(fd); if (_handle == INVALID_HANDLE_VALUE) @throw [OFInvalidArgumentException exception]; /* Not a console: Treat it as a regular OFStdIOStream */ if (!GetConsoleMode(_handle, &mode)) object_setClass(self, [OFStdIOStream class]); } @catch (id e) { [self release]; @throw e; } return self; } - (size_t)lowlevelReadIntoBuffer: (void *)buffer_ length: (size_t)length { void *pool = objc_autoreleasePoolPush(); char *buffer = buffer_; of_char16_t *UTF16; size_t j = 0; if (length > sizeof(UINT32_MAX)) @throw [OFOutOfRangeException exception]; UTF16 = [self allocMemoryWithSize: sizeof(of_char16_t) count: length]; @try { DWORD UTF16Len; OFMutableData *rest = nil; size_t i = 0; if (!ReadConsoleW(_handle, UTF16, (DWORD)length, &UTF16Len, NULL)) @throw [OFReadFailedException exceptionWithObject: self requestedLength: length * 2 errNo: EIO]; if (UTF16Len > 0 && _incompleteUTF16Surrogate != 0) { of_unichar_t c = (((_incompleteUTF16Surrogate & 0x3FF) << 10) | (UTF16[0] & 0x3FF)) + 0x10000; char UTF8[4]; size_t UTF8Len; if ((UTF8Len = of_string_utf8_encode(c, UTF8)) == 0) @throw [OFInvalidEncodingException exception]; if (UTF8Len <= length) { memcpy(buffer, UTF8, UTF8Len); j += UTF8Len; } else { if (rest == nil) rest = [OFMutableData data]; [rest addItems: UTF8 count: UTF8Len]; } _incompleteUTF16Surrogate = 0; i++; } for (; i < UTF16Len; i++) { of_unichar_t c = UTF16[i]; char UTF8[4]; size_t UTF8Len; /* Missing high surrogate */ if ((c & 0xFC00) == 0xDC00) @throw [OFInvalidEncodingException exception]; if ((c & 0xFC00) == 0xD800) { of_char16_t next; if (UTF16Len <= i + 1) { _incompleteUTF16Surrogate = c; if (rest != nil) { const char *items = rest.items; size_t count = rest.count; [self unreadFromBuffer: items length: count]; } objc_autoreleasePoolPop(pool); return j; } next = UTF16[i + 1]; if ((next & 0xFC00) != 0xDC00) @throw [OFInvalidEncodingException exception]; c = (((c & 0x3FF) << 10) | (next & 0x3FF)) + 0x10000; i++; } if ((UTF8Len = of_string_utf8_encode(c, UTF8)) == 0) @throw [OFInvalidEncodingException exception]; if (j + UTF8Len <= length) { memcpy(buffer + j, UTF8, UTF8Len); j += UTF8Len; } else { if (rest == nil) rest = [OFMutableData data]; [rest addItems: UTF8 count: UTF8Len]; } } if (rest != nil) [self unreadFromBuffer: rest.items length: rest.count]; } @finally { [self freeMemory: UTF16]; } objc_autoreleasePoolPop(pool); return j; } - (size_t)lowlevelWriteBuffer: (const void *)buffer_ length: (size_t)length { const char *buffer = buffer_; of_char16_t *tmp; size_t i = 0, j = 0; if (length > SIZE_MAX / 2) @throw [OFOutOfRangeException exception]; if (_incompleteUTF8SurrogateLen > 0) { of_unichar_t c; of_char16_t UTF16[2]; ssize_t UTF8Len; size_t toCopy; DWORD UTF16Len, bytesWritten; UTF8Len = -of_string_utf8_decode( _incompleteUTF8Surrogate, _incompleteUTF8SurrogateLen, &c); OF_ENSURE(UTF8Len > 0); toCopy = UTF8Len - _incompleteUTF8SurrogateLen; if (toCopy > length) toCopy = length; memcpy(_incompleteUTF8Surrogate + _incompleteUTF8SurrogateLen, buffer, toCopy); _incompleteUTF8SurrogateLen += toCopy; if (_incompleteUTF8SurrogateLen < (size_t)UTF8Len) return 0; UTF8Len = of_string_utf8_decode( _incompleteUTF8Surrogate, _incompleteUTF8SurrogateLen, &c); if (UTF8Len <= 0 || c > 0x10FFFF) { assert(UTF8Len == 0 || UTF8Len < -4); UTF16[0] = 0xFFFD; UTF16Len = 1; } else { if (c > 0xFFFF) { c -= 0x10000; UTF16[0] = 0xD800 | (c >> 10); UTF16[1] = 0xDC00 | (c & 0x3FF); UTF16Len = 2; } else { UTF16[0] = c; UTF16Len = 1; } } if (!WriteConsoleW(_handle, UTF16, UTF16Len, &bytesWritten, NULL)) @throw [OFWriteFailedException exceptionWithObject: self requestedLength: UTF16Len * 2 bytesWritten: 0 errNo: EIO]; if (bytesWritten != UTF16Len) @throw [OFWriteFailedException exceptionWithObject: self requestedLength: UTF16Len * 2 bytesWritten: bytesWritten * 2 errNo: 0]; _incompleteUTF8SurrogateLen = 0; i += toCopy; } tmp = [self allocMemoryWithSize: sizeof(of_char16_t) count: length * 2]; @try { DWORD bytesWritten; while (i < length) { of_unichar_t c; ssize_t UTF8Len; UTF8Len = of_string_utf8_decode(buffer + i, length - i, &c); if (UTF8Len < 0 && UTF8Len >= -4) { OF_ENSURE(length - i < 4); memcpy(_incompleteUTF8Surrogate, buffer + i, length - i); _incompleteUTF8SurrogateLen = length - i; break; } if (UTF8Len <= 0 || c > 0x10FFFF) { tmp[j++] = 0xFFFD; i++; continue; } if (c > 0xFFFF) { c -= 0x10000; tmp[j++] = 0xD800 | (c >> 10); tmp[j++] = 0xDC00 | (c & 0x3FF); } else tmp[j++] = c; i += UTF8Len; } if (j > UINT32_MAX) @throw [OFOutOfRangeException exception]; if (!WriteConsoleW(_handle, tmp, (DWORD)j, &bytesWritten, NULL)) @throw [OFWriteFailedException exceptionWithObject: self requestedLength: j * 2 bytesWritten: 0 errNo: EIO]; if (bytesWritten != j) @throw [OFWriteFailedException exceptionWithObject: self requestedLength: j * 2 bytesWritten: bytesWritten * 2 errNo: 0]; } @finally { [self freeMemory: tmp]; } /* * We do not count in bytes when writing to the Win32 console. But * since any incomplete write is an exception here anyway, we can just * return length. */ return length; } @end |
Modified src/OFXMLElement.m from [cbd628ecff] to [fc62d55fa3].
︙ | ︙ | |||
47 48 49 50 51 52 53 | { _OFXMLElement_Serialization_reference = 1; } static Class charactersClass = Nil; static Class CDATAClass = Nil; | | | | 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 | { _OFXMLElement_Serialization_reference = 1; } static Class charactersClass = Nil; static Class CDATAClass = Nil; @interface OFXMLElementElementBuilderDelegate: OFObject <OFXMLElementBuilderDelegate> { @public OFXMLElement *_element; } @end @implementation OFXMLElementElementBuilderDelegate - (void)elementBuilder: (OFXMLElementBuilder *)builder didBuildElement: (OFXMLElement *)element { if (_element == nil) _element = [element retain]; } |
︙ | ︙ | |||
212 213 214 215 216 217 218 | } - (instancetype)initWithXMLString: (OFString *)string { void *pool; OFXMLParser *parser; OFXMLElementBuilder *builder; | | | | 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 | } - (instancetype)initWithXMLString: (OFString *)string { void *pool; OFXMLParser *parser; OFXMLElementBuilder *builder; OFXMLElementElementBuilderDelegate *delegate; [self release]; if (string == nil) @throw [OFInvalidArgumentException exception]; pool = objc_autoreleasePoolPush(); parser = [OFXMLParser parser]; builder = [OFXMLElementBuilder elementBuilder]; delegate = [[[OFXMLElementElementBuilderDelegate alloc] init] autorelease]; parser.delegate = builder; builder.delegate = delegate; [parser parseString: string]; |
︙ | ︙ | |||
247 248 249 250 251 252 253 | #ifdef OF_HAVE_FILES - (instancetype)initWithFile: (OFString *)path { void *pool; OFXMLParser *parser; OFXMLElementBuilder *builder; | | | | 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 | #ifdef OF_HAVE_FILES - (instancetype)initWithFile: (OFString *)path { void *pool; OFXMLParser *parser; OFXMLElementBuilder *builder; OFXMLElementElementBuilderDelegate *delegate; [self release]; pool = objc_autoreleasePoolPush(); parser = [OFXMLParser parser]; builder = [OFXMLElementBuilder elementBuilder]; delegate = [[[OFXMLElementElementBuilderDelegate alloc] init] autorelease]; parser.delegate = builder; builder.delegate = delegate; [parser parseFile: path]; |
︙ | ︙ |
Modified src/OFZIPArchive.m from [4ebe3c89c2] to [ee57bc1743].
︙ | ︙ | |||
55 56 57 58 59 60 61 | @interface OFZIPArchive () - (void)of_readZIPInfo; - (void)of_readEntries; - (void)of_closeLastReturnedStream; - (void)of_writeCentralDirectory; @end | | | | | 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 | @interface OFZIPArchive () - (void)of_readZIPInfo; - (void)of_readEntries; - (void)of_closeLastReturnedStream; - (void)of_writeCentralDirectory; @end @interface OFZIPArchiveLocalFileHeader: OFObject { @public uint16_t _minVersionNeeded, _generalPurposeBitFlag, _compressionMethod; uint16_t _lastModifiedFileTime, _lastModifiedFileDate; uint32_t _CRC32; uint64_t _compressedSize, _uncompressedSize; OFString *_fileName; OFData *_extraField; } - (instancetype)initWithStream: (OFStream *)stream; - (bool)matchesEntry: (OFZIPArchiveEntry *)entry; @end @interface OFZIPArchiveFileReadStream: OFStream { OFStream *_stream, *_decompressedStream; OFZIPArchiveEntry *_entry; uint64_t _toRead; uint32_t _CRC32; bool _atEndOfStream; } - (instancetype)of_initWithStream: (OFStream *)stream entry: (OFZIPArchiveEntry *)entry; @end @interface OFZIPArchiveFileWriteStream: OFStream { OFStream *_stream; uint32_t _CRC32; @public int64_t _bytesWritten; OFMutableZIPArchiveEntry *_entry; } |
︙ | ︙ | |||
404 405 406 407 408 409 410 | - (void)of_closeLastReturnedStream { [_lastReturnedStream close]; if ((_mode == OF_ZIP_ARCHIVE_MODE_WRITE || _mode == OF_ZIP_ARCHIVE_MODE_APPEND) && [_lastReturnedStream isKindOfClass: | | | | | 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 | - (void)of_closeLastReturnedStream { [_lastReturnedStream close]; if ((_mode == OF_ZIP_ARCHIVE_MODE_WRITE || _mode == OF_ZIP_ARCHIVE_MODE_APPEND) && [_lastReturnedStream isKindOfClass: [OFZIPArchiveFileWriteStream class]]) { OFZIPArchiveFileWriteStream *stream = (OFZIPArchiveFileWriteStream *)_lastReturnedStream; if (INT64_MAX - _offset < stream->_bytesWritten) @throw [OFOutOfRangeException exception]; _offset += stream->_bytesWritten; if (stream->_entry != nil) { |
︙ | ︙ | |||
428 429 430 431 432 433 434 | _lastReturnedStream = nil; } - (OFStream *)streamForReadingFile: (OFString *)path { void *pool = objc_autoreleasePoolPush(); OFZIPArchiveEntry *entry; | | | | | 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 | _lastReturnedStream = nil; } - (OFStream *)streamForReadingFile: (OFString *)path { void *pool = objc_autoreleasePoolPush(); OFZIPArchiveEntry *entry; OFZIPArchiveLocalFileHeader *localFileHeader; int64_t offset64; if (_mode != OF_ZIP_ARCHIVE_MODE_READ) @throw [OFInvalidArgumentException exception]; if ((entry = [_pathToEntryMap objectForKey: path]) == nil) @throw [OFOpenItemFailedException exceptionWithPath: path mode: @"r" errNo: ENOENT]; [self of_closeLastReturnedStream]; offset64 = entry.of_localFileHeaderOffset; if (offset64 < 0 || (of_offset_t)offset64 != offset64) @throw [OFOutOfRangeException exception]; seekOrThrowInvalidFormat((OFSeekableStream *)_stream, (of_offset_t)offset64, SEEK_SET); localFileHeader = [[[OFZIPArchiveLocalFileHeader alloc] initWithStream: _stream] autorelease]; if (![localFileHeader matchesEntry: entry]) @throw [OFInvalidFormatException exception]; if ((localFileHeader->_minVersionNeeded & 0xFF) > 45) { OFString *version = [OFString stringWithFormat: @"%u.%u", (localFileHeader->_minVersionNeeded & 0xFF) / 10, (localFileHeader->_minVersionNeeded & 0xFF) % 10]; @throw [OFUnsupportedVersionException exceptionWithVersion: version]; } _lastReturnedStream = [[OFZIPArchiveFileReadStream alloc] of_initWithStream: _stream entry: entry]; objc_autoreleasePoolPop(pool); return [[_lastReturnedStream retain] autorelease]; } |
︙ | ︙ | |||
552 553 554 555 556 557 558 | offsetAdd += extraFieldLength; if (INT64_MAX - _offset < offsetAdd) @throw [OFOutOfRangeException exception]; _offset += offsetAdd; | | | 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 | offsetAdd += extraFieldLength; if (INT64_MAX - _offset < offsetAdd) @throw [OFOutOfRangeException exception]; _offset += offsetAdd; _lastReturnedStream = [[OFZIPArchiveFileWriteStream alloc] initWithStream: _stream entry: entry]; objc_autoreleasePoolPop(pool); return [[_lastReturnedStream retain] autorelease]; } |
︙ | ︙ | |||
626 627 628 629 630 631 632 | [self of_writeCentralDirectory]; [_stream release]; _stream = nil; } @end | | | 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 | [self of_writeCentralDirectory]; [_stream release]; _stream = nil; } @end @implementation OFZIPArchiveLocalFileHeader - (instancetype)initWithStream: (OFStream *)stream { self = [super init]; @try { void *pool = objc_autoreleasePoolPush(); OFMutableData *extraField = nil; |
︙ | ︙ | |||
726 727 728 729 730 731 732 | if (![_fileName isEqual: entry.fileName]) return false; return true; } @end | | | 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 | if (![_fileName isEqual: entry.fileName]) return false; return true; } @end @implementation OFZIPArchiveFileReadStream - (instancetype)of_initWithStream: (OFStream *)stream entry: (OFZIPArchiveEntry *)entry { self = [super init]; @try { _stream = [stream retain]; |
︙ | ︙ | |||
853 854 855 856 857 858 859 | [_decompressedStream release]; _decompressedStream = nil; [super close]; } @end | | | 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 | [_decompressedStream release]; _decompressedStream = nil; [super close]; } @end @implementation OFZIPArchiveFileWriteStream - (instancetype)initWithStream: (OFStream *)stream entry: (OFMutableZIPArchiveEntry *)entry { self = [super init]; _stream = [stream retain]; _entry = [entry retain]; |
︙ | ︙ |
Modified src/bridge/Makefile from [ce4a0c019e] to [f31f6bb273].
︙ | ︙ | |||
17 18 19 20 21 22 23 | NSString+OFObject.m INCLUDES := ${SRCS:.m=.h} \ NSBridging.h \ OFBridging.h \ ObjFWBridge.h | | | | | | 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | NSString+OFObject.m INCLUDES := ${SRCS:.m=.h} \ NSBridging.h \ OFBridging.h \ ObjFWBridge.h SRCS += NSOFArray.m \ NSOFDictionary.m \ OFNSArray.m \ OFNSDictionary.m \ includesubdir = ObjFWBridge include ../../buildsys.mk CPPFLAGS += -I. -I.. -I../.. -I../exceptions -DOF_BRIDGE_LOCAL_INCLUDES LD = ${OBJC} |
︙ | ︙ |
Modified src/bridge/NSArray+OFObject.m from [06544cde57] to [a67d5a3626].
︙ | ︙ | |||
12 13 14 15 16 17 18 | * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #import "NSArray+OFObject.h" | | | | 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #import "NSArray+OFObject.h" #import "OFNSArray.h" int _NSArray_OFObject_reference; @implementation NSArray (OFObject) - (id)OFObject { return [[[OFNSArray alloc] initWithNSArray: self] autorelease]; } @end |
Deleted src/bridge/NSArray_OFArray.h version [b7791982d2].
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted src/bridge/NSArray_OFArray.m version [48bc1264c2].
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Modified src/bridge/NSDictionary+OFObject.m from [43925a9e33] to [223ba55d15].
︙ | ︙ | |||
12 13 14 15 16 17 18 | * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #import "NSDictionary+OFObject.h" | | | | 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #import "NSDictionary+OFObject.h" #import "OFNSDictionary.h" int _NSDictionary_OFObject_reference; @implementation NSDictionary (OFObject) - (id)OFObject { return [[[OFNSDictionary alloc] initWithNSDictionary: self] autorelease]; } @end |
Deleted src/bridge/NSDictionary_OFDictionary.h version [b7613bb69d].
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted src/bridge/NSDictionary_OFDictionary.m version [d509c1b2b1].
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Added src/bridge/NSOFArray.h version [876f9801fd].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | /* * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, * 2018, 2019 * Jonathan Schleifer <js@heap.zone> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #import <Foundation/NSArray.h> #import "macros.h" @class OFArray; OF_ASSUME_NONNULL_BEGIN @interface NSOFArray: NSArray { OFArray *_array; } - (instancetype)initWithOFArray: (OFArray *)array; @end OF_ASSUME_NONNULL_END |
Added src/bridge/NSOFArray.m version [119e446fe6].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 | /* * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, * 2018, 2019 * Jonathan Schleifer <js@heap.zone> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #import "NSOFArray.h" #import "OFArray.h" #import "OFBridging.h" #import "OFOutOfRangeException.h" @implementation NSOFArray - (instancetype)initWithOFArray: (OFArray *)array { if ((self = [super init]) != nil) { @try { _array = [array retain]; } @catch (id e) { return nil; } } return self; } - (id)objectAtIndex: (NSUInteger)idx { id object = [_array objectAtIndex: idx]; if ([(OFObject *)object conformsToProtocol: @protocol(OFBridging)]) return [object NSObject]; return object; } - (NSUInteger)count { size_t count = _array.count; if (count > NSUIntegerMax) @throw [OFOutOfRangeException exception]; return (NSUInteger)count; } @end |
Added src/bridge/NSOFDictionary.h version [5da2dfd5c4].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | /* * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, * 2018, 2019 * Jonathan Schleifer <js@heap.zone> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #import <Foundation/NSDictionary.h> #import "macros.h" @class OFDictionary; OF_ASSUME_NONNULL_BEGIN @interface NSOFDictionary: NSDictionary { OFDictionary *_dictionary; } - (instancetype)initWithOFDictionary: (OFDictionary *)dictionary; @end OF_ASSUME_NONNULL_END |
Added src/bridge/NSOFDictionary.m version [671d75450d].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 | /* * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, * 2018, 2019 * Jonathan Schleifer <js@heap.zone> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #import "NSOFDictionary.h" #import "OFDictionary.h" #import "NSBridging.h" #import "OFBridging.h" #import "OFOutOfRangeException.h" @implementation NSOFDictionary - (instancetype)initWithOFDictionary: (OFDictionary *)dictionary { if ((self = [super init]) != nil) { @try { _dictionary = [dictionary retain]; } @catch (id e) { return nil; } } return self; } - (id)objectForKey: (id)key { id object; if ([(NSObject *)key conformsToProtocol: @protocol(NSBridging)]) key = [key OFObject]; object = [_dictionary objectForKey: key]; if ([(OFObject *)object conformsToProtocol: @protocol(OFBridging)]) return [object NSObject]; return object; } - (NSUInteger)count { size_t count = _dictionary.count; if (count > NSUIntegerMax) @throw [OFOutOfRangeException exception]; return (NSUInteger)count; } @end |
Modified src/bridge/OFArray+NSObject.m from [d0e114f7db] to [962fd0eb4e].
︙ | ︙ | |||
11 12 13 14 15 16 17 | * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ | | | | 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #import "NSOFArray.h" #import "OFArray+NSObject.h" int _OFArray_NSObject_reference; @implementation OFArray (NSObject) - (id)NSObject { return [[[NSOFArray alloc] initWithOFArray: self] autorelease]; } @end |
Deleted src/bridge/OFArray_NSArray.h version [cb13fb83ad].
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted src/bridge/OFArray_NSArray.m version [48af716058].
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Modified src/bridge/OFDictionary+NSObject.m from [e33a5852c5] to [3487ea35f9].
︙ | ︙ | |||
11 12 13 14 15 16 17 | * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ | | | | 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #import "NSOFDictionary.h" #import "OFDictionary+NSObject.h" int _OFDictionary_NSObject_reference; @implementation OFDictionary (NSObject) - (id)NSObject { return [[[NSOFDictionary alloc] initWithOFDictionary: self] autorelease]; } @end |
Deleted src/bridge/OFDictionary_NSDictionary.h version [492f8f7994].
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted src/bridge/OFDictionary_NSDictionary.m version [6f3ba7ec5c].
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Added src/bridge/OFNSArray.h version [911481dd73].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | /* * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, * 2018, 2019 * Jonathan Schleifer <js@heap.zone> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #ifdef OF_BRIDGE_LOCAL_INCLUDES # import "OFArray.h" #else # if defined(__has_feature) && __has_feature(modules) @import ObjFW; # else # import <ObjFW/OFArray.h> # endif #endif OF_ASSUME_NONNULL_BEGIN @class NSArray; @interface OFNSArray: OFArray { NSArray *_array; } - (instancetype)initWithNSArray: (NSArray *)array; @end OF_ASSUME_NONNULL_END |
Added src/bridge/OFNSArray.m version [79fd147030].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 | /* * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, * 2018, 2019 * Jonathan Schleifer <js@heap.zone> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #import <Foundation/NSArray.h> #import "OFNSArray.h" #import "NSBridging.h" #import "OFInitializationFailedException.h" #import "OFOutOfRangeException.h" @implementation OFNSArray - (instancetype)initWithNSArray: (NSArray *)array { self = [super init]; @try { if (array == nil) @throw [OFInitializationFailedException exceptionWithClass: self.class]; _array = [array retain]; } @catch (id e) { [self release]; @throw e; } return self; } - (id)objectAtIndex: (size_t)idx { id object; if (idx > NSUIntegerMax) @throw [OFOutOfRangeException exception]; object = [_array objectAtIndex: idx]; if ([(NSObject *)object conformsToProtocol: @protocol(NSBridging)]) return [object OFObject]; return object; } - (size_t)count { return _array.count; } @end |
Added src/bridge/OFNSDictionary.h version [fa76854e3a].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | /* * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, * 2018, 2019 * Jonathan Schleifer <js@heap.zone> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #ifdef OF_BRIDGE_LOCAL_INCLUDES # import "OFDictionary.h" #else # if defined(__has_feature) && __has_feature(modules) @import ObjFW; # else # import <ObjFW/OFDictionary.h> # endif #endif OF_ASSUME_NONNULL_BEGIN @class NSDictionary; @interface OFNSDictionary: OFDictionary { NSDictionary *_dictionary; } - (instancetype)initWithNSDictionary: (NSDictionary *)dictionary; @end OF_ASSUME_NONNULL_END |
Added src/bridge/OFNSDictionary.m version [233690560e].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 | /* * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, * 2018, 2019 * Jonathan Schleifer <js@heap.zone> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #import <Foundation/NSDictionary.h> #import "OFNSDictionary.h" #import "NSBridging.h" #import "OFBridging.h" #import "OFInitializationFailedException.h" @implementation OFNSDictionary - (instancetype)initWithNSDictionary: (NSDictionary *)dictionary { self = [super init]; @try { if (dictionary == nil) @throw [OFInitializationFailedException exceptionWithClass: self.class]; _dictionary = [dictionary retain]; } @catch (id e) { [self release]; @throw e; } return self; } - (id)objectForKey: (id)key { id object; if ([(OFObject *)key conformsToProtocol: @protocol(OFBridging)]) key = [key NSObject]; object = [_dictionary objectForKey: key]; if ([(NSObject *)object conformsToProtocol: @protocol(NSBridging)]) return [object OFObject]; return object; } - (size_t)count { return _dictionary.count; } @end |
Modified tests/OFCharacterSetTests.m from [bc8546fbb5] to [e126da2945].
︙ | ︙ | |||
15 16 17 18 19 20 21 | * file. */ #include "config.h" #import "TestsAppDelegate.h" | | > | | 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | * file. */ #include "config.h" #import "TestsAppDelegate.h" #import "OFCharacterSet.h" #import "OFBitSetCharacterSet.h" #import "OFRangeCharacterSet.h" static OFString *module = nil; @interface SimpleCharacterSet: OFCharacterSet @end @implementation SimpleCharacterSet |
︙ | ︙ | |||
51 52 53 54 55 56 57 | if (![cs characterIsMember: c]) ok = false; } else if ([cs characterIsMember: c]) ok = false; } TEST(@"-[characterIsMember:]", ok); | | | | | | 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 | if (![cs characterIsMember: c]) ok = false; } else if ([cs characterIsMember: c]) ok = false; } TEST(@"-[characterIsMember:]", ok); module = @"OFBitSetCharacterSet"; TEST(@"+[characterSetWithCharactersInString:]", (cs = [OFCharacterSet characterSetWithCharactersInString: @"0123456789"]) && [cs isKindOfClass: [OFBitSetCharacterSet class]]) ok = true; for (of_unichar_t c = 0; c < 65536; c++) { if (c >= '0' && c <= '9') { if (![cs characterIsMember: c]) ok = false; } else if ([cs characterIsMember: c]) ok = false; } TEST(@"-[characterIsMember:]", ok); module = @"OFRangeCharacterSet"; TEST(@"+[characterSetWithRange:]", (cs = [OFCharacterSet characterSetWithRange: of_range('0', 10)]) && [cs isKindOfClass: [OFRangeCharacterSet class]]) ok = true; for (of_unichar_t c = 0; c < 65536; c++) { if (c >= '0' && c <= '9') { if (![cs characterIsMember: c]) ok = false; } else if ([cs characterIsMember: c]) |
︙ | ︙ |
Modified tests/OFKernelEventObserverTests.m from [70f44cc10f] to [acffe39aa3].
︙ | ︙ | |||
14 15 16 17 18 19 20 | * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #ifdef HAVE_KQUEUE | | | | | | 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #ifdef HAVE_KQUEUE # import "OFKqueueKernelEventObserver.h" #endif #ifdef HAVE_EPOLL # import "OFEpollKernelEventObserver.h" #endif #ifdef HAVE_POLL # import "OFPollKernelEventObserver.h" #endif #ifdef HAVE_SELECT # import "OFSelectKernelEventObserver.h" #endif #import "TestsAppDelegate.h" #define EXPECTED_EVENTS 3 static OFString *module; |
︙ | ︙ | |||
217 218 219 220 221 222 223 | [pool drain]; } - (void)kernelEventObserverTests { #ifdef HAVE_SELECT [self kernelEventObserverTestsWithClass: | | | | | | 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 | [pool drain]; } - (void)kernelEventObserverTests { #ifdef HAVE_SELECT [self kernelEventObserverTestsWithClass: [OFSelectKernelEventObserver class]]; #endif #ifdef HAVE_POLL [self kernelEventObserverTestsWithClass: [OFPollKernelEventObserver class]]; #endif #ifdef HAVE_EPOLL [self kernelEventObserverTestsWithClass: [OFEpollKernelEventObserver class]]; #endif #ifdef HAVE_KQUEUE [self kernelEventObserverTestsWithClass: [OFKqueueKernelEventObserver class]]; #endif } @end |
Modified tests/OFSetTests.m from [c26bc92ca5] to [984a5f0223].
︙ | ︙ | |||
15 16 17 18 19 20 21 | * file. */ #include "config.h" #import "TestsAppDelegate.h" | | | > | 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | * file. */ #include "config.h" #import "TestsAppDelegate.h" #import "OFSet.h" #import "OFMapTableSet.h" #import "OFMutableMapTableSet.h" static OFString *module = nil; @interface SimpleSet: OFSet { OFMutableSet *_set; } |
︙ | ︙ | |||
272 273 274 275 276 277 278 | - (void)setTests { module = @"OFSet"; [self setTestsWithClass: [SimpleSet class] mutableClass: [SimpleMutableSet class]]; | | | | | 273 274 275 276 277 278 279 280 281 282 283 284 | - (void)setTests { module = @"OFSet"; [self setTestsWithClass: [SimpleSet class] mutableClass: [SimpleMutableSet class]]; module = @"OFMapTableSet"; [self setTestsWithClass: [OFMapTableSet class] mutableClass: [OFMutableMapTableSet class]]; } @end |
Modified tests/OFStringTests.m from [e7c58a38d5] to [6659b80a48].
︙ | ︙ | |||
19 20 21 22 23 24 25 | #include <stdlib.h> #include <string.h> #include <math.h> #import "TestsAppDelegate.h" | > | > | 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | #include <stdlib.h> #include <string.h> #include <math.h> #import "TestsAppDelegate.h" #import "OFString.h" #import "OFMutableUTF8String.h" #import "OFUTF8String.h" static OFString *module = nil; static OFString *whitespace[] = { @" \r \t\n\t \tasd \t \t\t\r\n", @" \t\t \t\t \t \t" }; static of_unichar_t ucstr[] = { |
︙ | ︙ | |||
1428 1429 1430 1431 1432 1433 1434 | - (void)stringTests { module = @"OFString"; [self stringTestsWithClass: [SimpleString class] mutableClass: [SimpleMutableString class]]; module = @"OFString_UTF8"; | | | | 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 | - (void)stringTests { module = @"OFString"; [self stringTestsWithClass: [SimpleString class] mutableClass: [SimpleMutableString class]]; module = @"OFString_UTF8"; [self stringTestsWithClass: [OFUTF8String class] mutableClass: [OFMutableUTF8String class]]; } @end |
Modified tests/OFValueTests.m from [46b74c3a5c] to [55c7d2a02d].
︙ | ︙ | |||
81 82 83 84 85 86 87 | TEST(@"-[rangeValue]", of_range_equal(value.rangeValue, range) && (value = [OFValue valueWithBytes: &range objCType: @encode(of_range_t)]) && of_range_equal(value.rangeValue, range)) | | | | | | 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 | TEST(@"-[rangeValue]", of_range_equal(value.rangeValue, range) && (value = [OFValue valueWithBytes: &range objCType: @encode(of_range_t)]) && of_range_equal(value.rangeValue, range)) TEST(@"-[getValue:size:] for OFRangeValue", (value = [OFValue valueWithRange: range]) && R([value getValue: &range2 size: sizeof(range2)]) && of_range_equal(range2, range)) EXPECT_EXCEPTION(@"-[rangeValue] with wrong size throws", OFOutOfRangeException, [[OFValue valueWithBytes: "a" objCType: @encode(char)] rangeValue]) TEST(@"+[valueWithPoint:]", (value = [OFValue valueWithPoint: point])) TEST(@"-[pointValue]", of_point_equal(value.pointValue, point) && (value = [OFValue valueWithBytes: &point objCType: @encode(of_point_t)]) && of_point_equal(value.pointValue, point)) TEST(@"-[getValue:size:] for OFPointValue", (value = [OFValue valueWithPoint: point]) && R([value getValue: &point2 size: sizeof(point2)]) && of_point_equal(point2, point)) EXPECT_EXCEPTION(@"-[pointValue] with wrong size throws", OFOutOfRangeException, [[OFValue valueWithBytes: "a" objCType: @encode(char)] pointValue]) TEST(@"+[valueWithDimension:]", (value = [OFValue valueWithDimension: dimension])) TEST(@"-[dimensionValue]", of_dimension_equal(value.dimensionValue, dimension) && (value = [OFValue valueWithBytes: &dimension objCType: @encode(of_dimension_t)]) && of_dimension_equal(value.dimensionValue, dimension)) TEST(@"-[getValue:size:] for OFDimensionValue", (value = [OFValue valueWithDimension: dimension]) && R([value getValue: &dimension2 size: sizeof(dimension2)]) && of_dimension_equal(dimension2, dimension)) EXPECT_EXCEPTION(@"-[dimensionValue] with wrong size throws", OFOutOfRangeException, [[OFValue valueWithBytes: "a" objCType: @encode(char)] dimensionValue]) TEST(@"+[valueWithRectangle:]", (value = [OFValue valueWithRectangle: rectangle])) TEST(@"-[rectangleValue]", of_rectangle_equal(value.rectangleValue, rectangle) && (value = [OFValue valueWithBytes: &rectangle objCType: @encode(of_rectangle_t)]) && of_rectangle_equal(value.rectangleValue, rectangle)) TEST(@"-[getValue:size:] for OFRectangleValue", (value = [OFValue valueWithRectangle: rectangle]) && R([value getValue: &rectangle2 size: sizeof(rectangle2)]) && of_rectangle_equal(rectangle2, rectangle)) EXPECT_EXCEPTION(@"-[rectangleValue] with wrong size throws", OFOutOfRangeException, |
︙ | ︙ |