Comment: | Use dot syntax |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA3-256: |
bceb7ed4c93080c0ab9cd2e98876f523 |
User & Date: | js on 2019-03-08 00:35:48 |
Other Links: | manifest | tags |
2019-03-09
| ||
10:48 | Several minor fixes check-in: c1e949a8c6 user: js tags: trunk | |
2019-03-08
| ||
00:35 | Use dot syntax check-in: bceb7ed4c9 user: js tags: trunk | |
2019-03-03
| ||
12:40 | OFHTTPServer: Support for using multiple threads check-in: 607cd05ad7 user: js tags: trunk | |
Modified src/OFASN1BitString.m from [12624c872e] to [1e12f722e3].
︙ | ︙ | |||
39 40 41 42 43 44 45 | - (instancetype)initWithBitStringValue: (OFData *)bitStringValue bitStringLength: (size_t)bitStringLength { self = [super init]; @try { | | | 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | - (instancetype)initWithBitStringValue: (OFData *)bitStringValue bitStringLength: (size_t)bitStringLength { self = [super init]; @try { if (bitStringValue.count * bitStringValue.itemSize != bitStringLength / 8) @throw [OFInvalidFormatException exception]; _bitStringValue = [bitStringValue copy]; _bitStringLength = bitStringLength; } @catch (id e) { [self release]; |
︙ | ︙ | |||
64 65 66 67 68 69 70 | { void *pool = objc_autoreleasePoolPush(); OFData *bitStringValue; size_t bitStringLength; @try { unsigned char lastByteBits; | | | | 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 | { void *pool = objc_autoreleasePoolPush(); OFData *bitStringValue; size_t bitStringLength; @try { unsigned char lastByteBits; size_t count = DEREncodedContents.count; if (tagClass != OF_ASN1_TAG_CLASS_UNIVERSAL || tagNumber != OF_ASN1_TAG_NUMBER_BIT_STRING || constructed) @throw [OFInvalidArgumentException exception]; if (DEREncodedContents.itemSize != 1 || count == 0) @throw [OFInvalidFormatException exception]; lastByteBits = *(unsigned char *)[DEREncodedContents itemAtIndex: 0]; if (count == 1 && lastByteBits != 0) @throw [OFInvalidFormatException exception]; |
︙ | ︙ | |||
130 131 132 133 134 135 136 | return false; return true; } - (uint32_t)hash { | | | 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 | return false; return true; } - (uint32_t)hash { return _bitStringValue.hash + (uint32_t)_bitStringLength; } - (OFString *)description { return [OFString stringWithFormat: @"<OFASN1BitString: %@ (%zu bits)>", _bitStringValue, _bitStringLength]; } @end |
Modified src/OFASN1Boolean.m from [d63a1fe7aa] to [dc4725221d].
︙ | ︙ | |||
49 50 51 52 53 54 55 | unsigned char value; @try { if (tagClass != OF_ASN1_TAG_CLASS_UNIVERSAL || tagNumber != OF_ASN1_TAG_NUMBER_BOOLEAN || constructed) @throw [OFInvalidArgumentException exception]; | | | | 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 | unsigned char value; @try { if (tagClass != OF_ASN1_TAG_CLASS_UNIVERSAL || tagNumber != OF_ASN1_TAG_NUMBER_BOOLEAN || constructed) @throw [OFInvalidArgumentException exception]; if (DEREncodedContents.itemSize != 1 || DEREncodedContents.count != 1) @throw [OFInvalidFormatException exception]; value = *(unsigned char *)[DEREncodedContents itemAtIndex: 0]; if (value != 0 && value != 0xFF) @throw [OFInvalidFormatException exception]; } @catch (id e) { |
︙ | ︙ |
Modified src/OFASN1Enumerated.m from [bfa277b108] to [a4cf04c865].
︙ | ︙ | |||
51 52 53 54 55 56 57 | intmax_t integerValue; @try { if (tagClass != OF_ASN1_TAG_CLASS_UNIVERSAL || tagNumber != OF_ASN1_TAG_NUMBER_ENUMERATED || constructed) @throw [OFInvalidArgumentException exception]; | | | | 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 | intmax_t integerValue; @try { if (tagClass != OF_ASN1_TAG_CLASS_UNIVERSAL || tagNumber != OF_ASN1_TAG_NUMBER_ENUMERATED || constructed) @throw [OFInvalidArgumentException exception]; if (DEREncodedContents.itemSize != 1) @throw [OFInvalidArgumentException exception]; integerValue = of_asn1_der_integer_parse( DEREncodedContents.items, DEREncodedContents.count); } @catch (id e) { [self release]; @throw e; } return [self initWithIntegerValue: integerValue]; } |
︙ | ︙ |
Modified src/OFASN1IA5String.m from [f26ab2e662] to [ec99f99ba0].
︙ | ︙ | |||
54 55 56 57 58 59 60 | OFString *IA5StringValue; @try { if (tagClass != OF_ASN1_TAG_CLASS_UNIVERSAL || tagNumber != OF_ASN1_TAG_NUMBER_IA5_STRING || constructed) @throw [OFInvalidArgumentException exception]; | | | | | 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 | OFString *IA5StringValue; @try { if (tagClass != OF_ASN1_TAG_CLASS_UNIVERSAL || tagNumber != OF_ASN1_TAG_NUMBER_IA5_STRING || constructed) @throw [OFInvalidArgumentException exception]; if (DEREncodedContents.itemSize != 1) @throw [OFInvalidArgumentException exception]; IA5StringValue = [OFString stringWithCString: DEREncodedContents.items encoding: OF_STRING_ENCODING_ASCII length: DEREncodedContents.count]; } @catch (id e) { [self release]; @throw e; } self = [self initWithStringValue: IA5StringValue]; |
︙ | ︙ | |||
87 88 89 90 91 92 93 | [_IA5StringValue release]; [super dealloc]; } - (OFString *)stringValue { | | | | 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 | [_IA5StringValue release]; [super dealloc]; } - (OFString *)stringValue { return self.IA5StringValue; } - (bool)isEqual: (id)object { OFASN1IA5String *IA5String; if (![object isKindOfClass: [OFASN1IA5String class]]) return false; IA5String = object; if (![IA5String->_IA5StringValue isEqual: _IA5StringValue]) return false; return true; } - (uint32_t)hash { return _IA5StringValue.hash; } - (OFString *)description { return [OFString stringWithFormat: @"<OFASN1IA5String: %@>", _IA5StringValue]; } @end |
Modified src/OFASN1Integer.m from [508a881579] to [f2823c2ecb].
︙ | ︙ | |||
73 74 75 76 77 78 79 | intmax_t integerValue; @try { if (tagClass != OF_ASN1_TAG_CLASS_UNIVERSAL || tagNumber != OF_ASN1_TAG_NUMBER_INTEGER || constructed) @throw [OFInvalidArgumentException exception]; | | | | 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 | intmax_t integerValue; @try { if (tagClass != OF_ASN1_TAG_CLASS_UNIVERSAL || tagNumber != OF_ASN1_TAG_NUMBER_INTEGER || constructed) @throw [OFInvalidArgumentException exception]; if (DEREncodedContents.itemSize != 1) @throw [OFInvalidArgumentException exception]; integerValue = of_asn1_der_integer_parse( DEREncodedContents.items, DEREncodedContents.count); } @catch (id e) { [self release]; @throw e; } return [self initWithIntegerValue: integerValue]; } |
︙ | ︙ |
Modified src/OFASN1NumericString.m from [5a551cb41a] to [cdfb24dfd4].
︙ | ︙ | |||
34 35 36 37 38 39 40 | - (instancetype)initWithStringValue: (OFString *)stringValue { self = [super init]; @try { void *pool = objc_autoreleasePoolPush(); | | | | 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 | - (instancetype)initWithStringValue: (OFString *)stringValue { self = [super init]; @try { void *pool = objc_autoreleasePoolPush(); const char *cString = stringValue.UTF8String; size_t length = stringValue.UTF8StringLength; for (size_t i = 0; i < length; i++) if (!of_ascii_isdigit(cString[i]) && cString[i] != ' ') @throw [OFInvalidEncodingException exception]; _numericStringValue = [stringValue copy]; |
︙ | ︙ | |||
66 67 68 69 70 71 72 | @try { if (tagClass != OF_ASN1_TAG_CLASS_UNIVERSAL || tagNumber != OF_ASN1_TAG_NUMBER_NUMERIC_STRING || constructed) @throw [OFInvalidArgumentException exception]; | | | | | 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 | @try { if (tagClass != OF_ASN1_TAG_CLASS_UNIVERSAL || tagNumber != OF_ASN1_TAG_NUMBER_NUMERIC_STRING || constructed) @throw [OFInvalidArgumentException exception]; if (DEREncodedContents.itemSize != 1) @throw [OFInvalidArgumentException exception]; numericStringValue = [OFString stringWithCString: DEREncodedContents.items encoding: OF_STRING_ENCODING_ASCII length: DEREncodedContents.count]; } @catch (id e) { [self release]; @throw e; } self = [self initWithStringValue: numericStringValue]; |
︙ | ︙ | |||
99 100 101 102 103 104 105 | [_numericStringValue release]; [super dealloc]; } - (OFString *)stringValue { | | | | 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 | [_numericStringValue release]; [super dealloc]; } - (OFString *)stringValue { return self.numericStringValue; } - (bool)isEqual: (id)object { OFASN1NumericString *numericString; if (![object isKindOfClass: [OFASN1NumericString class]]) return false; numericString = object; if (![numericString->_numericStringValue isEqual: _numericStringValue]) return false; return true; } - (uint32_t)hash { return _numericStringValue.hash; } - (OFString *)description { return [OFString stringWithFormat: @"<OFASN1NumericString: %@>", _numericStringValue]; } @end |
Modified src/OFASN1ObjectIdentifier.m from [1ad931a1cf] to [531a8feaa4].
︙ | ︙ | |||
39 40 41 42 43 44 45 | - (instancetype)initWithSubidentifiers: (OFArray OF_GENERIC(OFNumber *) *)subidentifiers { self = [super init]; @try { | | | 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | - (instancetype)initWithSubidentifiers: (OFArray OF_GENERIC(OFNumber *) *)subidentifiers { self = [super init]; @try { if (subidentifiers.count < 1) @throw [OFInvalidFormatException exception]; switch ([[subidentifiers objectAtIndex: 0] intMaxValue]) { case 0: case 1: case 2: break; |
︙ | ︙ | |||
69 70 71 72 73 74 75 | constructed: (bool)constructed DEREncodedContents: (OFData *)DEREncodedContents { void *pool = objc_autoreleasePoolPush(); OFMutableArray OF_GENERIC(OFNumber *) *subidentifiers; @try { | | | | | | 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 | constructed: (bool)constructed DEREncodedContents: (OFData *)DEREncodedContents { void *pool = objc_autoreleasePoolPush(); OFMutableArray OF_GENERIC(OFNumber *) *subidentifiers; @try { const unsigned char *items = DEREncodedContents.items; size_t count = DEREncodedContents.count; uintmax_t value = 0; uint_fast8_t bits = 0; if (tagClass != OF_ASN1_TAG_CLASS_UNIVERSAL || tagNumber != OF_ASN1_TAG_NUMBER_OBJECT_IDENTIFIER || constructed) @throw [OFInvalidArgumentException exception]; if (DEREncodedContents.itemSize != 1 || count == 0) @throw [OFInvalidArgumentException exception]; subidentifiers = [OFMutableArray array]; for (size_t i = 0; i < count; i++) { if (bits == 0 && items[i] == 0x80) @throw [OFInvalidFormatException exception]; value = (value << 7) | (items[i] & 0x7F); bits += 7; if (bits > sizeof(uintmax_t) * 8) @throw [OFOutOfRangeException exception]; if (items[i] & 0x80) continue; if (subidentifiers.count == 0) { if (value < 40) [subidentifiers addObject: [OFNumber numberWithUIntMax: 0]]; else if (value < 80) { [subidentifiers addObject: [OFNumber numberWithUIntMax: 1]]; value -= 40; |
︙ | ︙ | |||
164 165 166 167 168 169 170 | return false; return true; } - (uint32_t)hash { | | | 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 | return false; return true; } - (uint32_t)hash { return _subidentifiers.hash; } - (OFString *)description { return [OFString stringWithFormat: @"<OFASN1ObjectIdentifier: %@>", [_subidentifiers componentsJoinedByString: @"."]]; } @end |
Modified src/OFASN1OctetString.m from [45195d9bbf] to [3e4389dd2d].
︙ | ︙ | |||
53 54 55 56 57 58 59 | { @try { if (tagClass != OF_ASN1_TAG_CLASS_UNIVERSAL || tagNumber != OF_ASN1_TAG_NUMBER_OCTET_STRING || constructed) @throw [OFInvalidArgumentException exception]; | | | 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 | { @try { if (tagClass != OF_ASN1_TAG_CLASS_UNIVERSAL || tagNumber != OF_ASN1_TAG_NUMBER_OCTET_STRING || constructed) @throw [OFInvalidArgumentException exception]; if (DEREncodedContents.itemSize != 1) @throw [OFInvalidArgumentException exception]; } @catch (id e) { [self release]; @throw e; } return [self initWithOctetStringValue: DEREncodedContents]; |
︙ | ︙ | |||
92 93 94 95 96 97 98 | return false; return true; } - (uint32_t)hash { | | | 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 | return false; return true; } - (uint32_t)hash { return _octetStringValue.hash; } - (OFString *)description { return [OFString stringWithFormat: @"<OFASN1OctetString: %@>", _octetStringValue]; } @end |
Modified src/OFASN1PrintableString.m from [4f4ed13270] to [24350e65d6].
︙ | ︙ | |||
34 35 36 37 38 39 40 | - (instancetype)initWithStringValue: (OFString *)stringValue { self = [super init]; @try { void *pool = objc_autoreleasePoolPush(); | | | | 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 | - (instancetype)initWithStringValue: (OFString *)stringValue { self = [super init]; @try { void *pool = objc_autoreleasePoolPush(); const char *cString = stringValue.UTF8String; size_t length = stringValue.UTF8StringLength; for (size_t i = 0; i < length; i++) { if (of_ascii_isalnum(cString[i])) continue; switch (cString[i]) { case ' ': |
︙ | ︙ | |||
85 86 87 88 89 90 91 | @try { if (tagClass != OF_ASN1_TAG_CLASS_UNIVERSAL || tagNumber != OF_ASN1_TAG_NUMBER_PRINTABLE_STRING || constructed) @throw [OFInvalidArgumentException exception]; | | | | | 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 | @try { if (tagClass != OF_ASN1_TAG_CLASS_UNIVERSAL || tagNumber != OF_ASN1_TAG_NUMBER_PRINTABLE_STRING || constructed) @throw [OFInvalidArgumentException exception]; if (DEREncodedContents.itemSize != 1) @throw [OFInvalidArgumentException exception]; printableStringValue = [OFString stringWithCString: DEREncodedContents.items encoding: OF_STRING_ENCODING_ASCII length: DEREncodedContents.count]; } @catch (id e) { [self release]; @throw e; } self = [self initWithStringValue: printableStringValue]; |
︙ | ︙ | |||
118 119 120 121 122 123 124 | [_printableStringValue release]; [super dealloc]; } - (OFString *)stringValue { | | | | 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 | [_printableStringValue release]; [super dealloc]; } - (OFString *)stringValue { return self.printableStringValue; } - (bool)isEqual: (id)object { OFASN1PrintableString *printableString; if (![object isKindOfClass: [OFASN1PrintableString class]]) return false; printableString = object; if (![printableString->_printableStringValue isEqual: _printableStringValue]) return false; return true; } - (uint32_t)hash { return _printableStringValue.hash; } - (OFString *)description { return [OFString stringWithFormat: @"<OFASN1PrintableString: %@>", _printableStringValue]; } @end |
Modified src/OFASN1UTF8String.m from [2624d9034c] to [5aca8e49db].
︙ | ︙ | |||
54 55 56 57 58 59 60 | OFString *UTF8StringValue; @try { if (tagClass != OF_ASN1_TAG_CLASS_UNIVERSAL || tagNumber != OF_ASN1_TAG_NUMBER_UTF8_STRING || constructed) @throw [OFInvalidArgumentException exception]; | | | | | 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 | OFString *UTF8StringValue; @try { if (tagClass != OF_ASN1_TAG_CLASS_UNIVERSAL || tagNumber != OF_ASN1_TAG_NUMBER_UTF8_STRING || constructed) @throw [OFInvalidArgumentException exception]; if (DEREncodedContents.itemSize != 1) @throw [OFInvalidArgumentException exception]; UTF8StringValue = [OFString stringWithUTF8String: DEREncodedContents.items length: DEREncodedContents.count]; } @catch (id e) { [self release]; @throw e; } self = [self initWithStringValue: UTF8StringValue]; |
︙ | ︙ | |||
86 87 88 89 90 91 92 | [_UTF8StringValue release]; [super dealloc]; } - (OFString *)stringValue { | | | | 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 | [_UTF8StringValue release]; [super dealloc]; } - (OFString *)stringValue { return self.UTF8StringValue; } - (bool)isEqual: (id)object { OFASN1UTF8String *UTF8String; if (![object isKindOfClass: [OFASN1UTF8String class]]) return false; UTF8String = object; if (![UTF8String->_UTF8StringValue isEqual: _UTF8StringValue]) return false; return true; } - (uint32_t)hash { return _UTF8StringValue.hash; } - (OFString *)description { return [OFString stringWithFormat: @"<OFASN1UTF8String: %@>", _UTF8StringValue]; } @end |
Modified src/OFASN1Value.m from [021fb1b137] to [826101f4aa].
︙ | ︙ | |||
44 45 46 47 48 49 50 | tagNumber: (of_asn1_tag_number_t)tagNumber constructed: (bool)constructed DEREncodedContents: (OFData *)DEREncodedContents { self = [super init]; @try { | | | 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 | tagNumber: (of_asn1_tag_number_t)tagNumber constructed: (bool)constructed DEREncodedContents: (OFData *)DEREncodedContents { self = [super init]; @try { if (DEREncodedContents.itemSize != 1) @throw [OFInvalidFormatException exception]; _tagClass = tagClass; _tagNumber = tagNumber; _constructed = constructed; _DEREncodedContents = [DEREncodedContents copy]; } @catch (id e) { |
︙ | ︙ | |||
101 102 103 104 105 106 107 | uint32_t hash; OF_HASH_INIT(hash); OF_HASH_ADD(hash, _tagClass & 0xFF); OF_HASH_ADD(hash, _tagNumber & 0xFF); OF_HASH_ADD(hash, _constructed); | | | | 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 | uint32_t hash; OF_HASH_INIT(hash); OF_HASH_ADD(hash, _tagClass & 0xFF); OF_HASH_ADD(hash, _tagNumber & 0xFF); OF_HASH_ADD(hash, _constructed); OF_HASH_ADD_HASH(hash, _DEREncodedContents.hash); OF_HASH_FINALIZE(hash); return hash; } - (OFString *)description { return [OFString stringWithFormat: @"<OFASN1Value:\n" @"\tTag class = %x\n" @"\tTag number = %x\n" @"\tConstructed = %u\n" @"\tDER-encoded contents = %@\n" @">", _tagClass, _tagNumber, _constructed, _DEREncodedContents.description]; } @end |
Modified src/OFApplication.m from [529b6d94bf] to [b702abe021].
︙ | ︙ | |||
94 95 96 97 98 99 100 | @end static OFApplication *app = nil; static void atexitHandler(void) { | | | 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 | @end static OFApplication *app = nil; static void atexitHandler(void) { id <OFApplicationDelegate> delegate = app.delegate; if ([delegate respondsToSelector: @selector(applicationWillTerminate)]) [delegate applicationWillTerminate]; [delegate release]; } |
︙ | ︙ | |||
143 144 145 146 147 148 149 | #ifdef OF_WINDOWS __wgetmainargs(&wargc, &wargv, &wenvp, _CRT_glob, &si); [app of_setArgumentCount: wargc andWideArgumentValues: wargv]; #endif | | | 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 | #ifdef OF_WINDOWS __wgetmainargs(&wargc, &wargv, &wenvp, _CRT_glob, &si); [app of_setArgumentCount: wargc andWideArgumentValues: wargv]; #endif app.delegate = delegate; [app of_run]; [delegate release]; return 0; } |
︙ | ︙ | |||
167 168 169 170 171 172 173 | + (OFApplication *)sharedApplication { return app; } + (OFString *)programName { | | | | | 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 | + (OFApplication *)sharedApplication { return app; } + (OFString *)programName { return app.programName; } + (OFArray *)arguments { return app.arguments; } + (OFDictionary *)environment { return app.environment; } + (void)terminate { [self terminateWithStatus: EXIT_SUCCESS]; OF_UNREACHABLE |
︙ | ︙ | |||
259 260 261 262 263 264 265 | fprintf(stderr, "Warning: Invalid environment " "variable: %s\n", [tmp UTF8String]); continue; } key = [tmp substringWithRange: of_range(0, pos)]; value = [tmp substringWithRange: | | | 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 | fprintf(stderr, "Warning: Invalid environment " "variable: %s\n", [tmp UTF8String]); continue; } key = [tmp substringWithRange: of_range(0, pos)]; value = [tmp substringWithRange: of_range(pos + 1, tmp.length - pos - 1)]; [_environment setObject: value forKey: key]; objc_autoreleasePoolPop(pool); } |
︙ | ︙ | |||
573 574 575 576 577 578 579 | objc_autoreleasePoolPop(pool); [runLoop run]; } - (void)terminate { | | | | | | | | | 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 | objc_autoreleasePoolPop(pool); [runLoop run]; } - (void)terminate { [self.class terminate]; OF_UNREACHABLE } - (void)terminateWithStatus: (int)status { [self.class terminateWithStatus: status]; OF_UNREACHABLE } #ifdef OF_HAVE_SANDBOX - (void)activateSandbox: (OFSandbox *)sandbox { # ifdef OF_HAVE_PLEDGE void *pool = objc_autoreleasePoolPush(); of_string_encoding_t encoding = [OFLocale encoding]; OFArray OF_GENERIC(of_sandbox_unveil_path_t) *unveiledPaths; size_t unveiledPathsCount; const char *promises; if (_activeSandbox != nil && sandbox != _activeSandbox) @throw [OFInvalidArgumentException exception]; unveiledPaths = sandbox.unveiledPaths; unveiledPathsCount = unveiledPaths.count; for (size_t i = sandbox->_unveiledPathsIndex; i < unveiledPathsCount; i++) { of_sandbox_unveil_path_t unveiledPath = [unveiledPaths objectAtIndex: i]; OFString *path = unveiledPath.firstObject; OFString *permissions = unveiledPath.secondObject; if (path == nil || permissions == nil) @throw [OFInvalidArgumentException exception]; unveil([path cStringWithEncoding: encoding], [permissions cStringWithEncoding: encoding]); } sandbox->_unveiledPathsIndex = unveiledPathsCount; promises = [sandbox.pledgeString cStringWithEncoding: encoding]; if (pledge(promises, NULL) != 0) @throw [OFSandboxActivationFailedException exceptionWithSandbox: sandbox errNo: errno]; objc_autoreleasePoolPop(pool); |
︙ | ︙ | |||
640 641 642 643 644 645 646 | # ifdef OF_HAVE_PLEDGE void *pool = objc_autoreleasePoolPush(); const char *promises; if (_activeExecSandbox != nil && sandbox != _activeExecSandbox) @throw [OFInvalidArgumentException exception]; | | | | 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 | # ifdef OF_HAVE_PLEDGE void *pool = objc_autoreleasePoolPush(); const char *promises; if (_activeExecSandbox != nil && sandbox != _activeExecSandbox) @throw [OFInvalidArgumentException exception]; if (sandbox.unveiledPaths.count != 0) @throw [OFInvalidArgumentException exception]; promises = [sandbox.pledgeString cStringWithEncoding: [OFLocale encoding]]; if (pledge(NULL, promises) != 0) @throw [OFSandboxActivationFailedException exceptionWithSandbox: sandbox errNo: errno]; |
︙ | ︙ |
Modified src/OFArray.m from [d06dd3fbb6] to [58353278e7].
︙ | ︙ | |||
240 241 242 243 244 245 246 | - (id const *)objects { OFObject *container; size_t count; id *buffer; container = [[[OFObject alloc] init] autorelease]; | | | | 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 | - (id const *)objects { OFObject *container; size_t count; id *buffer; container = [[[OFObject alloc] init] autorelease]; count = self.count; buffer = [container allocMemoryWithSize: sizeof(*buffer) count: count]; [self getObjects: buffer inRange: of_range(0, count)]; return buffer; } |
︙ | ︙ | |||
277 278 279 280 281 282 283 | - (id)valueForKey: (OFString *)key { id ret; if ([key hasPrefix: @"@"]) { void *pool = objc_autoreleasePoolPush(); | | | | 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 | - (id)valueForKey: (OFString *)key { id ret; if ([key hasPrefix: @"@"]) { void *pool = objc_autoreleasePoolPush(); key = [key substringWithRange: of_range(1, key.length - 1)]; ret = [[super valueForKey: key] retain]; objc_autoreleasePoolPop(pool); return [ret autorelease]; } ret = [OFMutableArray arrayWithCapacity: self.count]; for (id object in self) { id value = [object valueForKey: key]; if (value == nil) value = [OFNull null]; |
︙ | ︙ | |||
307 308 309 310 311 312 313 | - (void)setValue: (id)value forKey: (OFString *)key { if ([key hasPrefix: @"@"]) { void *pool = objc_autoreleasePoolPush(); | | | 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 | - (void)setValue: (id)value forKey: (OFString *)key { if ([key hasPrefix: @"@"]) { void *pool = objc_autoreleasePoolPush(); key = [key substringWithRange: of_range(1, key.length - 1)]; [super setValue: value forKey: key]; objc_autoreleasePoolPop(pool); return; } |
︙ | ︙ | |||
366 367 368 369 370 371 372 | - (bool)containsObjectIdenticalTo: (id)object { return ([self indexOfObjectIdenticalTo: object] != OF_NOT_FOUND); } - (id)firstObject { | | | | | 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 | - (bool)containsObjectIdenticalTo: (id)object { return ([self indexOfObjectIdenticalTo: object] != OF_NOT_FOUND); } - (id)firstObject { if (self.count > 0) return [self objectAtIndex: 0]; return nil; } - (id)lastObject { size_t count = self.count; if (count > 0) return [self objectAtIndex: count - 1]; return nil; } - (OFArray *)objectsInRange: (of_range_t)range { OFArray *ret; id *buffer; if (range.length > SIZE_MAX - range.location || range.location + range.length < self.count) @throw [OFOutOfRangeException exception]; if (![self isKindOfClass: [OFMutableArray class]]) return [OFArray_subarray arrayWithArray: self range: range]; buffer = [self allocMemoryWithSize: sizeof(*buffer) |
︙ | ︙ | |||
443 444 445 446 447 448 449 | options: (int)options { OFMutableString *ret; if (separator == nil) @throw [OFInvalidArgumentException exception]; | | | | | | 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 | options: (int)options { OFMutableString *ret; if (separator == nil) @throw [OFInvalidArgumentException exception]; if (self.count == 0) return @""; if (self.count == 1) { OFString *component = [[self firstObject] performSelector: selector]; if (component == nil) @throw [OFInvalidArgumentException exception]; return component; } ret = [OFMutableString string]; if (options & OF_ARRAY_SKIP_EMPTY) { for (id object in self) { void *pool = objc_autoreleasePoolPush(); OFString *component = [object performSelector: selector]; if (component == nil) @throw [OFInvalidArgumentException exception]; if (component.length > 0) { if (ret.length > 0) [ret appendString: separator]; [ret appendString: component]; } objc_autoreleasePoolPop(pool); } } else { |
︙ | ︙ | |||
516 517 518 519 520 521 522 | return true; if (![object isKindOfClass: [OFArray class]]) return false; otherArray = object; | | | | 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 | return true; if (![object isKindOfClass: [OFArray class]]) return false; otherArray = object; count = self.count; if (count != otherArray.count) return false; for (size_t i = 0; i < count; i++) if (![[self objectAtIndex: i] isEqual: [otherArray objectAtIndex: i]]) return false; |
︙ | ︙ | |||
548 549 550 551 552 553 554 | } - (OFString *)description { void *pool; OFMutableString *ret; | | | 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 | } - (OFString *)description { void *pool; OFMutableString *ret; if (self.count == 0) return @"()"; pool = objc_autoreleasePoolPush(); ret = [[self componentsJoinedByString: @",\n"] mutableCopy]; @try { [ret prependString: @"(\n"]; |
︙ | ︙ | |||
583 584 585 586 587 588 589 | if ([self isKindOfClass: [OFMutableArray class]]) element = [OFXMLElement elementWithName: @"OFMutableArray" namespace: OF_SERIALIZATION_NS]; else element = [OFXMLElement elementWithName: @"OFArray" namespace: OF_SERIALIZATION_NS]; | | | | 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 | if ([self isKindOfClass: [OFMutableArray class]]) element = [OFXMLElement elementWithName: @"OFMutableArray" namespace: OF_SERIALIZATION_NS]; else element = [OFXMLElement elementWithName: @"OFArray" namespace: OF_SERIALIZATION_NS]; for (id <OFSerialization> object in self) { void *pool2 = objc_autoreleasePoolPush(); [element addChild: object.XMLElementBySerializing]; objc_autoreleasePoolPop(pool2); } [element retain]; objc_autoreleasePoolPop(pool); |
︙ | ︙ | |||
615 616 617 618 619 620 621 | } - (OFString *)of_JSONRepresentationWithOptions: (int)options depth: (size_t)depth { OFMutableString *JSON = [OFMutableString stringWithString: @"["]; void *pool = objc_autoreleasePoolPush(); | | | 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 | } - (OFString *)of_JSONRepresentationWithOptions: (int)options depth: (size_t)depth { OFMutableString *JSON = [OFMutableString stringWithString: @"["]; void *pool = objc_autoreleasePoolPush(); size_t i, count = self.count; if (options & OF_JSON_REPRESENTATION_PRETTY) { OFMutableString *indentation = [OFMutableString string]; for (i = 0; i < depth; i++) [indentation appendString: @"\t"]; |
︙ | ︙ | |||
675 676 677 678 679 680 681 | - (OFData *)messagePackRepresentation { OFMutableData *data; size_t i, count; void *pool; data = [OFMutableData data]; | | | 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 | - (OFData *)messagePackRepresentation { OFMutableData *data; size_t i, count; void *pool; data = [OFMutableData data]; count = self.count; if (count <= 15) { uint8_t tmp = 0x90 | ((uint8_t)count & 0xF); [data addItem: &tmp]; } else if (count <= UINT16_MAX) { uint8_t type = 0xDC; uint16_t tmp = OF_BSWAP16_IF_LE((uint16_t)count); |
︙ | ︙ | |||
707 708 709 710 711 712 713 | for (id object in self) { void *pool2 = objc_autoreleasePoolPush(); OFData *child; i++; child = [object messagePackRepresentation]; | | | | 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 | for (id object in self) { void *pool2 = objc_autoreleasePoolPush(); OFData *child; i++; child = [object messagePackRepresentation]; [data addItems: child.items count: child.count]; objc_autoreleasePoolPop(pool2); } assert(i == count); [data makeImmutable]; |
︙ | ︙ | |||
795 796 797 798 799 800 801 | count: (int)count { of_range_t range = of_range(state->state, count); if (range.length > SIZE_MAX - range.location) @throw [OFOutOfRangeException exception]; | | | | 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 | count: (int)count { of_range_t range = of_range(state->state, count); if (range.length > SIZE_MAX - range.location) @throw [OFOutOfRangeException exception]; if (range.location + range.length > self.count) range.length = self.count - range.location; [self getObjects: objects inRange: range]; if (range.location + range.length > ULONG_MAX) @throw [OFOutOfRangeException exception]; |
︙ | ︙ | |||
871 872 873 874 875 876 877 | return ret; } #ifdef OF_HAVE_BLOCKS - (OFArray *)mappedArrayUsingBlock: (of_array_map_block_t)block { OFArray *ret; | | | 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 | return ret; } #ifdef OF_HAVE_BLOCKS - (OFArray *)mappedArrayUsingBlock: (of_array_map_block_t)block { OFArray *ret; size_t count = self.count; id *tmp = [self allocMemoryWithSize: sizeof(id) count: count]; @try { [self enumerateObjectsUsingBlock: ^ (id object, size_t idx, bool *stop) { tmp[idx] = block(object, idx); |
︙ | ︙ | |||
893 894 895 896 897 898 899 | return ret; } - (OFArray *)filteredArrayUsingBlock: (of_array_filter_block_t)block { OFArray *ret; | | | 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 | return ret; } - (OFArray *)filteredArrayUsingBlock: (of_array_filter_block_t)block { OFArray *ret; size_t count = self.count; id *tmp = [self allocMemoryWithSize: sizeof(id) count: count]; @try { __block size_t i = 0; [self enumerateObjectsUsingBlock: ^ (id object, size_t idx, |
︙ | ︙ | |||
917 918 919 920 921 922 923 | } return ret; } - (id)foldUsingBlock: (of_array_fold_block_t)block { | | | 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 | } return ret; } - (id)foldUsingBlock: (of_array_fold_block_t)block { size_t count = self.count; __block id current; if (count == 0) return nil; if (count == 1) return [[[self firstObject] retain] autorelease]; |
︙ | ︙ |
Modified src/OFArray_adjacent.m from [6816050f97] to [8d3e15f3ea].
︙ | ︙ | |||
93 94 95 96 97 98 99 | self = [super init]; if (array == nil) return self; @try { | | | | 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 | 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; } |
︙ | ︙ | |||
162 163 164 165 166 167 168 | - (instancetype)initWithSerialization: (OFXMLElement *)element { self = [self init]; @try { void *pool = objc_autoreleasePoolPush(); | | | | | | | | | | | | | | | | | | 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 | - (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 [OFArray_adjacentSubarray arrayWithArray: self range: range]; } - (bool)isEqual: (id)object |
︙ | ︙ | |||
289 290 291 292 293 294 295 | if (![object isKindOfClass: [OFArray_adjacent class]] && ![object isKindOfClass: [OFMutableArray_adjacent class]]) return [super isEqual: object]; otherArray = object; | | | | | | | | | | | | | | 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 | if (![object isKindOfClass: [OFArray_adjacent class]] && ![object isKindOfClass: [OFMutableArray_adjacent 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 |
Modified src/OFArray_adjacentSubarray.m from [3bce39d414] to [71c6741d2d].
︙ | ︙ | |||
20 21 22 23 24 25 26 | #import "OFArray_adjacentSubarray.h" #import "OFArray_adjacent.h" #import "OFMutableArray_adjacent.h" @implementation OFArray_adjacentSubarray - (const id *)objects { | | | | | | | 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 | #import "OFArray_adjacentSubarray.h" #import "OFArray_adjacent.h" #import "OFMutableArray_adjacent.h" @implementation OFArray_adjacentSubarray - (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: [OFArray_adjacent class]] && ![object isKindOfClass: [OFMutableArray_adjacent 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/OFCharacterSet_bitset.m from [98690aa9bb] to [37fa197eff].
︙ | ︙ | |||
30 31 32 33 34 35 36 | - (instancetype)initWithCharactersInString: (OFString *)string { self = [super init]; @try { void *pool = objc_autoreleasePoolPush(); | | | | 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | - (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; |
︙ | ︙ |
Modified src/OFCondition.m from [7f0b7083ad] to [42e8f34c96].
︙ | ︙ | |||
33 34 35 36 37 38 39 | } - (instancetype)init { self = [super init]; if (!of_condition_new(&_condition)) { | | | 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | } - (instancetype)init { self = [super init]; if (!of_condition_new(&_condition)) { Class c = self.class; [self release]; @throw [OFInitializationFailedException exceptionWithClass: c]; } _conditionInitialized = true; return self; |
︙ | ︙ | |||
68 69 70 71 72 73 74 | { return of_condition_timed_wait(&_condition, &_mutex, timeInterval); } - (bool)waitUntilDate: (OFDate *)date { return of_condition_timed_wait(&_condition, &_mutex, | | | 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 | { return of_condition_timed_wait(&_condition, &_mutex, timeInterval); } - (bool)waitUntilDate: (OFDate *)date { return of_condition_timed_wait(&_condition, &_mutex, date.timeIntervalSinceNow); } - (void)signal { if (!of_condition_signal(&_condition)) @throw [OFConditionSignalFailedException exceptionWithCondition: self]; |
︙ | ︙ |
Modified src/OFConstantString.m from [e40123b4c3] to [299aa74c88].
︙ | ︙ | |||
260 261 262 263 264 265 266 | return [self isEqual: object]; } - (uint32_t)hash { [self finishInitialization]; | | | | | 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 | return [self isEqual: object]; } - (uint32_t)hash { [self finishInitialization]; return self.hash; } - (OFString *)description { [self finishInitialization]; return self.description; } /* From OFString */ - (const char *)UTF8String { [self finishInitialization]; return self.UTF8String; } - (size_t)getCString: (char *)cString_ maxLength: (size_t)maxLength encoding: (of_string_encoding_t)encoding { [self finishInitialization]; |
︙ | ︙ | |||
300 301 302 303 304 305 306 | return [self cStringWithEncoding: encoding]; } - (size_t)length { [self finishInitialization]; | | | | 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 | return [self cStringWithEncoding: encoding]; } - (size_t)length { [self finishInitialization]; return self.length; } - (size_t)UTF8StringLength { [self finishInitialization]; return self.UTF8StringLength; } - (size_t)cStringLengthWithEncoding: (of_string_encoding_t)encoding { [self finishInitialization]; return [self cStringLengthWithEncoding: encoding]; |
︙ | ︙ | |||
464 465 466 467 468 469 470 | range: range]; } - (OFString *)uppercaseString { [self finishInitialization]; | | | | | | | | 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 | range: range]; } - (OFString *)uppercaseString { [self finishInitialization]; return self.uppercaseString; } - (OFString *)lowercaseString { [self finishInitialization]; return self.lowercaseString; } - (OFString *)capitalizedString { [self finishInitialization]; return self.capitalizedString; } - (OFString *)stringByDeletingLeadingWhitespaces { [self finishInitialization]; return self.stringByDeletingLeadingWhitespaces; } - (OFString *)stringByDeletingTrailingWhitespaces { [self finishInitialization]; return self.stringByDeletingTrailingWhitespaces; } - (OFString *)stringByDeletingEnclosingWhitespaces { [self finishInitialization]; return self.stringByDeletingEnclosingWhitespaces; } - (bool)hasPrefix: (OFString *)prefix { [self finishInitialization]; return [self hasPrefix: prefix]; |
︙ | ︙ | |||
554 555 556 557 558 559 560 | options: options]; } - (OFArray *)pathComponents { [self finishInitialization]; | | | | | | | | | | | | | | 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 | options: options]; } - (OFArray *)pathComponents { [self finishInitialization]; return self.pathComponents; } - (OFString *)lastPathComponent { [self finishInitialization]; return self.lastPathComponent; } - (OFString *)stringByDeletingLastPathComponent { [self finishInitialization]; return self.stringByDeletingLastPathComponent; } - (intmax_t)decimalValue { [self finishInitialization]; return self.decimalValue; } - (uintmax_t)hexadecimalValue { [self finishInitialization]; return self.hexadecimalValue; } - (uintmax_t)octalValue { [self finishInitialization]; return self.octalValue; } - (float)floatValue { [self finishInitialization]; return self.floatValue; } - (double)doubleValue { [self finishInitialization]; return self.doubleValue; } - (const of_unichar_t *)characters { [self finishInitialization]; return self.characters; } - (const of_char16_t *)UTF16String { [self finishInitialization]; return self.UTF16String; } - (const of_char16_t *)UTF16StringWithByteOrder: (of_byte_order_t)byteOrder { [self finishInitialization]; return [self UTF16StringWithByteOrder: byteOrder]; } - (size_t)UTF16StringLength { [self finishInitialization]; return self.UTF16StringLength; } - (const of_char32_t *)UTF32String { [self finishInitialization]; return self.UTF32String; } - (const of_char32_t *)UTF32StringWithByteOrder: (of_byte_order_t)byteOrder { [self finishInitialization]; return [self UTF32StringWithByteOrder: byteOrder]; |
︙ | ︙ | |||
660 661 662 663 664 665 666 | } #ifdef OF_HAVE_UNICODE_TABLES - (OFString *)decomposedStringWithCanonicalMapping { [self finishInitialization]; | | | | 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 | } #ifdef OF_HAVE_UNICODE_TABLES - (OFString *)decomposedStringWithCanonicalMapping { [self finishInitialization]; return self.decomposedStringWithCanonicalMapping; } - (OFString *)decomposedStringWithCompatibilityMapping { [self finishInitialization]; return self.decomposedStringWithCompatibilityMapping; } #endif #ifdef OF_HAVE_FILES - (void)writeToFile: (OFString *)path { [self finishInitialization]; |
︙ | ︙ |
Modified src/OFCountedSet.m from [beddf34789] to [d7f89e4f31].
︙ | ︙ | |||
137 138 139 140 141 142 143 | OF_UNRECOGNIZED_SELECTOR } - (OFString *)description { OFMutableString *ret; void *pool; | | | 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 | OF_UNRECOGNIZED_SELECTOR } - (OFString *)description { OFMutableString *ret; void *pool; size_t i, count = self.count; if (count == 0) return @"{()}"; ret = [OFMutableString stringWithString: @"{(\n"]; pool = objc_autoreleasePoolPush(); |
︙ | ︙ | |||
202 203 204 205 206 207 208 | [self countForObject: object]]; objectElement = [OFXMLElement elementWithName: @"object" namespace: OF_SERIALIZATION_NS]; [objectElement addAttributeWithName: @"count" stringValue: count]; | | | 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 | [self countForObject: object]]; objectElement = [OFXMLElement elementWithName: @"object" namespace: OF_SERIALIZATION_NS]; [objectElement addAttributeWithName: @"count" stringValue: count]; [objectElement addChild: object.XMLElementBySerializing]; [element addChild: objectElement]; objc_autoreleasePoolPop(pool2); } [element retain]; |
︙ | ︙ |
Modified src/OFCountedSet_hashtable.m from [6969402f59] to [73078b5bc4].
︙ | ︙ | |||
68 69 70 71 72 73 74 | } - (instancetype)initWithArray: (OFArray *)array { self = [self init]; @try { | | | | 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 | } - (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; } |
︙ | ︙ | |||
124 125 126 127 128 129 130 | - (instancetype)initWithSerialization: (OFXMLElement *)element { self = [self init]; @try { void *pool = objc_autoreleasePoolPush(); | | | | | | | | 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 | - (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.stringValue.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]; |
︙ | ︙ |
Modified src/OFDNSResolver.m from [2303b7b240] to [b26d10f3a6].
︙ | ︙ | |||
195 196 197 198 199 200 201 | recursion: (unsigned int)recursion result: (OFMutableArray *)result; - (void)resolver: (OFDNSResolver *)resolver didResolveCNAME: (OFString *)CNAME answerRecords: (OFDictionary *)answerRecords authorityRecords: (OFDictionary *)authorityRecords additionalRecords: (OFDictionary *)additionalRecords | | | | 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 | recursion: (unsigned int)recursion result: (OFMutableArray *)result; - (void)resolver: (OFDNSResolver *)resolver didResolveCNAME: (OFString *)CNAME answerRecords: (OFDictionary *)answerRecords authorityRecords: (OFDictionary *)authorityRecords additionalRecords: (OFDictionary *)additionalRecords context: (OFNumber *)context exception: (id)exception; - (void)done; - (void)resolver: (OFDNSResolver *)resolver didResolveDomainName: (OFString *)domainName answerRecords: (OFDictionary *)answerRecords authorityRecords: (OFDictionary *)authorityRecords additionalRecords: (OFDictionary *)additionalRecords context: (OFNumber *)context exception: (id)exception; @end @interface OFDNSResolver_ResolveSocketAddressesDelegate: OFObject <OFDNSResolverDelegate> { @public |
︙ | ︙ | |||
288 289 290 291 292 293 294 | /* Not an IP address -> we can use it if it contains a dot. */ size_t pos = [domain rangeOfString: @"."].location; if (pos == OF_NOT_FOUND) return nil; return [domain substringWithRange: | | | | | 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 | /* Not an IP address -> we can use it if it contains a dot. */ size_t pos = [domain rangeOfString: @"."].location; if (pos == OF_NOT_FOUND) return nil; return [domain substringWithRange: of_range(pos + 1, domain.length - pos - 1)]; } } #endif static bool isFQDN(OFString *host, OFDNSResolverSettings *settings) { const char *UTF8String = host.UTF8String; size_t length = host.UTF8StringLength; unsigned int dots = 0; if ([host hasSuffix: @"."]) return true; for (size_t i = 0; i < length; i++) if (UTF8String[i] == '.') |
︙ | ︙ | |||
367 368 369 370 371 372 373 | /* Pointing to itself?! */ @throw [OFInvalidServerReplyException exception]; suffix = parseName(buffer, length, &j, pointerLevel - 1); | | | 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 | /* Pointing to itself?! */ @throw [OFInvalidServerReplyException exception]; suffix = parseName(buffer, length, &j, pointerLevel - 1); if (components.count == 0) return suffix; else { [components addObject: suffix]; return [components componentsJoinedByString: @"."]; } } |
︙ | ︙ | |||
757 758 759 760 761 762 763 | _selector = selector; _context = [context retain]; queryData = [OFMutableData dataWithCapacity: 512]; /* Header */ | | | 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 | _selector = selector; _context = [context retain]; queryData = [OFMutableData dataWithCapacity: 512]; /* Header */ tmp = OF_BSWAP16_IF_LE(ID.uInt16Value); [queryData addItems: &tmp count: 2]; /* RD */ tmp = OF_BSWAP16_IF_LE(1 << 8); [queryData addItems: &tmp count: 2]; |
︙ | ︙ | |||
779 780 781 782 783 784 785 | [queryData increaseCountBy: 6]; /* Question */ /* QNAME */ for (OFString *component in [domainName componentsSeparatedByString: @"."]) { | | | | | 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 | [queryData increaseCountBy: 6]; /* Question */ /* QNAME */ for (OFString *component in [domainName componentsSeparatedByString: @"."]) { size_t length = component.UTF8StringLength; uint8_t length8; if (length > 63 || queryData.count + length > 512) @throw [OFOutOfRangeException exception]; length8 = (uint8_t)length; [queryData addItem: &length8]; [queryData addItems: component.UTF8String count: length]; } /* QTYPE */ tmp = OF_BSWAP16_IF_LE(recordType); [queryData addItems: &tmp count: 2]; |
︙ | ︙ | |||
868 869 870 871 872 873 874 | additionalRecords: (OFDictionary *)additionalRecords recordType: (of_dns_resource_record_type_t)recordType recursion: (unsigned int)recursion result: (OFMutableArray *)result { bool found = false; | | | | | | | | 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 | additionalRecords: (OFDictionary *)additionalRecords recordType: (of_dns_resource_record_type_t)recordType recursion: (unsigned int)recursion result: (OFMutableArray *)result { bool found = false; for (OFDNSResourceRecord *record in records) { if (record.recordClass != OF_DNS_RESOURCE_RECORD_CLASS_IN) continue; if (record.recordType == recordType) { [result addObject: record]; found = true; } else if (record.recordType == OF_DNS_RESOURCE_RECORD_TYPE_CNAME) { [self resolveCNAME: (OFCNAMEDNSResourceRecord *)record answerRecords: answerRecords additionalRecords: additionalRecords recordType: recordType recursion: recursion result: result]; found = true; } } return found; } - (void)resolveCNAME: (OFCNAMEDNSResourceRecord *)CNAME answerRecords: (OFDictionary *)answerRecords additionalRecords: (OFDictionary *)additionalRecords recordType: (of_dns_resource_record_type_t)recordType recursion: (unsigned int)recursion result: (OFMutableArray *)result { OFString *alias = CNAME.alias; bool found = false; if (recursion == 0) return; if ([self parseRecords: [answerRecords objectForKey: alias] answerRecords: answerRecords |
︙ | ︙ | |||
921 922 923 924 925 926 927 | recordType: recordType recursion: recursion - 1 result: result]) found = true; if (!found) { of_run_loop_mode_t runLoopMode = | | | 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 | recordType: recordType recursion: recursion - 1 result: result]) found = true; if (!found) { of_run_loop_mode_t runLoopMode = [OFRunLoop currentRunLoop].currentMode; OFNumber *recordTypeNumber = [OFNumber numberWithInt: recordType]; _expectedResponses++; [result addObject: [OFPair pairWithFirstObject: CNAME |
︙ | ︙ | |||
951 952 953 954 955 956 957 | } - (void)resolver: (OFDNSResolver *)resolver didResolveCNAME: (OFString *)CNAME answerRecords: (OFDictionary *)answerRecords authorityRecords: (OFDictionary *)authorityRecords additionalRecords: (OFDictionary *)additionalRecords | | | | 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 | } - (void)resolver: (OFDNSResolver *)resolver didResolveCNAME: (OFString *)CNAME answerRecords: (OFDictionary *)answerRecords authorityRecords: (OFDictionary *)authorityRecords additionalRecords: (OFDictionary *)additionalRecords context: (OFNumber *)context exception: (id)exception { /* * TODO: Error handling could be improved. Ignore error if there are * responses, otherwise propagate error. */ of_dns_resource_record_type_t recordType = context.unsignedIntValue; bool found = false; OFMutableArray *records; size_t count; OF_ENSURE(resolver == _resolver); _expectedResponses--; |
︙ | ︙ | |||
1000 1001 1002 1003 1004 1005 1006 | if (!found) { if (_expectedResponses == 0) [self done]; return; } | | | | 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 | if (!found) { if (_expectedResponses == 0) [self done]; return; } count = _records.count; for (size_t i = 0; i < count; i++) { id object = [_records objectAtIndex: i]; if (![object isKindOfClass: [OFPair class]]) continue; if (![[[object firstObject] alias] isEqual: CNAME]) continue; if ([[object secondObject] unsignedIntValue] != recordType) continue; [_records removeObjectAtIndex: i]; [_records insertObjectsFromArray: records atIndex: i]; i += records.count - 1; } if (_expectedResponses == 0) [self done]; } - (void)done |
︙ | ︙ | |||
1045 1046 1047 1048 1049 1050 1051 | default: break; } } [addresses makeImmutable]; | | | | | 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 | default: break; } } [addresses makeImmutable]; if (addresses.count == 0) exception = [OFResolveHostFailedException exceptionWithHost: _host recordClass: OF_DNS_RESOURCE_RECORD_CLASS_IN recordType: 0 error: OF_DNS_RESOLVER_ERROR_UNKNOWN]; if ([_delegate respondsToSelector: @selector( resolver:didResolveDomainName:socketAddresses:exception:)]) [_delegate resolver: _resolver didResolveDomainName: _domainName socketAddresses: (exception == nil ? addresses : nil) exception: exception]; } - (void)resolver: (OFDNSResolver *)resolver didResolveDomainName: (OFString *)domainName answerRecords: (OFDictionary *)answerRecords authorityRecords: (OFDictionary *)authorityRecords additionalRecords: (OFDictionary *)additionalRecords context: (OFNumber *)context exception: (id)exception { /* * TODO: Error handling could be improved. Ignore error if there are * responses, otherwise propagate error. */ of_dns_resource_record_type_t recordType = context.unsignedIntValue; if (_resolver != nil) OF_ENSURE(resolver == _resolver); else _resolver = [resolver retain]; _expectedResponses--; |
︙ | ︙ | |||
1313 1314 1315 1316 1317 1318 1319 | if (pos != OF_NOT_FOUND) line = [line substringWithRange: of_range(0, pos)]; components = [line componentsSeparatedByCharactersInSet: whitespaceCharacterSet options: OF_STRING_SKIP_EMPTY]; | | | | | 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 | if (pos != OF_NOT_FOUND) line = [line substringWithRange: of_range(0, pos)]; components = [line componentsSeparatedByCharactersInSet: whitespaceCharacterSet options: OF_STRING_SKIP_EMPTY]; if (components.count < 2) { objc_autoreleasePoolPop(pool2); continue; } address = components.firstObject; hosts = [components objectsInRange: of_range(1, components.count - 1)]; for (OFString *host in hosts) { addresses = [staticHosts objectForKey: host]; if (addresses == nil) { addresses = [OFMutableArray array]; [staticHosts setObject: addresses |
︙ | ︙ | |||
1386 1387 1388 1389 1390 1391 1392 | if (pos != OF_NOT_FOUND) line = [line substringWithRange: of_range(0, pos)]; components = [line componentsSeparatedByCharactersInSet: whitespaceCharacterSet options: OF_STRING_SKIP_EMPTY]; | | | | | | | | 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 | if (pos != OF_NOT_FOUND) line = [line substringWithRange: of_range(0, pos)]; components = [line componentsSeparatedByCharactersInSet: whitespaceCharacterSet options: OF_STRING_SKIP_EMPTY]; if (components.count < 2) { objc_autoreleasePoolPop(pool2); continue; } option = components.firstObject; arguments = [components objectsInRange: of_range(1, components.count - 1)]; if ([option isEqual: @"nameserver"]) { if (arguments.count != 1) { objc_autoreleasePoolPop(pool2); continue; } [nameServers addObject: [arguments firstObject]]; } else if ([option isEqual: @"domain"]) { if (arguments.count != 1) { objc_autoreleasePoolPop(pool2); continue; } [_localDomain release]; _localDomain = [arguments.firstObject copy]; } else if ([option isEqual: @"search"]) { [_searchDomains release]; _searchDomains = [arguments copy]; } else if ([option isEqual: @"options"]) for (OFString *argument in arguments) [self of_parseResolvConfOption: argument]; |
︙ | ︙ | |||
1433 1434 1435 1436 1437 1438 1439 | } - (void)of_parseResolvConfOption: (OFString *)option { @try { if ([option hasPrefix: @"ndots:"]) { option = [option substringWithRange: | | | | | | | | | | 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 | } - (void)of_parseResolvConfOption: (OFString *)option { @try { if ([option hasPrefix: @"ndots:"]) { option = [option substringWithRange: of_range(6, option.length - 6)]; _minNumberOfDotsInAbsoluteName = (unsigned int)option.decimalValue; } else if ([option hasPrefix: @"timeout:"]) { option = [option substringWithRange: of_range(8, option.length - 8)]; _timeout = option.decimalValue; } else if ([option hasPrefix: @"attempts:"]) { option = [option substringWithRange: of_range(9, option.length - 9)]; _maxAttempts = (unsigned int)option.decimalValue; } else if ([option hasPrefix: @"reload-period:"]) { option = [option substringWithRange: of_range(14, option.length - 14)]; _configReloadInterval = option.decimalValue; } else if ([option isEqual: @"tcp"]) _usesTCP = true; } @catch (OFInvalidFormatException *e) { } } # endif #endif |
︙ | ︙ | |||
1484 1485 1486 1487 1488 1489 1490 | nameServers = [OFMutableArray array]; for (iter = &fixedInfo->DnsServerList; iter != NULL; iter = iter->Next) [nameServers addObject: [OFString stringWithCString: iter->IpAddress.String encoding: encoding]]; | | | 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 | nameServers = [OFMutableArray array]; for (iter = &fixedInfo->DnsServerList; iter != NULL; iter = iter->Next) [nameServers addObject: [OFString stringWithCString: iter->IpAddress.String encoding: encoding]]; if (nameServers.count > 0) { [nameServers makeImmutable]; _nameServers = [nameServers copy]; } if (fixedInfo->DomainName[0] != '\0') _localDomain = [[OFString alloc] initWithCString: fixedInfo->DomainName |
︙ | ︙ | |||
1528 1529 1530 1531 1532 1533 1534 | iter = (struct DomainNameServerNode *) iter->dnsn_MinNode.mln_Succ; } } @finally { ReleaseDomainNameServerList(nameServerList); } | | | 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 | iter = (struct DomainNameServerNode *) iter->dnsn_MinNode.mln_Succ; } } @finally { ReleaseDomainNameServerList(nameServerList); } if (nameServers.count > 0) { [nameServers makeImmutable]; _nameServers = [nameServers copy]; } if (GetDefaultDomainName(buffer, sizeof(buffer))) _localDomain = [[OFString alloc] initWithCString: buffer encoding: encoding]; |
︙ | ︙ | |||
1575 1576 1577 1578 1579 1580 1581 | continue; [nameServers addObject: [OFString stringWithFormat: @"%u.%u.%u.%u", (ip >> 24) & 0xFF, (ip >> 16) & 0xFF, (ip >> 8) & 0xFF, ip & 0xFF]]; } | | | | 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 | continue; [nameServers addObject: [OFString stringWithFormat: @"%u.%u.%u.%u", (ip >> 24) & 0xFF, (ip >> 16) & 0xFF, (ip >> 8) & 0xFF, ip & 0xFF]]; } if (nameServers.count > 0) { [nameServers makeImmutable]; _nameServers = [nameServers copy]; } } #endif - (void)of_reloadSystemConfig { /* * TODO: Rather than reparsing every, check what actually changed * (mtime) and only reset those. */ if (_lastConfigReload != nil && _configReloadInterval > 0 && _lastConfigReload.timeIntervalSinceNow < _configReloadInterval) return; [_staticHosts release]; _staticHosts = nil; [_nameServers release]; _nameServers = nil; |
︙ | ︙ | |||
1649 1650 1651 1652 1653 1654 1655 | OFString *searchDomain = [settings->_searchDomains objectAtIndex: searchDomainsIndex]; domainName = [OFString stringWithFormat: @"%@.%@.", host, searchDomain]; } | | | 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 | OFString *searchDomain = [settings->_searchDomains objectAtIndex: searchDomainsIndex]; domainName = [OFString stringWithFormat: @"%@.%@.", host, searchDomain]; } if (domainName.UTF8StringLength > 253) @throw [OFOutOfRangeException exception]; query = [[[OFDNSResolverQuery alloc] initWithHost: host domainName: domainName recordClass: recordClass recordType: recordType |
︙ | ︙ | |||
1804 1805 1806 1807 1808 1809 1810 | if (_IPv6Socket == nil) { of_socket_address_t address = of_socket_address_parse_ip(@"::", 0); _IPv6Socket = [[OFUDPSocket alloc] init]; [_IPv6Socket of_bindToAddress: &address extraType: SOCK_DNS]; | | | | | | 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 | if (_IPv6Socket == nil) { of_socket_address_t address = of_socket_address_parse_ip(@"::", 0); _IPv6Socket = [[OFUDPSocket alloc] init]; [_IPv6Socket of_bindToAddress: &address extraType: SOCK_DNS]; _IPv6Socket.blocking = false; _IPv6Socket.delegate = self; [_IPv6Socket asyncReceiveIntoBuffer: _buffer length: BUFFER_LENGTH]; } sock = _IPv6Socket; break; #endif case OF_SOCKET_ADDRESS_FAMILY_IPV4: if (_IPv4Socket == nil) { of_socket_address_t address = of_socket_address_parse_ip(@"0.0.0.0", 0); _IPv4Socket = [[OFUDPSocket alloc] init]; [_IPv4Socket of_bindToAddress: &address extraType: SOCK_DNS]; _IPv4Socket.blocking = false; _IPv4Socket.delegate = self; [_IPv4Socket asyncReceiveIntoBuffer: _buffer length: BUFFER_LENGTH]; } sock = _IPv4Socket; break; default: |
︙ | ︙ | |||
1846 1847 1848 1849 1850 1851 1852 | { OFResolveHostFailedException *exception; if (query == nil) return; if (query->_nameServersIndex + 1 < | | | | | 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 | { OFResolveHostFailedException *exception; if (query == nil) return; if (query->_nameServersIndex + 1 < query->_settings->_nameServers.count) { query->_nameServersIndex++; [self of_sendQuery: query runLoopMode: [OFRunLoop currentRunLoop].currentMode]; return; } if (query->_attempt < query->_settings->_maxAttempts) { query->_attempt++; query->_nameServersIndex = 0; [self of_sendQuery: query runLoopMode: [OFRunLoop currentRunLoop].currentMode]; return; } query = [[query retain] autorelease]; [_queries removeObjectForKey: query->_ID]; /* |
︙ | ︙ | |||
1887 1888 1889 1890 1891 1892 1893 | recordType: query->_recordType error: OF_DNS_RESOLVER_ERROR_TIMEOUT]; callback(query->_target, query->_selector, self, query->_domainName, nil, nil, nil, query->_context, exception); } | | | 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 | recordType: query->_recordType error: OF_DNS_RESOLVER_ERROR_TIMEOUT]; callback(query->_target, query->_selector, self, query->_domainName, nil, nil, nil, query->_context, exception); } - (bool)socket: (OFUDPSocket *)sock didReceiveIntoBuffer: (void *)buffer_ length: (size_t)length sender: (const of_socket_address_t *)sender exception: (id)exception { unsigned char *buffer = buffer_; OFDictionary *answerRecords = nil, *authorityRecords = nil; |
︙ | ︙ | |||
1930 1931 1932 1933 1934 1935 1936 | of_dns_resolver_error_t error; uint16_t numQuestions, numAnswers, numAuthorityRecords; uint16_t numAdditionalRecords; if (length < 12) @throw [OFTruncatedDataException exception]; | | | | | 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 | of_dns_resolver_error_t error; uint16_t numQuestions, numAnswers, numAuthorityRecords; uint16_t numAdditionalRecords; if (length < 12) @throw [OFTruncatedDataException exception]; if (query->_queryData.itemSize != 1 || query->_queryData.count < 12) @throw [OFInvalidArgumentException exception]; queryDataBuffer = query->_queryData.items; /* QR */ if ((buffer[2] & 0x80) == 0) @throw [OFInvalidServerReplyException exception]; /* Opcode */ if ((buffer[2] & 0x78) != (queryDataBuffer[2] & 0x78)) |
︙ | ︙ | |||
1960 1961 1962 1963 1964 1965 1966 | error = OF_DNS_RESOLVER_ERROR_SERVER_INVALID_FORMAT; break; case 2: error = OF_DNS_RESOLVER_ERROR_SERVER_FAILURE; break; case 3: if (query->_searchDomainsIndex + 1 < | | | | 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 | error = OF_DNS_RESOLVER_ERROR_SERVER_INVALID_FORMAT; break; case 2: error = OF_DNS_RESOLVER_ERROR_SERVER_FAILURE; break; case 3: if (query->_searchDomainsIndex + 1 < query->_settings->_searchDomains.count) { of_run_loop_mode_t runLoopMode = [OFRunLoop currentRunLoop].currentMode; query->_searchDomainsIndex++; [self of_resolveHost: query->_host recordClass: query->_recordClass recordType: query->_recordType settings: query->_settings |
︙ | ︙ | |||
2125 2126 2127 2128 2129 2130 2131 | continue; [addresses addItem: &address]; } [addresses makeImmutable]; | | | 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 | continue; [addresses addItem: &address]; } [addresses makeImmutable]; if (addresses.count == 0) { of_dns_resource_record_type_t recordType = 0; addresses = nil; switch (addressFamily) { case OF_SOCKET_ADDRESS_FAMILY_ANY: recordType = OF_DNS_RESOURCE_RECORD_TYPE_ALL; |
︙ | ︙ |
Modified src/OFDNSResourceRecord.m from [46064a3180] to [b77a7c0c09].
︙ | ︙ | |||
72 73 74 75 76 77 78 | of_dns_resource_record_class_t of_dns_resource_record_class_parse( OFString *string) { void *pool = objc_autoreleasePoolPush(); of_dns_resource_record_class_t recordClass; | | | | 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 | of_dns_resource_record_class_t of_dns_resource_record_class_parse( OFString *string) { void *pool = objc_autoreleasePoolPush(); of_dns_resource_record_class_t recordClass; string = string.uppercaseString; if ([string isEqual: @"IN"]) recordClass = OF_DNS_RESOURCE_RECORD_CLASS_IN; else @throw [OFInvalidArgumentException exception]; objc_autoreleasePoolPop(pool); return recordClass; } of_dns_resource_record_type_t of_dns_resource_record_type_parse( OFString *string) { void *pool = objc_autoreleasePoolPush(); of_dns_resource_record_type_t recordType; string = string.uppercaseString; if ([string isEqual: @"A"]) recordType = OF_DNS_RESOURCE_RECORD_TYPE_A; else if ([string isEqual: @"NS"]) recordType = OF_DNS_RESOURCE_RECORD_TYPE_NS; else if ([string isEqual: @"CNAME"]) recordType = OF_DNS_RESOURCE_RECORD_TYPE_CNAME; |
︙ | ︙ | |||
167 168 169 170 171 172 173 | return [OFString stringWithFormat: @"<%@:\n" @"\tName = %@\n" @"\tClass = %@\n" @"\tType = %@\n" @"\tTTL = %" PRIu32 "\n" @">", | | | 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 | return [OFString stringWithFormat: @"<%@:\n" @"\tName = %@\n" @"\tClass = %@\n" @"\tType = %@\n" @"\tTTL = %" PRIu32 "\n" @">", self.className, _name, of_dns_resource_record_class_to_string(_recordClass), of_dns_resource_record_type_to_string(_recordType), _TTL]; } @end @implementation OFADNSResourceRecord - (instancetype)initWithName: (OFString *)name |
︙ | ︙ | |||
231 232 233 234 235 236 237 | - (uint32_t)hash { uint32_t hash; OF_HASH_INIT(hash); | | | | 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 | - (uint32_t)hash { uint32_t hash; OF_HASH_INIT(hash); OF_HASH_ADD_HASH(hash, _name.hash); OF_HASH_ADD(hash, _recordClass >> 8); OF_HASH_ADD(hash, _recordClass); OF_HASH_ADD(hash, _recordType >> 8); OF_HASH_ADD(hash, _recordType); OF_HASH_ADD_HASH(hash, of_socket_address_hash(&_address)); OF_HASH_FINALIZE(hash); return hash; } - (OFString *)description { return [OFString stringWithFormat: @"<%@:\n" @"\tName = %@\n" @"\tAddress = %@\n" @"\tTTL = %" PRIu32 "\n" @">", self.className, _name, of_socket_address_ip_string(&_address, NULL), _TTL]; } @end @implementation OFAAAADNSResourceRecord - (instancetype)initWithName: (OFString *)name recordClass: (of_dns_resource_record_class_t)recordClass |
︙ | ︙ | |||
314 315 316 317 318 319 320 | - (uint32_t)hash { uint32_t hash; OF_HASH_INIT(hash); | | | | 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 | - (uint32_t)hash { uint32_t hash; OF_HASH_INIT(hash); OF_HASH_ADD_HASH(hash, _name.hash); OF_HASH_ADD(hash, _recordClass >> 8); OF_HASH_ADD(hash, _recordClass); OF_HASH_ADD(hash, _recordType >> 8); OF_HASH_ADD(hash, _recordType); OF_HASH_ADD_HASH(hash, of_socket_address_hash(&_address)); OF_HASH_FINALIZE(hash); return hash; } - (OFString *)description { return [OFString stringWithFormat: @"<%@:\n" @"\tName = %@\n" @"\tAddress = %@\n" @"\tTTL = %" PRIu32 "\n" @">", self.className, _name, of_socket_address_ip_string(&_address, NULL), _TTL]; } @end @implementation OFCNAMEDNSResourceRecord @synthesize alias = _alias; |
︙ | ︙ | |||
408 409 410 411 412 413 414 | - (uint32_t)hash { uint32_t hash; OF_HASH_INIT(hash); | | | | | 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 | - (uint32_t)hash { uint32_t hash; OF_HASH_INIT(hash); OF_HASH_ADD_HASH(hash, _name.hash); OF_HASH_ADD(hash, _recordClass >> 8); OF_HASH_ADD(hash, _recordClass); OF_HASH_ADD(hash, _recordType >> 8); OF_HASH_ADD(hash, _recordType); OF_HASH_ADD_HASH(hash, _alias.hash); OF_HASH_FINALIZE(hash); return hash; } - (OFString *)description { return [OFString stringWithFormat: @"<%@:\n" @"\tName = %@\n" @"\tClass = %@\n" @"\tAlias = %@\n" @"\tTTL = %" PRIu32 "\n" @">", self.className, _name, of_dns_resource_record_class_to_string(_recordClass), _alias, _TTL]; } @end @implementation OFHINFODNSResourceRecord @synthesize CPU = _CPU, OS = _OS; |
︙ | ︙ | |||
508 509 510 511 512 513 514 | - (uint32_t)hash { uint32_t hash; OF_HASH_INIT(hash); | | | | | | 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 | - (uint32_t)hash { uint32_t hash; OF_HASH_INIT(hash); OF_HASH_ADD_HASH(hash, _name.hash); OF_HASH_ADD(hash, _recordClass >> 8); OF_HASH_ADD(hash, _recordClass); OF_HASH_ADD(hash, _recordType >> 8); OF_HASH_ADD(hash, _recordType); OF_HASH_ADD_HASH(hash, _CPU.hash); OF_HASH_ADD_HASH(hash, _OS.hash); OF_HASH_FINALIZE(hash); return hash; } - (OFString *)description { return [OFString stringWithFormat: @"<%@:\n" @"\tName = %@\n" @"\tClass = %@\n" @"\tCPU = %@\n" @"\tOS = %@\n" @"\tTTL = %" PRIu32 "\n" @">", self.className, _name, of_dns_resource_record_class_to_string(_recordClass), _CPU, _OS, _TTL]; } @end @implementation OFMXDNSResourceRecord @synthesize preference = _preference, mailExchange = _mailExchange; |
︙ | ︙ | |||
611 612 613 614 615 616 617 | - (uint32_t)hash { uint32_t hash; OF_HASH_INIT(hash); | | | | | 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 | - (uint32_t)hash { uint32_t hash; OF_HASH_INIT(hash); OF_HASH_ADD_HASH(hash, _name.hash); OF_HASH_ADD(hash, _recordClass >> 8); OF_HASH_ADD(hash, _recordClass); OF_HASH_ADD(hash, _recordType >> 8); OF_HASH_ADD(hash, _recordType); OF_HASH_ADD(hash, _preference >> 8); OF_HASH_ADD(hash, _preference); OF_HASH_ADD_HASH(hash, _mailExchange.hash); OF_HASH_FINALIZE(hash); return hash; } - (OFString *)description { return [OFString stringWithFormat: @"<%@:\n" @"\tName = %@\n" @"\tClass = %@\n" @"\tPreference = %" PRIu16 "\n" @"\tMail Exchange = %@\n" @"\tTTL = %" PRIu32 "\n" @">", self.className, _name, of_dns_resource_record_class_to_string(_recordClass), _preference, _mailExchange, _TTL]; } @end @implementation OFNSDNSResourceRecord @synthesize authoritativeHost = _authoritativeHost; |
︙ | ︙ | |||
710 711 712 713 714 715 716 | - (uint32_t)hash { uint32_t hash; OF_HASH_INIT(hash); | | | | | 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 | - (uint32_t)hash { uint32_t hash; OF_HASH_INIT(hash); OF_HASH_ADD_HASH(hash, _name.hash); OF_HASH_ADD(hash, _recordClass >> 8); OF_HASH_ADD(hash, _recordClass); OF_HASH_ADD(hash, _recordType >> 8); OF_HASH_ADD(hash, _recordType); OF_HASH_ADD_HASH(hash, _authoritativeHost.hash); OF_HASH_FINALIZE(hash); return hash; } - (OFString *)description { return [OFString stringWithFormat: @"<%@:\n" @"\tName = %@\n" @"\tClass = %@\n" @"\tAuthoritative Host = %@\n" @"\tTTL = %" PRIu32 "\n" @">", self.className, _name, of_dns_resource_record_class_to_string(_recordClass), _authoritativeHost, _TTL]; } @end @implementation OFPTRDNSResourceRecord @synthesize domainName = _domainName; |
︙ | ︙ | |||
806 807 808 809 810 811 812 | - (uint32_t)hash { uint32_t hash; OF_HASH_INIT(hash); | | | | | 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 | - (uint32_t)hash { uint32_t hash; OF_HASH_INIT(hash); OF_HASH_ADD_HASH(hash, _name.hash); OF_HASH_ADD(hash, _recordClass >> 8); OF_HASH_ADD(hash, _recordClass); OF_HASH_ADD(hash, _recordType >> 8); OF_HASH_ADD(hash, _recordType); OF_HASH_ADD_HASH(hash, _domainName.hash); OF_HASH_FINALIZE(hash); return hash; } - (OFString *)description { return [OFString stringWithFormat: @"<%@:\n" @"\tName = %@\n" @"\tClass = %@\n" @"\tDomain Name = %@\n" @"\tTTL = %" PRIu32 "\n" @">", self.className, _name, of_dns_resource_record_class_to_string(_recordClass), _domainName, _TTL]; } @end @implementation OFRPDNSResourceRecord @synthesize mailbox = _mailbox, TXTDomainName = _TXTDomainName; |
︙ | ︙ | |||
909 910 911 912 913 914 915 | - (uint32_t)hash { uint32_t hash; OF_HASH_INIT(hash); | | | | | | 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 | - (uint32_t)hash { uint32_t hash; OF_HASH_INIT(hash); OF_HASH_ADD_HASH(hash, _name.hash); OF_HASH_ADD(hash, _recordClass >> 8); OF_HASH_ADD(hash, _recordClass); OF_HASH_ADD(hash, _recordType >> 8); OF_HASH_ADD(hash, _recordType); OF_HASH_ADD_HASH(hash, _mailbox.hash); OF_HASH_ADD_HASH(hash, _TXTDomainName.hash); OF_HASH_FINALIZE(hash); return hash; } - (OFString *)description { return [OFString stringWithFormat: @"<%@:\n" @"\tName = %@\n" @"\tClass = %@\n" @"\tMailbox = %@\n" @"\tTXT Domain Name = %@\n" @"\tTTL = %" PRIu32 "\n" @">", self.className, _name, of_dns_resource_record_class_to_string(_recordClass), _mailbox, _TXTDomainName, _TTL]; } @end @implementation OFSOADNSResourceRecord @synthesize primaryNameServer = _primaryNameServer; |
︙ | ︙ | |||
1043 1044 1045 1046 1047 1048 1049 | - (uint32_t)hash { uint32_t hash; OF_HASH_INIT(hash); | | | | | 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 | - (uint32_t)hash { uint32_t hash; OF_HASH_INIT(hash); OF_HASH_ADD_HASH(hash, _name.hash); OF_HASH_ADD(hash, _recordClass >> 8); OF_HASH_ADD(hash, _recordClass); OF_HASH_ADD(hash, _recordType >> 8); OF_HASH_ADD(hash, _recordType); OF_HASH_ADD_HASH(hash, _primaryNameServer.hash); OF_HASH_ADD_HASH(hash, _responsiblePerson.hash); OF_HASH_ADD(hash, _serialNumber >> 24); OF_HASH_ADD(hash, _serialNumber >> 16); OF_HASH_ADD(hash, _serialNumber >> 8); OF_HASH_ADD(hash, _serialNumber); OF_HASH_ADD(hash, _refreshInterval >> 24); OF_HASH_ADD(hash, _refreshInterval >> 16); OF_HASH_ADD(hash, _refreshInterval >> 8); |
︙ | ︙ | |||
1091 1092 1093 1094 1095 1096 1097 | @"\tSerial Number = %" PRIu32 "\n" @"\tRefresh Interval = %" PRIu32 "\n" @"\tRetry Interval = %" PRIu32 "\n" @"\tExpiration Interval = %" PRIu32 "\n" @"\tMinimum TTL = %" PRIu32 "\n" @"\tTTL = %" PRIu32 "\n" @">", | | | 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 | @"\tSerial Number = %" PRIu32 "\n" @"\tRefresh Interval = %" PRIu32 "\n" @"\tRetry Interval = %" PRIu32 "\n" @"\tExpiration Interval = %" PRIu32 "\n" @"\tMinimum TTL = %" PRIu32 "\n" @"\tTTL = %" PRIu32 "\n" @">", self.className, _name, of_dns_resource_record_class_to_string(_recordClass), _primaryNameServer, _responsiblePerson, _serialNumber, _refreshInterval, _retryInterval, _expirationInterval, _minTTL, _TTL]; } @end |
︙ | ︙ | |||
1183 1184 1185 1186 1187 1188 1189 | - (uint32_t)hash { uint32_t hash; OF_HASH_INIT(hash); | | | | | 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 | - (uint32_t)hash { uint32_t hash; OF_HASH_INIT(hash); OF_HASH_ADD_HASH(hash, _name.hash); OF_HASH_ADD(hash, _recordClass >> 8); OF_HASH_ADD(hash, _recordClass); OF_HASH_ADD(hash, _recordType >> 8); OF_HASH_ADD(hash, _recordType); OF_HASH_ADD(hash, _priority >> 8); OF_HASH_ADD(hash, _priority); OF_HASH_ADD(hash, _weight >> 8); OF_HASH_ADD(hash, _weight); OF_HASH_ADD_HASH(hash, _target.hash); OF_HASH_ADD(hash, _port >> 8); OF_HASH_ADD(hash, _port); OF_HASH_FINALIZE(hash); return hash; } - (OFString *)description { return [OFString stringWithFormat: @"<%@:\n" @"\tName = %@\n" @"\tPriority = %" PRIu16 "\n" @"\tWeight = %" PRIu16 "\n" @"\tTarget = %@\n" @"\tPort = %" PRIu16 "\n" @"\tTTL = %" PRIu32 "\n" @">", self.className, _name, _priority, _weight, _target, _port, _TTL]; } @end @implementation OFTXTDNSResourceRecord @synthesize textData = _textData; - (instancetype)initWithName: (OFString *)name |
︙ | ︙ | |||
1285 1286 1287 1288 1289 1290 1291 | - (uint32_t)hash { uint32_t hash; OF_HASH_INIT(hash); | | | | | 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 | - (uint32_t)hash { uint32_t hash; OF_HASH_INIT(hash); OF_HASH_ADD_HASH(hash, _name.hash); OF_HASH_ADD(hash, _recordClass >> 8); OF_HASH_ADD(hash, _recordClass); OF_HASH_ADD(hash, _recordType >> 8); OF_HASH_ADD(hash, _recordType); OF_HASH_ADD_HASH(hash, _textData.hash); OF_HASH_FINALIZE(hash); return hash; } - (OFString *)description { return [OFString stringWithFormat: @"<%@:\n" @"\tName = %@\n" @"\tClass = %@\n" @"\tText Data = %@\n" @"\tTTL = %" PRIu32 "\n" @">", self.className, _name, of_dns_resource_record_class_to_string(_recordClass), _textData, _TTL]; } @end |
Modified src/OFData+ASN1DERValue.m from [1b4c7e0240] to [8ca4fa488c].
︙ | ︙ | |||
46 47 48 49 50 51 52 | static size_t parseObject(OFData *self, id *object, size_t depthLimit); static OFArray * parseSequence(OFData *contents, size_t depthLimit) { OFMutableArray *ret = [OFMutableArray array]; | | | 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 | static size_t parseObject(OFData *self, id *object, size_t depthLimit); static OFArray * parseSequence(OFData *contents, size_t depthLimit) { OFMutableArray *ret = [OFMutableArray array]; size_t count = contents.count; if (depthLimit == 0) @throw [OFOutOfRangeException exception]; while (count > 0) { id object; size_t objectLength; |
︙ | ︙ | |||
73 74 75 76 77 78 79 | return ret; } static OFSet * parseSet(OFData *contents, size_t depthLimit) { OFMutableSet *ret = [OFMutableSet set]; | | | 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 | return ret; } static OFSet * parseSet(OFData *contents, size_t depthLimit) { OFMutableSet *ret = [OFMutableSet set]; size_t count = contents.count; OFData *previousObjectData = nil; if (depthLimit == 0) @throw [OFOutOfRangeException exception]; while (count > 0) { id object; |
︙ | ︙ | |||
110 111 112 113 114 115 116 | return ret; } static size_t parseObject(OFData *self, id *object, size_t depthLimit) { | | | | 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 | return ret; } static size_t parseObject(OFData *self, id *object, size_t depthLimit) { const unsigned char *items = self.items; size_t count = self.count; unsigned char tag; size_t contentsLength, bytesConsumed = 0; Class valueClass; OFData *contents; if (count < 2) @throw [OFTruncatedDataException exception]; |
︙ | ︙ | |||
173 174 175 176 177 178 179 | case OF_ASN1_TAG_NUMBER_OCTET_STRING: valueClass = [OFASN1OctetString class]; break; case OF_ASN1_TAG_NUMBER_NULL: if (tag & ASN1_TAG_CONSTRUCTED_MASK) @throw [OFInvalidFormatException exception]; | | | 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 | case OF_ASN1_TAG_NUMBER_OCTET_STRING: valueClass = [OFASN1OctetString class]; break; case OF_ASN1_TAG_NUMBER_NULL: if (tag & ASN1_TAG_CONSTRUCTED_MASK) @throw [OFInvalidFormatException exception]; if (contents.count != 0) @throw [OFInvalidFormatException exception]; *object = [OFNull null]; return bytesConsumed; case OF_ASN1_TAG_NUMBER_OBJECT_IDENTIFIER: valueClass = [OFASN1ObjectIdentifier class]; break; |
︙ | ︙ | |||
232 233 234 235 236 237 238 | } - (id)ASN1DERValueWithDepthLimit: (size_t)depthLimit { void *pool = objc_autoreleasePoolPush(); id object; | | | | 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 | } - (id)ASN1DERValueWithDepthLimit: (size_t)depthLimit { void *pool = objc_autoreleasePoolPush(); id object; if (self.itemSize != 1) @throw [OFInvalidArgumentException exception]; if (parseObject(self, &object, depthLimit) != self.count) @throw [OFInvalidFormatException exception]; [object retain]; objc_autoreleasePoolPop(pool); return [object autorelease]; } @end |
Modified src/OFData+CryptoHashing.m from [8a6be30c19] to [0fcbff4bbf].
︙ | ︙ | |||
37 38 39 40 41 42 43 | id <OFCryptoHash> hash = [class cryptoHash]; size_t digestSize = [class digestSize]; const unsigned char *digest; char cString[digestSize * 2]; [hash updateWithBuffer: _items length: _count * _itemSize]; | | | 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 | id <OFCryptoHash> hash = [class cryptoHash]; size_t digestSize = [class digestSize]; const unsigned char *digest; char cString[digestSize * 2]; [hash updateWithBuffer: _items length: _count * _itemSize]; digest = hash.digest; for (size_t i = 0; i < digestSize; i++) { uint8_t high, low; high = digest[i] >> 4; low = digest[i] & 0x0F; |
︙ | ︙ |
Modified src/OFData+MessagePackValue.m from [32c546e84a] to [823c91328e].
︙ | ︙ | |||
128 129 130 131 132 133 134 | return pos; } static OFDate * createDate(OFData *data) { | | | | | | | 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 | return pos; } static OFDate * createDate(OFData *data) { switch (data.count) { case 4: { uint32_t timestamp; memcpy(×tamp, data.items, 4); timestamp = OF_BSWAP32_IF_LE(timestamp); return [OFDate dateWithTimeIntervalSince1970: timestamp]; } case 8: { uint64_t combined; memcpy(&combined, data.items, 8); combined = OF_BSWAP64_IF_LE(combined); return [OFDate dateWithTimeIntervalSince1970: (double)(combined & 0x3FFFFFFFF) + (double)(combined >> 34) / 1000000000]; } case 12: { uint32_t nanoseconds; int64_t seconds; memcpy(&nanoseconds, data.items, 4); memcpy(&seconds, (char *)data.items + 4, 8); nanoseconds = OF_BSWAP32_IF_LE(nanoseconds); seconds = OF_BSWAP64_IF_LE(seconds); return [OFDate dateWithTimeIntervalSince1970: (double)seconds + (double)nanoseconds / 1000000000]; } |
︙ | ︙ | |||
554 555 556 557 558 559 560 | { return [self messagePackValueWithDepthLimit: 32]; } - (id)messagePackValueWithDepthLimit: (size_t)depthLimit { void *pool = objc_autoreleasePoolPush(); | | | | | 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 | { return [self messagePackValueWithDepthLimit: 32]; } - (id)messagePackValueWithDepthLimit: (size_t)depthLimit { void *pool = objc_autoreleasePoolPush(); size_t count = self.count; id object; if (self.itemSize != 1) @throw [OFInvalidArgumentException exception]; if (parseObject(self.items, count, &object, depthLimit) != count) @throw [OFInvalidFormatException exception]; [object retain]; objc_autoreleasePoolPop(pool); return [object autorelease]; } @end |
Modified src/OFData.m from [fa334deef0] to [5a0f1a8428].
︙ | ︙ | |||
185 186 187 188 189 190 191 | { char *buffer = NULL; uintmax_t size; @try { OFFile *file; | | | | 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 | { char *buffer = NULL; uintmax_t size; @try { OFFile *file; size = [[OFFileManager defaultManager] attributesOfItemAtPath: path].fileSize; # if UINTMAX_MAX > SIZE_MAX if (size > SIZE_MAX) @throw [OFOutOfRangeException exception]; # endif if ((buffer = malloc((size_t)size)) == NULL) |
︙ | ︙ | |||
249 250 251 252 253 254 255 | _itemSize = 1; _count = 0; pageSize = [OFSystemInfo pageSize]; buffer = [self allocMemoryWithSize: pageSize]; | | | 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 | _itemSize = 1; _count = 0; pageSize = [OFSystemInfo pageSize]; buffer = [self allocMemoryWithSize: pageSize]; while (!stream.atEndOfStream) { size_t length = [stream readIntoBuffer: buffer length: pageSize]; if (SIZE_MAX - _count < length) @throw [OFOutOfRangeException exception]; _items = [self resizeMemory: _items |
︙ | ︙ | |||
334 335 336 337 338 339 340 | bool mutable = [self isKindOfClass: [OFMutableData class]]; if (!mutable) { [self release]; self = [OFMutableData alloc]; } | | | 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 | bool mutable = [self isKindOfClass: [OFMutableData class]]; if (!mutable) { [self release]; self = [OFMutableData alloc]; } self = [(OFMutableData *)self initWithCapacity: string.length / 3]; @try { if (!of_base64_decode((OFMutableData *)self, [string cStringWithEncoding: OF_STRING_ENCODING_ASCII], [string cStringLengthWithEncoding: OF_STRING_ENCODING_ASCII])) @throw [OFInvalidFormatException exception]; |
︙ | ︙ | |||
359 360 361 362 363 364 365 | - (instancetype)initWithSerialization: (OFXMLElement *)element { void *pool = objc_autoreleasePoolPush(); OFString *stringValue; @try { | | | | | 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 | - (instancetype)initWithSerialization: (OFXMLElement *)element { void *pool = objc_autoreleasePoolPush(); OFString *stringValue; @try { if (![element.name isEqual: self.className] || ![element.namespace isEqual: OF_SERIALIZATION_NS]) @throw [OFInvalidArgumentException exception]; stringValue = element.stringValue; } @catch (id e) { [self release]; @throw e; } self = [self initWithBase64EncodedString: stringValue]; |
︙ | ︙ | |||
444 445 446 447 448 449 450 | return true; if (![object isKindOfClass: [OFData class]]) return false; data = object; | | | | | | | 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 | return true; if (![object isKindOfClass: [OFData class]]) return false; data = object; if (data.count != _count || data.itemSize != _itemSize) return false; if (memcmp(data.items, _items, _count * _itemSize) != 0) return false; return true; } - (of_comparison_result_t)compare: (id <OFComparing>)object { OFData *data; int comparison; size_t count, minCount; if (![(id)object isKindOfClass: [OFData class]]) @throw [OFInvalidArgumentException exception]; data = (OFData *)object; if (data.itemSize != _itemSize) @throw [OFInvalidArgumentException exception]; count = data.count; minCount = (_count > count ? count : _count); if ((comparison = memcmp(_items, data.items, minCount * _itemSize)) == 0) { if (_count > count) return OF_ORDERED_DESCENDING; if (_count < count) return OF_ORDERED_ASCENDING; return OF_ORDERED_SAME; |
︙ | ︙ | |||
562 563 564 565 566 567 568 | const char *search; size_t searchLength; if (range.length > SIZE_MAX - range.location || range.location + range.length > _count) @throw [OFOutOfRangeException exception]; | | | | | 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 | const char *search; size_t searchLength; if (range.length > SIZE_MAX - range.location || range.location + range.length > _count) @throw [OFOutOfRangeException exception]; if (data == nil || data.itemSize != _itemSize) @throw [OFInvalidArgumentException exception]; if ((searchLength = data.count) == 0) return of_range(0, 0); if (searchLength > range.length) return of_range(OF_NOT_FOUND, 0); search = data.items; if (options & OF_DATA_SEARCH_BACKWARDS) { for (size_t i = range.length - searchLength;; i--) { if (memcmp(_items + i * _itemSize, search, searchLength * _itemSize) == 0) return of_range(i, searchLength); |
︙ | ︙ | |||
635 636 637 638 639 640 641 | OFXMLElement *element; if (_itemSize != 1) @throw [OFInvalidArgumentException exception]; pool = objc_autoreleasePoolPush(); element = [OFXMLElement | | | 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 | OFXMLElement *element; if (_itemSize != 1) @throw [OFInvalidArgumentException exception]; pool = objc_autoreleasePoolPush(); element = [OFXMLElement elementWithName: self.className namespace: OF_SERIALIZATION_NS stringValue: of_base64_encode(_items, _count * _itemSize)]; [element retain]; objc_autoreleasePoolPop(pool); |
︙ | ︙ |
Modified src/OFDate.m from [f76ec7bd46] to [aa9496cc90].
︙ | ︙ | |||
272 273 274 275 276 277 278 | - (instancetype)initWithDateString: (OFString *)string format: (OFString *)format { self = [super init]; @try { | | | | | | | | 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 | - (instancetype)initWithDateString: (OFString *)string format: (OFString *)format { self = [super init]; @try { const char *UTF8String = string.UTF8String; struct tm tm = { 0 }; int16_t tz = 0; tm.tm_isdst = -1; if (of_strptime(UTF8String, format.UTF8String, &tm, &tz) != UTF8String + string.UTF8StringLength) @throw [OFInvalidFormatException exception]; _seconds = tmAndTzToTime(&tm, &tz); } @catch (id e) { [self release]; @throw e; } return self; } - (instancetype)initWithLocalDateString: (OFString *)string format: (OFString *)format { self = [super init]; @try { const char *UTF8String = string.UTF8String; struct tm tm = { 0 }; /* * of_strptime() can never set this to INT16_MAX, no matter * what is passed to it, so this is a safe way to figure out if * the date contains a time zone. */ int16_t tz = INT16_MAX; tm.tm_isdst = -1; if (of_strptime(UTF8String, format.UTF8String, &tm, &tz) != UTF8String + string.UTF8StringLength) @throw [OFInvalidFormatException exception]; if (tz == INT16_MAX) { #ifndef OF_WINDOWS if ((_seconds = mktime(&tm)) == -1) @throw [OFInvalidFormatException exception]; #else |
︙ | ︙ | |||
341 342 343 344 345 346 347 | @try { void *pool = objc_autoreleasePoolPush(); union { double d; uint64_t u; } d; | | | | | 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 | @try { void *pool = objc_autoreleasePoolPush(); union { double d; uint64_t u; } d; if (![element.name isEqual: self.className] || ![element.namespace isEqual: OF_SERIALIZATION_NS]) @throw [OFInvalidArgumentException exception]; d.u = OF_BSWAP64_IF_LE((uint64_t)element.hexadecimalValue); _seconds = OF_BSWAP_DOUBLE_IF_LE(d.d); objc_autoreleasePoolPop(pool); } @catch (id e) { [self release]; @throw e; } |
︙ | ︙ | |||
431 432 433 434 435 436 437 | void *pool = objc_autoreleasePoolPush(); OFXMLElement *element; union { double d; uint64_t u; } d; | | | | | 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 | void *pool = objc_autoreleasePoolPush(); OFXMLElement *element; union { double d; uint64_t u; } d; element = [OFXMLElement elementWithName: self.className namespace: OF_SERIALIZATION_NS]; d.d = OF_BSWAP_DOUBLE_IF_LE(_seconds); element.stringValue = [OFString stringWithFormat: @"%016" PRIx64, OF_BSWAP64_IF_LE(d.u)]; [element retain]; objc_autoreleasePoolPop(pool); return [element autorelease]; } |
︙ | ︙ | |||
622 623 624 625 626 627 628 | #endif pageSize = [OFSystemInfo pageSize]; buffer = [self allocMemoryWithSize: pageSize]; @try { #ifndef OF_WINDOWS | | | | 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 | #endif pageSize = [OFSystemInfo pageSize]; buffer = [self allocMemoryWithSize: pageSize]; @try { #ifndef OF_WINDOWS if (strftime(buffer, pageSize, format.UTF8String, &tm) == 0) @throw [OFOutOfRangeException exception]; ret = [OFString stringWithUTF8String: buffer]; #else if (wcsftime(buffer, pageSize / sizeof(wchar_t), format.UTF16String, &tm) == 0) @throw [OFOutOfRangeException exception]; ret = [OFString stringWithUTF16String: buffer]; #endif } @finally { [self freeMemory: buffer]; } |
︙ | ︙ | |||
682 683 684 685 686 687 688 | #endif pageSize = [OFSystemInfo pageSize]; buffer = [self allocMemoryWithSize: pageSize]; @try { #ifndef OF_WINDOWS | | | | 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 | #endif pageSize = [OFSystemInfo pageSize]; buffer = [self allocMemoryWithSize: pageSize]; @try { #ifndef OF_WINDOWS if (strftime(buffer, pageSize, format.UTF8String, &tm) == 0) @throw [OFOutOfRangeException exception]; ret = [OFString stringWithUTF8String: buffer]; #else if (wcsftime(buffer, pageSize / sizeof(wchar_t), format.UTF16String, &tm) == 0) @throw [OFOutOfRangeException exception]; ret = [OFString stringWithUTF16String: buffer]; #endif } @finally { [self freeMemory: buffer]; } |
︙ | ︙ |
Modified src/OFDictionary.m from [01ef213c97] to [f5551c8463].
︙ | ︙ | |||
286 287 288 289 290 291 292 | - (instancetype)initWithObjects: (OFArray *)objects_ forKeys: (OFArray *)keys_ { id const *objects, *keys; size_t count; @try { | | | | | | 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 | - (instancetype)initWithObjects: (OFArray *)objects_ forKeys: (OFArray *)keys_ { id const *objects, *keys; size_t count; @try { count = objects_.count; if (count != keys_.count) @throw [OFInvalidArgumentException exception]; objects = objects_.objects; keys = keys_.objects; } @catch (id e) { [self release]; @throw e; } return [self initWithObjects: objects forKeys: keys |
︙ | ︙ | |||
350 351 352 353 354 355 356 | - (id)valueForKey: (OFString *)key { if ([key hasPrefix: @"@"]) { void *pool = objc_autoreleasePoolPush(); id ret; | | | | 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 | - (id)valueForKey: (OFString *)key { if ([key hasPrefix: @"@"]) { void *pool = objc_autoreleasePoolPush(); id ret; key = [key substringWithRange: of_range(1, key.length - 1)]; ret = [[super valueForKey: key] retain]; objc_autoreleasePoolPop(pool); return [ret autorelease]; } return [self objectForKey: key]; } - (void)setValue: (id)value forKey: (OFString *)key { if ([key hasPrefix: @"@"]) { void *pool = objc_autoreleasePoolPush(); key = [key substringWithRange: of_range(1, key.length - 1)]; [super setValue: value forKey: key]; objc_autoreleasePoolPop(pool); return; } |
︙ | ︙ | |||
414 415 416 417 418 419 420 | return true; if (![object isKindOfClass: [OFDictionary class]]) return false; otherDictionary = object; | | | 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 | return true; if (![object isKindOfClass: [OFDictionary class]]) return false; otherDictionary = object; if (otherDictionary.count != self.count) return false; pool = objc_autoreleasePoolPush(); keyEnumerator = [self keyEnumerator]; objectEnumerator = [self objectEnumerator]; while ((key = [keyEnumerator nextObject]) != nil && |
︙ | ︙ | |||
486 487 488 489 490 491 492 | objc_autoreleasePoolPop(pool); return false; } - (OFArray *)allKeys { | | | | 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 | objc_autoreleasePoolPop(pool); return false; } - (OFArray *)allKeys { OFMutableArray *ret = [OFMutableArray arrayWithCapacity: self.count]; for (id key in self) [ret addObject: key]; [ret makeImmutable]; return ret; } - (OFArray *)allObjects { OFMutableArray *ret = [OFMutableArray arrayWithCapacity: self.count]; void *pool = objc_autoreleasePoolPush(); OFEnumerator *enumerator = [self objectEnumerator]; id object; while ((object = [enumerator nextObject]) != nil) [ret addObject: object]; |
︙ | ︙ | |||
601 602 603 604 605 606 607 | } - (OFString *)description { OFMutableString *ret; void *pool; OFEnumerator *keyEnumerator, *objectEnumerator; | | | | | | 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 | } - (OFString *)description { OFMutableString *ret; void *pool; OFEnumerator *keyEnumerator, *objectEnumerator; OFObject *key, *object; size_t i, count = self.count; if (count == 0) return @"{}"; ret = [OFMutableString stringWithString: @"{\n"]; pool = objc_autoreleasePoolPush(); keyEnumerator = [self keyEnumerator]; objectEnumerator = [self objectEnumerator]; i = 0; while ((key = [keyEnumerator nextObject]) != nil && (object = [objectEnumerator nextObject]) != nil) { void *pool2 = objc_autoreleasePoolPush(); [ret appendString: key.description]; [ret appendString: @" = "]; [ret appendString: object.description]; if (++i < count) [ret appendString: @";\n"]; objc_autoreleasePoolPop(pool2); } [ret replaceOccurrencesOfString: @"\n" |
︙ | ︙ | |||
646 647 648 649 650 651 652 | OFMutableString *ret = [OFMutableString string]; void *pool = objc_autoreleasePoolPush(); OFEnumerator *keyEnumerator = [self keyEnumerator]; OFEnumerator *objectEnumerator = [self objectEnumerator]; OFCharacterSet *allowed = [OFCharacterSet_URLQueryPartAllowed URLQueryPartAllowedCharacterSet]; bool first = true; | | | | | 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 | OFMutableString *ret = [OFMutableString string]; void *pool = objc_autoreleasePoolPush(); OFEnumerator *keyEnumerator = [self keyEnumerator]; OFEnumerator *objectEnumerator = [self objectEnumerator]; OFCharacterSet *allowed = [OFCharacterSet_URLQueryPartAllowed URLQueryPartAllowedCharacterSet]; bool first = true; OFObject *key, *object; while ((key = [keyEnumerator nextObject]) != nil && (object = [objectEnumerator nextObject]) != nil) { if OF_UNLIKELY (first) first = false; else [ret appendString: @"&"]; [ret appendString: [key.description stringByURLEncodingWithAllowedCharacters: allowed]]; [ret appendString: @"="]; [ret appendString: [object.description stringByURLEncodingWithAllowedCharacters: allowed]]; } [ret makeImmutable]; objc_autoreleasePoolPop(pool); |
︙ | ︙ | |||
693 694 695 696 697 698 699 | (object = [objectEnumerator nextObject]) != nil) { void *pool2 = objc_autoreleasePoolPush(); OFXMLElement *keyElement, *objectElement; keyElement = [OFXMLElement elementWithName: @"key" namespace: OF_SERIALIZATION_NS]; | | | | 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 | (object = [objectEnumerator nextObject]) != nil) { void *pool2 = objc_autoreleasePoolPush(); OFXMLElement *keyElement, *objectElement; keyElement = [OFXMLElement elementWithName: @"key" namespace: OF_SERIALIZATION_NS]; [keyElement addChild: key.XMLElementBySerializing]; objectElement = [OFXMLElement elementWithName: @"object" namespace: OF_SERIALIZATION_NS]; [objectElement addChild: object.XMLElementBySerializing]; [element addChild: keyElement]; [element addChild: objectElement]; objc_autoreleasePoolPop(pool2); } |
︙ | ︙ | |||
732 733 734 735 736 737 738 | - (OFString *)of_JSONRepresentationWithOptions: (int)options depth: (size_t)depth { OFMutableString *JSON = [OFMutableString stringWithString: @"{"]; void *pool = objc_autoreleasePoolPush(); OFEnumerator *keyEnumerator = [self keyEnumerator]; OFEnumerator *objectEnumerator = [self objectEnumerator]; | | | 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 | - (OFString *)of_JSONRepresentationWithOptions: (int)options depth: (size_t)depth { OFMutableString *JSON = [OFMutableString stringWithString: @"{"]; void *pool = objc_autoreleasePoolPush(); OFEnumerator *keyEnumerator = [self keyEnumerator]; OFEnumerator *objectEnumerator = [self objectEnumerator]; size_t i, count = self.count; id key, object; if (options & OF_JSON_REPRESENTATION_PRETTY) { OFMutableString *indentation = [OFMutableString string]; for (i = 0; i < depth; i++) [indentation appendString: @"\t"]; |
︙ | ︙ | |||
812 813 814 815 816 817 818 | - (OFData *)messagePackRepresentation { OFMutableData *data; size_t i, count; void *pool; OFEnumerator *keyEnumerator, *objectEnumerator; | | | | 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 | - (OFData *)messagePackRepresentation { OFMutableData *data; size_t i, count; void *pool; OFEnumerator *keyEnumerator, *objectEnumerator; id <OFMessagePackRepresentation> key, object; data = [OFMutableData data]; count = self.count; if (count <= 15) { uint8_t tmp = 0x80 | ((uint8_t)count & 0xF); [data addItem: &tmp]; } else if (count <= UINT16_MAX) { uint8_t type = 0xDE; uint16_t tmp = OF_BSWAP16_IF_LE((uint16_t)count); |
︙ | ︙ | |||
849 850 851 852 853 854 855 | while ((key = [keyEnumerator nextObject]) != nil && (object = [objectEnumerator nextObject]) != nil) { void *pool2 = objc_autoreleasePoolPush(); OFData *child; i++; | | | | | | | | 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 | while ((key = [keyEnumerator nextObject]) != nil && (object = [objectEnumerator nextObject]) != nil) { void *pool2 = objc_autoreleasePoolPush(); OFData *child; i++; child = key.messagePackRepresentation; [data addItems: child.items count: child.count]; child = object.messagePackRepresentation; [data addItems: child.items count: child.count]; objc_autoreleasePoolPop(pool2); } assert(i == count); [data makeImmutable]; objc_autoreleasePoolPop(pool); return data; } @end |
Modified src/OFDictionary_hashtable.m from [4b8b632d36] to [59f7a05c14].
︙ | ︙ | |||
118 119 120 121 122 123 124 | @throw e; } return self; } @try { | | | 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 | @throw e; } return self; } @try { count = dictionary.count; } @catch (id e) { [self release]; @throw e; } self = [self initWithCapacity: count]; |
︙ | ︙ | |||
252 253 254 255 256 257 258 | OFXMLElement *keyElement, *objectElement; keys = [element elementsForName: @"key" namespace: OF_SERIALIZATION_NS]; objects = [element elementsForName: @"object" namespace: OF_SERIALIZATION_NS]; | | | | | | | | | | 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 | 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]; |
︙ | ︙ | |||
304 305 306 307 308 309 310 | - (id)objectForKey: (id)key { return [_mapTable objectForKey: key]; } - (size_t)count { | | | 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 | - (id)objectForKey: (id)key { return [_mapTable objectForKey: key]; } - (size_t)count { return _mapTable.count; } - (bool)isEqual: (id)object { OFDictionary_hashtable *dictionary; if (object == self) |
︙ | ︙ | |||
339 340 341 342 343 344 345 | - (OFArray *)allKeys { OFArray *ret; id *keys; size_t count; | | | 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 | - (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; |
︙ | ︙ | |||
374 375 376 377 378 379 380 | - (OFArray *)allObjects { OFArray *ret; id *objects; size_t count; | | | 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 | - (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; |
︙ | ︙ | |||
444 445 446 447 448 449 450 | exceptionWithObject: self]; } } #endif - (uint32_t)hash { | | | 444 445 446 447 448 449 450 451 452 453 | exceptionWithObject: self]; } } #endif - (uint32_t)hash { return _mapTable.hash; } @end |
Modified src/OFEnumerator.h from [a15bc1046c] to [3064d9daa6].
︙ | ︙ | |||
83 84 85 86 87 88 89 | */ #define of_fast_enumeration_state_t NSFastEnumerationState #ifndef NSINTEGER_DEFINED typedef struct { /*! Arbitrary state information for the enumeration */ unsigned long state; /*! Pointer to a C array of objects to return */ | | | 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 | */ #define of_fast_enumeration_state_t NSFastEnumerationState #ifndef NSINTEGER_DEFINED typedef struct { /*! Arbitrary state information for the enumeration */ unsigned long state; /*! Pointer to a C array of objects to return */ id const __unsafe_unretained _Nullable *_Nullable itemsPtr; /*! Arbitrary state information to detect mutations */ unsigned long *_Nullable mutationsPtr; /*! Additional arbitrary state information */ unsigned long extra[5]; } of_fast_enumeration_state_t; #endif |
︙ | ︙ |
Modified src/OFFile.m from [ce755e8542] to [8a440b67d1].
︙ | ︙ | |||
241 242 243 244 245 246 247 | of_file_handle_t handle; @try { void *pool = objc_autoreleasePoolPush(); int flags; #ifndef OF_AMIGAOS | | | | | 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 | of_file_handle_t handle; @try { void *pool = objc_autoreleasePoolPush(); int flags; #ifndef OF_AMIGAOS if ((flags = parseMode(mode.UTF8String)) == -1) @throw [OFInvalidArgumentException exception]; flags |= O_BINARY | O_CLOEXEC; # if defined(OF_WINDOWS) if ((handle = _wopen(path.UTF16String, flags, _S_IREAD | _S_IWRITE)) == -1) # elif defined(OF_HAVE_OFF64_T) if ((handle = open64([path cStringWithEncoding: [OFLocale encoding]], flags, 0666)) == -1) # else if ((handle = open([path cStringWithEncoding: [OFLocale encoding]], flags, 0666)) == -1) # endif @throw [OFOpenItemFailedException exceptionWithPath: path mode: mode errNo: errno]; #else if ((handle = malloc(sizeof(*handle))) == NULL) @throw [OFOutOfMemoryException exceptionWithRequestedSize: sizeof(*handle)]; @try { if ((flags = parseMode(mode.UTF8String, &handle->append)) == -1) @throw [OFInvalidArgumentException exception]; if ((handle->handle = Open([path cStringWithEncoding: [OFLocale encoding]], flags)) == 0) { int errNo; |
︙ | ︙ | |||
354 355 356 357 358 359 360 | - (instancetype)initWithURL: (OFURL *)URL mode: (OFString *)mode { void *pool = objc_autoreleasePoolPush(); OFString *fileSystemRepresentation; @try { | | | 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 | - (instancetype)initWithURL: (OFURL *)URL mode: (OFString *)mode { void *pool = objc_autoreleasePoolPush(); OFString *fileSystemRepresentation; @try { fileSystemRepresentation = URL.fileSystemRepresentation; } @catch (id e) { [self release]; @throw e; } self = [self initWithPath: fileSystemRepresentation mode: mode]; |
︙ | ︙ |
Modified src/OFFileManager.m from [fd1f20d425] to [a70bd77335].
︙ | ︙ | |||
179 180 181 182 183 184 185 | } - (OFURL *)currentDirectoryURL { void *pool = objc_autoreleasePoolPush(); OFURL *ret; | | | 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 | } - (OFURL *)currentDirectoryURL { void *pool = objc_autoreleasePoolPush(); OFURL *ret; ret = [OFURL fileURLWithPath: self.currentDirectoryPath]; [ret retain]; objc_autoreleasePoolPop(pool); return [ret autorelease]; } - (of_file_attributes_t)attributesOfItemAtURL: (OFURL *)URL |
︙ | ︙ | |||
340 341 342 343 344 345 346 | * If we didn't fail because any of the parents is missing, * there is no point in trying to create the parents. */ if ([e errNo] != ENOENT) @throw e; } | | | | | 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 | * If we didn't fail because any of the parents is missing, * there is no point in trying to create the parents. */ if ([e errNo] != ENOENT) @throw e; } components = [URL.URLEncodedPath componentsSeparatedByString: @"/"]; for (OFString *component in components) { if (currentPath != nil) currentPath = [currentPath stringByAppendingFormat: @"/%@", component]; else currentPath = component; URL.URLEncodedPath = currentPath; if (currentPath.length > 0 && ![self directoryExistsAtURL: URL]) [self createDirectoryAtURL: URL]; } objc_autoreleasePoolPop(pool); } |
︙ | ︙ | |||
412 413 414 415 416 417 418 | - (void)changeCurrentDirectoryPath: (OFString *)path { if (path == nil) @throw [OFInvalidArgumentException exception]; #if defined(OF_WINDOWS) | | | 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 | - (void)changeCurrentDirectoryPath: (OFString *)path { if (path == nil) @throw [OFInvalidArgumentException exception]; #if defined(OF_WINDOWS) if (_wchdir(path.UTF16String) != 0) @throw [OFChangeCurrentDirectoryPathFailedException exceptionWithPath: path errNo: errno]; #elif defined(OF_AMIGAOS) BPTR lock, oldLock; if ((lock = Lock([path cStringWithEncoding: [OFLocale encoding]], |
︙ | ︙ | |||
461 462 463 464 465 466 467 | #endif } - (void)changeCurrentDirectoryURL: (OFURL *)URL { void *pool = objc_autoreleasePoolPush(); | | | 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 | #endif } - (void)changeCurrentDirectoryURL: (OFURL *)URL { void *pool = objc_autoreleasePoolPush(); [self changeCurrentDirectoryPath: URL.fileSystemRepresentation]; objc_autoreleasePoolPop(pool); } - (void)copyItemAtPath: (OFString *)source toPath: (OFString *)destination { |
︙ | ︙ | |||
510 511 512 513 514 515 516 | @try { attributes = [self attributesOfItemAtURL: source]; } @catch (OFRetrieveItemAttributesFailedException *e) { @throw [OFCopyItemFailedException exceptionWithSourceURL: source destinationURL: destination | | | | 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 | @try { attributes = [self attributesOfItemAtURL: source]; } @catch (OFRetrieveItemAttributesFailedException *e) { @throw [OFCopyItemFailedException exceptionWithSourceURL: source destinationURL: destination errNo: e.errNo]; } type = attributes.fileType; if ([type isEqual: of_file_type_directory]) { OFArray *contents; @try { [self createDirectoryAtURL: destination]; |
︙ | ︙ | |||
582 583 584 585 586 587 588 | sourceStream = [[OFURLHandler handlerForURL: source] openItemAtURL: source mode: @"r"]; destinationStream = [[OFURLHandler handlerForURL: destination] openItemAtURL: destination mode: @"w"]; | | | 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 | sourceStream = [[OFURLHandler handlerForURL: source] openItemAtURL: source mode: @"r"]; destinationStream = [[OFURLHandler handlerForURL: destination] openItemAtURL: destination mode: @"w"]; while (!sourceStream.atEndOfStream) { size_t length; length = [sourceStream readIntoBuffer: buffer length: pageSize]; [destinationStream writeBuffer: buffer length: length]; |
︙ | ︙ | |||
626 627 628 629 630 631 632 | [destinationStream close]; free(buffer); } #ifdef OF_FILE_MANAGER_SUPPORTS_SYMLINKS } else if ([type isEqual: of_file_type_symbolic_link]) { @try { OFString *linkDestination = | | | 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 | [destinationStream close]; free(buffer); } #ifdef OF_FILE_MANAGER_SUPPORTS_SYMLINKS } else if ([type isEqual: of_file_type_symbolic_link]) { @try { OFString *linkDestination = attributes.fileSymbolicLinkDestination; [self createSymbolicLinkAtURL: destination withDestinationPath: linkDestination]; } @catch (id e) { /* * Only convert exceptions to OFCopyItemFailedException * that have an errNo property. This covers all I/O |
︙ | ︙ | |||
686 687 688 689 690 691 692 | exceptionWithURL: source]; @try { if ([URLHandler moveItemAtURL: source toURL: destination]) return; } @catch (OFMoveItemFailedException *e) { | | | | | 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 | exceptionWithURL: source]; @try { if ([URLHandler moveItemAtURL: source toURL: destination]) return; } @catch (OFMoveItemFailedException *e) { if (e.errNo != EXDEV) @throw e; } if ([self fileExistsAtURL: destination]) @throw [OFMoveItemFailedException exceptionWithSourceURL: source destinationURL: destination errNo: EEXIST]; @try { [self copyItemAtURL: source toURL: destination]; } @catch (OFCopyItemFailedException *e) { [self removeItemAtURL: destination]; @throw [OFMoveItemFailedException exceptionWithSourceURL: source destinationURL: destination errNo: e.errNo]; } @try { [self removeItemAtURL: source]; } @catch (OFRemoveItemFailedException *e) { @throw [OFMoveItemFailedException exceptionWithSourceURL: source destinationURL: destination errNo: e.errNo]; } objc_autoreleasePoolPop(pool); } - (void)removeItemAtURL: (OFURL *)URL { |
︙ | ︙ | |||
751 752 753 754 755 756 757 | { void *pool = objc_autoreleasePoolPush(); OFURLHandler *URLHandler; if (source == nil || destination == nil) @throw [OFInvalidArgumentException exception]; | | | 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 | { void *pool = objc_autoreleasePoolPush(); OFURLHandler *URLHandler; if (source == nil || destination == nil) @throw [OFInvalidArgumentException exception]; if (![destination.scheme isEqual: source.scheme]) @throw [OFInvalidArgumentException exception]; URLHandler = [OFURLHandler handlerForURL: source]; if (URLHandler == nil) @throw [OFUnsupportedProtocolException exceptionWithURL: source]; |
︙ | ︙ |
Modified src/OFGZIPStream.m from [7f75898f5a] to [f365c42bc2].
︙ | ︙ | |||
79 80 81 82 83 84 85 | if (_stream == nil) @throw [OFNotOpenException exceptionWithObject: self]; for (;;) { uint8_t byte; uint32_t CRC32, uncompressedSize; | | | 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 | if (_stream == nil) @throw [OFNotOpenException exceptionWithObject: self]; for (;;) { uint8_t byte; uint32_t CRC32, uncompressedSize; if (_stream.atEndOfStream) { if (_state != OF_GZIP_STREAM_ID1) @throw [OFTruncatedDataException exception]; return 0; } switch (_state) { |
︙ | ︙ | |||
235 236 237 238 239 240 241 | _state++; break; case OF_GZIP_STREAM_DATA: if (_inflateStream == nil) _inflateStream = [[OFInflateStream alloc] initWithStream: _stream]; | | | 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 | _state++; break; case OF_GZIP_STREAM_DATA: if (_inflateStream == nil) _inflateStream = [[OFInflateStream alloc] initWithStream: _stream]; if (!_inflateStream.atEndOfStream) { size_t bytesRead = [_inflateStream readIntoBuffer: buffer length: length]; _CRC32 = of_crc32(_CRC32, buffer, bytesRead); _uncompressedSize += bytesRead; |
︙ | ︙ | |||
305 306 307 308 309 310 311 | } - (bool)lowlevelIsAtEndOfStream { if (_stream == nil) @throw [OFNotOpenException exceptionWithObject: self]; | | | | | | 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 | } - (bool)lowlevelIsAtEndOfStream { if (_stream == nil) @throw [OFNotOpenException exceptionWithObject: self]; return _stream.atEndOfStream; } - (bool)hasDataInReadBuffer { if (_state == OF_GZIP_STREAM_DATA) return (super.hasDataInReadBuffer || _inflateStream.hasDataInReadBuffer); return (super.hasDataInReadBuffer || _stream.hasDataInReadBuffer); } - (void)close { [_stream release]; _stream = nil; [super close]; } @end |
Modified src/OFHMAC.m from [319ce0f0dd] to [61a4776d3d].
︙ | ︙ | |||
58 59 60 61 62 63 64 | - (void)setKey: (const void *)key length: (size_t)length { void *pool = objc_autoreleasePoolPush(); size_t blockSize = [_hashClass blockSize]; OFSecureData *outerKeyPad = [OFSecureData dataWithCount: blockSize]; OFSecureData *innerKeyPad = [OFSecureData dataWithCount: blockSize]; | | | | | | 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 | - (void)setKey: (const void *)key length: (size_t)length { void *pool = objc_autoreleasePoolPush(); size_t blockSize = [_hashClass blockSize]; OFSecureData *outerKeyPad = [OFSecureData dataWithCount: blockSize]; OFSecureData *innerKeyPad = [OFSecureData dataWithCount: blockSize]; unsigned char *outerKeyPadItems = outerKeyPad.mutableItems; unsigned char *innerKeyPadItems = innerKeyPad.mutableItems; [_outerHash release]; [_innerHash release]; [_outerHashCopy release]; [_innerHashCopy release]; _outerHash = _innerHash = _outerHashCopy = _innerHashCopy = nil; @try { if (length > blockSize) { id <OFCryptoHash> hash = [_hashClass cryptoHash]; [hash updateWithBuffer: key length: length]; length = [_hashClass digestSize]; if OF_UNLIKELY (length > blockSize) length = blockSize; memcpy(outerKeyPadItems, hash.digest, length); memcpy(innerKeyPadItems, hash.digest, length); } else { memcpy(outerKeyPadItems, key, length); memcpy(innerKeyPadItems, key, length); } memset(outerKeyPadItems + length, 0, blockSize - length); memset(innerKeyPadItems + length, 0, blockSize - length); |
︙ | ︙ | |||
135 136 137 138 139 140 141 | - (const unsigned char *)digest { if (_outerHash == nil || _innerHash == nil) @throw [OFInvalidArgumentException exception]; if (_calculated) | | | | | 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 | - (const unsigned char *)digest { if (_outerHash == nil || _innerHash == nil) @throw [OFInvalidArgumentException exception]; if (_calculated) return _outerHash.digest; [_outerHash updateWithBuffer: _innerHash.digest length: [_hashClass digestSize]]; _calculated = true; return _outerHash.digest; } - (size_t)digestSize { return [_hashClass digestSize]; } |
︙ | ︙ |
Modified src/OFHTTPClient.h from [37c93537fa] to [ec1691a772].
︙ | ︙ | |||
70 71 72 73 74 75 76 | * proxy it should use for this connection. * * @param client The OFHTTPClient that created a socket * @param socket The socket created by the OFHTTPClient * @param request The request for which the socket was created */ - (void)client: (OFHTTPClient *)client | | | 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 | * proxy it should use for this connection. * * @param client The OFHTTPClient that created a socket * @param socket The socket created by the OFHTTPClient * @param request The request for which the socket was created */ - (void)client: (OFHTTPClient *)client didCreateSocket: (OFTCPSocket *)socket request: (OFHTTPRequest *)request; /*! * @brief A callback which is called when an OFHTTPClient wants to send the * body for a request. * * @param client The OFHTTPClient that wants to send the body |
︙ | ︙ |
Modified src/OFHTTPClient.m from [281ca703ab] to [fa73320acf].
︙ | ︙ | |||
106 107 108 109 110 111 112 | redirects: (unsigned int)redirects; @end static OFString * constructRequestString(OFHTTPRequest *request) { void *pool = objc_autoreleasePoolPush(); | | | | | | | | | | | | | | | | | | | | | 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 | redirects: (unsigned int)redirects; @end static OFString * constructRequestString(OFHTTPRequest *request) { void *pool = objc_autoreleasePoolPush(); of_http_request_method_t method = request.method; OFURL *URL = request.URL; OFString *path; OFString *user = URL.user, *password = URL.password; OFMutableString *requestString; OFMutableDictionary OF_GENERIC(OFString *, OFString *) *headers; OFEnumerator OF_GENERIC(OFString *) *keyEnumerator, *objectEnumerator; OFString *key, *object; if (URL.path != nil) path = URL.URLEncodedPath; else path = @"/"; requestString = [OFMutableString stringWithFormat: @"%s %@", of_http_request_method_to_string(method), path]; if (URL.query != nil) { [requestString appendString: @"?"]; [requestString appendString: URL.URLEncodedQuery]; } [requestString appendString: @" HTTP/"]; [requestString appendString: request.protocolVersionString]; [requestString appendString: @"\r\n"]; headers = [[request.headers mutableCopy] autorelease]; if (headers == nil) headers = [OFMutableDictionary dictionary]; if ([headers objectForKey: @"Host"] == nil) { OFNumber *port = URL.port; if (port != nil) { OFString *host = [OFString stringWithFormat: @"%@:%@", URL.URLEncodedHost, port]; [headers setObject: host forKey: @"Host"]; } else [headers setObject: [URL URLEncodedHost] forKey: @"Host"]; } if ((user.length > 0 || password.length > 0) && [headers objectForKey: @"Authorization"] == nil) { OFMutableData *authorizationData = [OFMutableData data]; OFString *authorization; [authorizationData addItems: user.UTF8String count: user.UTF8StringLength]; [authorizationData addItem: ":"]; [authorizationData addItems: password.UTF8String count: password.UTF8StringLength]; authorization = [OFString stringWithFormat: @"Basic %@", authorizationData.stringByBase64Encoding]; [headers setObject: authorization forKey: @"Authorization"]; } if ([headers objectForKey: @"User-Agent"] == nil) [headers setObject: @"Something using ObjFW " @"<https://heap.zone/objfw>" forKey: @"User-Agent"]; if (request.protocolVersion.major == 1 && request.protocolVersion.minor == 0 && [headers objectForKey: @"Connection"] == nil) [headers setObject: @"keep-alive" forKey: @"Connection"]; if ([headers objectForKey: @"Content-Length"] != nil && [headers objectForKey: @"Content-Type"] == nil) [headers setObject: @"application/x-www-form-" |
︙ | ︙ | |||
287 288 289 290 291 292 293 | [_client->_delegate client: _client didFailWithException: exception request: _request]; } - (void)createResponseWithSocketOrThrow: (OFTCPSocket *)sock { | | | | | | | | | < | | | 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 | [_client->_delegate client: _client didFailWithException: exception request: _request]; } - (void)createResponseWithSocketOrThrow: (OFTCPSocket *)sock { OFURL *URL = _request.URL; OFHTTPClientResponse *response; OFString *connectionHeader; bool keepAlive; OFString *location; response = [[[OFHTTPClientResponse alloc] initWithSocket: sock] autorelease]; response.protocolVersionString = _version; response.statusCode = _status; response.headers = _serverHeaders; connectionHeader = [_serverHeaders objectForKey: @"Connection"]; if ([_version isEqual: @"1.1"]) { if (connectionHeader != nil) keepAlive = ([connectionHeader caseInsensitiveCompare: @"close"] != OF_ORDERED_SAME); else keepAlive = true; } else { if (connectionHeader != nil) keepAlive = ([connectionHeader caseInsensitiveCompare: @"keep-alive"] == OF_ORDERED_SAME); else keepAlive = false; } if (keepAlive) { response.of_keepAlive = true; _client->_socket = [sock retain]; _client->_lastURL = [URL copy]; _client->_lastWasHEAD = (_request.method == OF_HTTP_REQUEST_METHOD_HEAD); _client->_lastResponse = [response retain]; } /* FIXME: Case-insensitive check of redirect's scheme */ if (_redirects > 0 && (_status == 301 || _status == 302 || _status == 303 || _status == 307) && (location = [_serverHeaders objectForKey: @"Location"]) != nil && (_client->_insecureRedirectsAllowed || [URL.scheme isEqual: @"http"] || [location hasPrefix: @"https://"])) { OFURL *newURL; bool follow; newURL = [OFURL URLWithString: location relativeToURL: URL]; if ([_client->_delegate respondsToSelector: @selector(client: shouldFollowRedirect:statusCode:request:response:)]) follow = [_client->_delegate client: _client shouldFollowRedirect: newURL statusCode: _status request: _request response: response]; else follow = defaultShouldFollow(_request.method, _status); if (follow) { OFDictionary OF_GENERIC(OFString *, OFString *) *headers = _request.headers; OFHTTPRequest *newRequest = [[_request copy] autorelease]; OFMutableDictionary *newHeaders = [[headers mutableCopy] autorelease]; if (![newURL.host isEqual: URL.host]) [newHeaders removeObjectForKey: @"Host"]; /* * 303 means the request should be converted to a GET * request before redirection. This also means stripping * the entity of the request. */ |
︙ | ︙ | |||
379 380 381 382 383 384 385 | (object = [objectEnumerator nextObject]) != nil) if ([key hasPrefix: @"Content-"] || [key hasPrefix: @"Transfer-"]) [newHeaders removeObjectForKey: key]; | < | | | | 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 | (object = [objectEnumerator nextObject]) != nil) if ([key hasPrefix: @"Content-"] || [key hasPrefix: @"Transfer-"]) [newHeaders removeObjectForKey: key]; newRequest.method = OF_HTTP_REQUEST_METHOD_GET; } newRequest.URL = newURL; newRequest.headers = newHeaders; _client->_inProgress = false; [_client asyncPerformRequest: newRequest redirects: _redirects - 1]; return; } |
︙ | ︙ | |||
430 431 432 433 434 435 436 | * end due to a timeout. In this case, we need to reconnect. */ if (line == nil) { [self closeAndReconnect]; return false; } | | | | | | | 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 | * end due to a timeout. In this case, we need to reconnect. */ if (line == nil) { [self closeAndReconnect]; return false; } if (![line hasPrefix: @"HTTP/"] || line.length < 9 || [line characterAtIndex: 8] != ' ') @throw [OFInvalidServerReplyException exception]; _version = [[line substringWithRange: of_range(5, 3)] copy]; if (![_version isEqual: @"1.0"] && ![_version isEqual: @"1.1"]) @throw [OFUnsupportedVersionException exceptionWithVersion: _version]; _status = (int)[line substringWithRange: of_range(9, 3)].decimalValue; return true; } - (bool)handleServerHeader: (OFString *)line socket: (OFTCPSocket *)sock { OFString *key, *value, *old; const char *lineC, *tmp; char *keyC; if (line == nil) @throw [OFInvalidServerReplyException exception]; if (line.length == 0) { [_serverHeaders makeImmutable]; if ([_client->_delegate respondsToSelector: @selector(client: didReceiveHeaders:statusCode:request:)]) [_client->_delegate client: _client didReceiveHeaders: _serverHeaders statusCode: _status request: _request]; sock.delegate = nil; [self performSelector: @selector(createResponseWithSocket:) withObject: sock afterDelay: 0]; return false; } lineC = line.UTF8String; if ((tmp = strchr(lineC, ':')) == NULL) @throw [OFInvalidServerReplyException exception]; if ((keyC = malloc(tmp - lineC + 1)) == NULL) @throw [OFOutOfMemoryException exceptionWithRequestedSize: tmp - lineC + 1]; |
︙ | ︙ | |||
510 511 512 513 514 515 516 | [_serverHeaders setObject: value forKey: key]; return true; } | | | | | | | | 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 | [_serverHeaders setObject: value forKey: key]; return true; } - (bool)stream: (OFStream *)sock didReadLine: (OFString *)line exception: (id)exception { bool ret; if (exception != nil) { if ([exception isKindOfClass: [OFInvalidEncodingException class]]) exception = [OFInvalidServerReplyException exception]; [self raiseException: exception]; return false; } @try { if (_firstLine) { _firstLine = false; ret = [self handleFirstLine: line]; } else ret = [self handleServerHeader: line socket: (OFTCPSocket *)sock]; } @catch (id e) { [self raiseException: e]; ret = false; } return ret; } - (OFString *)stream: (OFStream *)stream didWriteString: (OFString *)string encoding: (of_string_encoding_t)encoding bytesWritten: (size_t)bytesWritten exception: (id)exception { if (exception != nil) { if ([exception isKindOfClass: [OFWriteFailedException class]] && ([exception errNo] == ECONNRESET || [exception errNo] == EPIPE)) { /* In case a keep-alive connection timed out */ [self closeAndReconnect]; return nil; } [self raiseException: exception]; return nil; } _firstLine = true; if ([_request.headers objectForKey: @"Content-Length"] != nil) { stream.delegate = nil; OFStream *requestBody = [[[OFHTTPClientRequestBodyStream alloc] initWithHandler: self socket: (OFTCPSocket *)stream] autorelease]; if ([_client->_delegate respondsToSelector: @selector(client:wantsRequestBody:request:)]) [_client->_delegate client: _client wantsRequestBody: requestBody request: _request]; } else |
︙ | ︙ | |||
598 599 600 601 602 603 604 | [sock asyncWriteString: constructRequestString(_request)]; } @catch (id e) { [self raiseException: e]; return; } } | | | | | | | | | < | | | | | | | | 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 | [sock asyncWriteString: constructRequestString(_request)]; } @catch (id e) { [self raiseException: e]; return; } } - (void)socket: (OFTCPSocket *)sock didConnectToHost: (OFString *)host port: (uint16_t)port exception: (id)exception { sock.delegate = self; if (exception != nil) { [self raiseException: exception]; return; } if ([_client->_delegate respondsToSelector: @selector(client:didCreateSocket:request:)]) [_client->_delegate client: _client didCreateSocket: sock request: _request]; [self performSelector: @selector(handleSocket:) withObject: sock afterDelay: 0]; } - (void)start { OFURL *URL = _request.URL; OFTCPSocket *sock; /* Can we reuse the last socket? */ if (_client->_socket != nil && !_client->_socket.atEndOfStream && [_client->_lastURL.scheme isEqual: URL.scheme] && [_client->_lastURL.host isEqual: URL.host] && _client->_lastURL.port == URL.port && (_client->_lastWasHEAD || _client->_lastResponse.atEndOfStream)) { /* * Set _socket to nil, so that in case of an error it won't be * reused. If everything is successful, we set _socket again * at the end. */ sock = [_client->_socket autorelease]; _client->_socket = nil; [_client->_lastURL release]; _client->_lastURL = nil; [_client->_lastResponse release]; _client->_lastResponse = nil; sock.delegate = self; [self performSelector: @selector(handleSocket:) withObject: sock afterDelay: 0]; } else [self closeAndReconnect]; } - (void)closeAndReconnect { @try { OFURL *URL = _request.URL; OFTCPSocket *sock; uint16_t port; OFNumber *URLPort; [_client close]; if ([URL.scheme isEqual: @"https"]) { if (of_tls_socket_class == Nil) @throw [OFUnsupportedProtocolException exceptionWithURL: URL]; sock = [[[of_tls_socket_class alloc] init] autorelease]; port = 443; } else { sock = [OFTCPSocket socket]; port = 80; } URLPort = URL.port; if (URLPort != nil) port = URLPort.uInt16Value; sock.delegate = self; [sock asyncConnectToHost: URL.host port: port]; } @catch (id e) { [self raiseException: e]; } } @end |
︙ | ︙ | |||
705 706 707 708 709 710 711 | OFDictionary OF_GENERIC(OFString *, OFString *) *headers; intmax_t contentLength; OFString *contentLengthString; _handler = [handler retain]; _socket = [sock retain]; | | | | 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 | OFDictionary OF_GENERIC(OFString *, OFString *) *headers; intmax_t contentLength; OFString *contentLengthString; _handler = [handler retain]; _socket = [sock retain]; headers = _handler->_request.headers; contentLengthString = [headers objectForKey: @"Content-Length"]; if (contentLengthString == nil) @throw [OFInvalidArgumentException exception]; contentLength = contentLengthString.decimalValue; if (contentLength < 0) @throw [OFOutOfRangeException exception]; _toWrite = contentLength; if ([headers objectForKey: @"Transfer-Encoding"] != nil) @throw [OFInvalidArgumentException exception]; |
︙ | ︙ | |||
790 791 792 793 794 795 796 | { if (_socket == nil) return; if (_toWrite > 0) @throw [OFTruncatedDataException exception]; | | | | 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 | { if (_socket == nil) return; if (_toWrite > 0) @throw [OFTruncatedDataException exception]; _socket.delegate = _handler; [_socket asyncReadLine]; [_socket release]; _socket = nil; } - (int)fileDescriptorForWriting { return _socket.fileDescriptorForWriting; } @end @implementation OFHTTPClientResponse @synthesize of_keepAlive = _keepAlive; - (instancetype)initWithSocket: (OFTCPSocket *)sock |
︙ | ︙ | |||
826 827 828 829 830 831 832 | [super dealloc]; } - (void)setHeaders: (OFDictionary *)headers { OFString *contentLength; | | | | 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 | [super dealloc]; } - (void)setHeaders: (OFDictionary *)headers { OFString *contentLength; super.headers = headers; _chunked = [[headers objectForKey: @"Transfer-Encoding"] isEqual: @"chunked"]; contentLength = [headers objectForKey: @"Content-Length"]; if (contentLength != nil) { _hasContentLength = true; @try { intmax_t toRead = contentLength.decimalValue; if (toRead < 0) @throw [OFInvalidServerReplyException exception]; _toRead = toRead; } @catch (OFInvalidFormatException *e) { |
︙ | ︙ | |||
862 863 864 865 866 867 868 | if (_atEndOfStream) return 0; if (!_hasContentLength && !_chunked) return [_socket readIntoBuffer: buffer length: length]; | | | 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 | if (_atEndOfStream) return 0; if (!_hasContentLength && !_chunked) return [_socket readIntoBuffer: buffer length: length]; if (_socket.atEndOfStream) @throw [OFTruncatedDataException exception]; /* Content-Length */ if (!_chunked) { size_t ret; if (length > _toRead) |
︙ | ︙ | |||
903 904 905 906 907 908 909 | length = [_socket readIntoBuffer: buffer length: length]; _toRead -= length; if (_toRead == 0) | | | 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 | length = [_socket readIntoBuffer: buffer length: length]; _toRead -= length; if (_toRead == 0) if ([_socket readLine].length > 0) @throw [OFInvalidServerReplyException exception]; return length; } else { void *pool = objc_autoreleasePoolPush(); OFString *line; |
︙ | ︙ | |||
925 926 927 928 929 930 931 | range = [line rangeOfString: @";"]; if (range.location != OF_NOT_FOUND) line = [line substringWithRange: of_range(0, range.location)]; @try { | | | | 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 | range = [line rangeOfString: @";"]; if (range.location != OF_NOT_FOUND) line = [line substringWithRange: of_range(0, range.location)]; @try { intmax_t toRead = line.hexadecimalValue; if (toRead < 0) @throw [OFOutOfRangeException exception]; _toRead = toRead; } @catch (OFInvalidFormatException *e) { @throw [OFInvalidServerReplyException exception]; } if (_toRead == 0) { _atEndOfStream = true; if (_keepAlive) { @try { line = [_socket readLine]; } @catch (OFInvalidEncodingException *e) { @throw [OFInvalidServerReplyException exception]; } if (line.length > 0) @throw [OFInvalidServerReplyException exception]; } else { [_socket release]; _socket = nil; } } |
︙ | ︙ | |||
970 971 972 973 974 975 976 | if (_atEndOfStream) return true; if (_socket == nil) @throw [OFNotOpenException exceptionWithObject: self]; if (!_hasContentLength && !_chunked) | | | | | | | | 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 | if (_atEndOfStream) return true; if (_socket == nil) @throw [OFNotOpenException exceptionWithObject: self]; if (!_hasContentLength && !_chunked) return _socket.atEndOfStream; return _atEndOfStream; } - (int)fileDescriptorForReading { if (_socket == nil) return -1; return _socket.fileDescriptorForReading; } - (bool)hasDataInReadBuffer { return (super.hasDataInReadBuffer || _socket.hasDataInReadBuffer); } - (void)close { _atEndOfStream = false; [_socket release]; _socket = nil; [super close]; } @end @implementation OFHTTPClient_SyncPerformer - (instancetype)initWithClient: (OFHTTPClient *)client { self = [super init]; @try { _client = [client retain]; _delegate = client.delegate; _client.delegate = self; } @catch (id e) { [self release]; @throw e; } return self; } - (void)dealloc { _client.delegate = _delegate; [_client release]; [super dealloc]; } - (OFHTTPResponse *)performRequest: (OFHTTPRequest *)request redirects: (unsigned int)redirects |
︙ | ︙ | |||
1059 1060 1061 1062 1063 1064 1065 | request: (OFHTTPRequest *)request { /* * Restore the delegate - we're giving up, but not reaching the release * of the autorelease pool that contains us, so resetting it via * -[dealloc] might be too late. */ | | | | 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 | request: (OFHTTPRequest *)request { /* * Restore the delegate - we're giving up, but not reaching the release * of the autorelease pool that contains us, so resetting it via * -[dealloc] might be too late. */ _client.delegate = _delegate; @throw exception; } - (void)client: (OFHTTPClient *)client didCreateSocket: (OFTCPSocket *)sock request: (OFHTTPRequest *)request { if ([_delegate respondsToSelector: @selector(client:didCreateSocket:request:)]) [_delegate client: client didCreateSocket: sock request: request]; |
︙ | ︙ | |||
1113 1114 1115 1116 1117 1118 1119 | shouldFollowRedirect:statusCode:request:response:)]) return [_delegate client: client shouldFollowRedirect: URL statusCode: statusCode request: request response: response]; else | | | 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 | shouldFollowRedirect:statusCode:request:response:)]) return [_delegate client: client shouldFollowRedirect: URL statusCode: statusCode request: request response: response]; else return defaultShouldFollow(request.method, statusCode); } @end @implementation OFHTTPClient @synthesize delegate = _delegate; @synthesize insecureRedirectsAllowed = _insecureRedirectsAllowed; |
︙ | ︙ | |||
1166 1167 1168 1169 1170 1171 1172 | redirects: REDIRECTS_DEFAULT]; } - (void)asyncPerformRequest: (OFHTTPRequest *)request redirects: (unsigned int)redirects { void *pool = objc_autoreleasePoolPush(); | | | | 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 | redirects: REDIRECTS_DEFAULT]; } - (void)asyncPerformRequest: (OFHTTPRequest *)request redirects: (unsigned int)redirects { void *pool = objc_autoreleasePoolPush(); OFURL *URL = request.URL; OFString *scheme = URL.scheme; if (![scheme isEqual: @"http"] && ![scheme isEqual: @"https"]) @throw [OFUnsupportedProtocolException exceptionWithURL: URL]; if (_inProgress) /* TODO: Find a better exception */ @throw [OFAlreadyConnectedException exception]; |
︙ | ︙ |
Modified src/OFHTTPCookie.m from [26fae4bc2d] to [09fd3cd222].
︙ | ︙ | |||
24 25 26 27 28 29 30 | #import "OFURL.h" #import "OFInvalidFormatException.h" static void handleAttribute(OFHTTPCookie *cookie, OFString *name, OFString *value) { | | | | | | | | | | | | | | | | 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 | #import "OFURL.h" #import "OFInvalidFormatException.h" static void handleAttribute(OFHTTPCookie *cookie, OFString *name, OFString *value) { OFString *lowercaseName = name.lowercaseString; if (value != nil) { if ([lowercaseName isEqual: @"expires"]) { OFDate *date = [OFDate dateWithDateString: value format: @"%a, %d %b %Y %H:%M:%S %z"]; cookie.expires = date; } else if ([lowercaseName isEqual: @"max-age"]) { OFDate *date = [OFDate dateWithTimeIntervalSinceNow: value.decimalValue]; cookie.expires = date; } else if ([lowercaseName isEqual: @"domain"]) cookie.domain = value; else if ([lowercaseName isEqual: @"path"]) cookie.path = value; else [cookie.extensions addObject: [OFString stringWithFormat: @"%@=%@", name, value]]; } else { if ([lowercaseName isEqual: @"secure"]) cookie.secure = true; else if ([lowercaseName isEqual: @"httponly"]) cookie.HTTPOnly = true; else if (name.length > 0) [cookie.extensions addObject: name]; } } @implementation OFHTTPCookie @synthesize name = _name, value = _value, domain = _domain, path = _path; @synthesize expires = _expires, secure = _secure, HTTPOnly = _HTTPOnly; @synthesize extensions = _extensions; + (OFArray OF_GENERIC(OFHTTPCookie *) *)cookiesWithResponseHeaderFields: (OFDictionary OF_GENERIC(OFString *, OFString *) *)headerFields forURL: (OFURL *)URL { OFMutableArray OF_GENERIC(OFHTTPCookie *) *ret = [OFMutableArray array]; void *pool = objc_autoreleasePoolPush(); OFString *string = [headerFields objectForKey: @"Set-Cookie"]; OFString *domain = URL.host; const of_unichar_t *characters = string.characters; size_t length = string.length, last = 0; enum { STATE_PRE_NAME, STATE_NAME, STATE_EXPECT_VALUE, STATE_VALUE, STATE_QUOTED_VALUE, STATE_POST_QUOTED_VALUE, |
︙ | ︙ | |||
162 163 164 165 166 167 168 | state = STATE_ATTR_VALUE; last = i + 1; } else if (characters[i] == ';' || characters[i] == ',') { name = [string substringWithRange: of_range(last, i - last)]; | | | | | 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 | state = STATE_ATTR_VALUE; last = i + 1; } else if (characters[i] == ';' || characters[i] == ',') { name = [string substringWithRange: of_range(last, i - last)]; handleAttribute(ret.lastObject, name, nil); state = (characters[i] == ';' ? STATE_PRE_ATTR_NAME : STATE_PRE_NAME); } break; case STATE_ATTR_VALUE: if (characters[i] == ';' || characters[i] == ',') { value = [string substringWithRange: of_range(last, i - last)]; /* * Expires often contains a comma, even though * the comma is used as a separator for * concatenating headers as per RFC 2616, * meaning RFC 6265 contradicts RFC 2616. * Solve this by special casing this. */ if (characters[i] == ',' && [name caseInsensitiveCompare: @"expires"] == OF_ORDERED_SAME && value.length == 3 && ([value isEqual: @"Mon"] || [value isEqual: @"Tue"] || [value isEqual: @"Wed"] || [value isEqual: @"Thu"] || [value isEqual: @"Fri"] || [value isEqual: @"Sat"] || [value isEqual: @"Sun"])) break; handleAttribute(ret.lastObject, name, value); state = (characters[i] == ';' ? STATE_PRE_ATTR_NAME : STATE_PRE_NAME); } break; } } |
︙ | ︙ | |||
229 230 231 232 233 234 235 | domain: domain]]; break; case STATE_ATTR_NAME: if (last != length) { name = [string substringWithRange: of_range(last, length - last)]; | | | | | | | 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 | domain: domain]]; break; case STATE_ATTR_NAME: if (last != length) { name = [string substringWithRange: of_range(last, length - last)]; handleAttribute(ret.lastObject, name, nil); } break; case STATE_ATTR_VALUE: value = [string substringWithRange: of_range(last, length - last)]; handleAttribute(ret.lastObject, name, value); break; } objc_autoreleasePoolPop(pool); return ret; } + (OFDictionary *)requestHeaderFieldsWithCookies: (OFArray OF_GENERIC(OFHTTPCookie *) *)cookies { OFDictionary OF_GENERIC(OFString *, OFString *) *ret; void *pool; OFMutableString *cookieString; bool first = true; if (cookies.count == 0) return [OFDictionary dictionary]; pool = objc_autoreleasePoolPush(); cookieString = [OFMutableString string]; for (OFHTTPCookie *cookie in cookies) { if OF_UNLIKELY (first) first = false; else [cookieString appendString: @"; "]; [cookieString appendString: cookie.name]; [cookieString appendString: @"="]; [cookieString appendString: cookie.value]; } ret = [[OFDictionary alloc] initWithObject: cookieString forKey: @"Cookie"]; objc_autoreleasePoolPop(pool); |
︙ | ︙ | |||
364 365 366 367 368 369 370 | } - (uint32_t)hash { uint32_t hash; OF_HASH_INIT(hash); | | | | | | | | 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 | } - (uint32_t)hash { uint32_t hash; OF_HASH_INIT(hash); OF_HASH_ADD_HASH(hash, _name.hash); OF_HASH_ADD_HASH(hash, _value.hash); OF_HASH_ADD_HASH(hash, _domain.hash); OF_HASH_ADD_HASH(hash, _path.hash); OF_HASH_ADD_HASH(hash, _expires.hash); OF_HASH_ADD(hash, _secure); OF_HASH_ADD(hash, _HTTPOnly); OF_HASH_ADD_HASH(hash, _extensions.hash); OF_HASH_FINALIZE(hash); return hash; } - (id)copy { |
︙ | ︙ | |||
416 417 418 419 420 421 422 | if (_secure) [ret appendString: @"; Secure"]; if (_HTTPOnly) [ret appendString: @"; HTTPOnly"]; | | | 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 | if (_secure) [ret appendString: @"; Secure"]; if (_HTTPOnly) [ret appendString: @"; HTTPOnly"]; if (_extensions.count > 0) [ret appendFormat: @"; %@", [_extensions componentsJoinedByString: @"; "]]; objc_autoreleasePoolPop(pool); [ret makeImmutable]; return ret; } @end |
Modified src/OFHTTPCookieManager.m from [e598ba5279] to [41a76d5b5b].
︙ | ︙ | |||
58 59 60 61 62 63 64 | - (void)addCookie: (OFHTTPCookie *)cookie forURL: (OFURL *)URL { void *pool = objc_autoreleasePoolPush(); OFString *cookieDomain, *URLHost; size_t i; | | | | | | | | | | | 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 | - (void)addCookie: (OFHTTPCookie *)cookie forURL: (OFURL *)URL { void *pool = objc_autoreleasePoolPush(); OFString *cookieDomain, *URLHost; size_t i; if (![cookie.path hasPrefix: @"/"]) cookie.path = @"/"; if (cookie.secure && ![URL.scheme isEqual: @"https"]) { objc_autoreleasePoolPop(pool); return; } cookieDomain = cookie.domain.lowercaseString; cookie.domain = cookieDomain; URLHost = URL.host.lowercaseString; if (![cookieDomain isEqual: URLHost]) { URLHost = [@"." stringByAppendingString: URLHost]; if (![cookieDomain hasSuffix: URLHost]) { objc_autoreleasePoolPop(pool); return; } } i = 0; for (OFHTTPCookie *iter in _cookies) { if ([iter.name isEqual: cookie.name] && [iter.domain isEqual: cookie.domain] && [iter.path isEqual: cookie.path]) { [_cookies replaceObjectAtIndex: i withObject: cookie]; objc_autoreleasePoolPop(pool); return; } |
︙ | ︙ | |||
117 118 119 120 121 122 123 | for (OFHTTPCookie *cookie in _cookies) { void *pool; OFDate *expires; OFString *cookieDomain, *URLHost, *cookiePath, *URLPath; bool match; | | | | | | | | | | 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 | for (OFHTTPCookie *cookie in _cookies) { void *pool; OFDate *expires; OFString *cookieDomain, *URLHost, *cookiePath, *URLPath; bool match; expires = cookie.expires; if (expires != nil && expires.timeIntervalSinceNow <= 0) continue; if (cookie.secure && ![URL.scheme isEqual: @"https"]) continue; pool = objc_autoreleasePoolPush(); cookieDomain = cookie.domain.lowercaseString; URLHost = URL.host.lowercaseString; if ([cookieDomain hasPrefix: @"."]) { if ([URLHost hasSuffix: cookieDomain]) match = true; else { cookieDomain = [cookieDomain substringWithRange: of_range(1, cookieDomain.length - 1)]; match = [cookieDomain isEqual: URLHost]; } } else match = [cookieDomain isEqual: URLHost]; if (!match) { objc_autoreleasePoolPop(pool); continue; } cookiePath = cookie.path; URLPath = URL.path; if (![cookiePath isEqual: @"/"]) { if ([cookiePath isEqual: URLPath]) match = true; else { if (![cookiePath hasSuffix: @"/"]) cookiePath = [cookiePath stringByAppendingString: @"/"]; |
︙ | ︙ | |||
174 175 176 177 178 179 180 | [ret makeImmutable]; return ret; } - (void)purgeExpiredCookies { | | | | 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 | [ret makeImmutable]; return ret; } - (void)purgeExpiredCookies { for (size_t i = 0, count = _cookies.count; i < count; i++) { OFDate *expires = [[_cookies objectAtIndex: i] expires]; if (expires != nil && expires.timeIntervalSinceNow <= 0) { [_cookies removeObjectAtIndex: i]; i--; count--; continue; } } } @end |
Modified src/OFHTTPRequest.m from [8752774259] to [e973ddf9ac].
︙ | ︙ | |||
137 138 139 140 141 142 143 | - (id)copy { OFHTTPRequest *copy = [[OFHTTPRequest alloc] init]; @try { copy->_method = _method; copy->_protocolVersion = _protocolVersion; | | | | | 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 | - (id)copy { OFHTTPRequest *copy = [[OFHTTPRequest alloc] init]; @try { copy->_method = _method; copy->_protocolVersion = _protocolVersion; copy.URL = _URL; copy.headers = _headers; copy.remoteAddress = &_remoteAddress; } @catch (id e) { [copy release]; @throw e; } return copy; } |
︙ | ︙ | |||
180 181 182 183 184 185 186 | uint32_t hash; OF_HASH_INIT(hash); OF_HASH_ADD(hash, _method); OF_HASH_ADD(hash, _protocolVersion.major); OF_HASH_ADD(hash, _protocolVersion.minor); | | | | 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 | uint32_t hash; OF_HASH_INIT(hash); OF_HASH_ADD(hash, _method); OF_HASH_ADD(hash, _protocolVersion.major); OF_HASH_ADD(hash, _protocolVersion.minor); OF_HASH_ADD_HASH(hash, _URL.hash); OF_HASH_ADD_HASH(hash, _headers.hash); OF_HASH_ADD_HASH(hash, of_socket_address_hash(&_remoteAddress)); OF_HASH_FINALIZE(hash); return hash; } |
︙ | ︙ | |||
212 213 214 215 216 217 218 | - (void)setProtocolVersionString: (OFString *)string { void *pool = objc_autoreleasePoolPush(); OFArray *components = [string componentsSeparatedByString: @"."]; intmax_t major, minor; of_http_request_protocol_version_t protocolVersion; | | | | | | | | 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 | - (void)setProtocolVersionString: (OFString *)string { void *pool = objc_autoreleasePoolPush(); OFArray *components = [string componentsSeparatedByString: @"."]; intmax_t major, minor; of_http_request_protocol_version_t protocolVersion; if (components.count != 2) @throw [OFInvalidFormatException exception]; major = [components.firstObject decimalValue]; minor = [components.lastObject decimalValue]; if (major < 0 || major > UINT8_MAX || minor < 0 || minor > UINT8_MAX) @throw [OFOutOfRangeException exception]; protocolVersion.major = (uint8_t)major; protocolVersion.minor = (uint8_t)minor; self.protocolVersion = protocolVersion; objc_autoreleasePoolPop(pool); } - (OFString *)protocolVersionString { return [OFString stringWithFormat: @"%u.%u", _protocolVersion.major, _protocolVersion.minor]; } - (OFString *)description { void *pool = objc_autoreleasePoolPush(); const char *method = of_http_request_method_to_string(_method); OFString *indentedHeaders, *ret; indentedHeaders = [_headers.description stringByReplacingOccurrencesOfString: @"\n" withString: @"\n\t"]; ret = [[OFString alloc] initWithFormat: @"<%@:\n\tURL = %@\n" @"\tMethod = %s\n" @"\tHeaders = %@\n" @"\tRemote address = %@\n" @">", self.class, _URL, method, indentedHeaders, of_socket_address_ip_string(&_remoteAddress, NULL)]; objc_autoreleasePoolPop(pool); return [ret autorelease]; } @end |
Modified src/OFHTTPResponse.m from [5a8bf08410] to [883113a592].
︙ | ︙ | |||
28 29 30 31 32 33 34 | #import "OFOutOfRangeException.h" #import "OFTruncatedDataException.h" #import "OFUnsupportedVersionException.h" static of_string_encoding_t encodingForContentType(OFString *contentType) { | | | | 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | #import "OFOutOfRangeException.h" #import "OFTruncatedDataException.h" #import "OFUnsupportedVersionException.h" static of_string_encoding_t encodingForContentType(OFString *contentType) { const char *UTF8String = contentType.UTF8String; size_t last, length = contentType.UTF8StringLength; enum { STATE_TYPE, STATE_BEFORE_PARAM_NAME, STATE_PARAM_NAME, STATE_PARAM_VALUE_OR_QUOTE, STATE_PARAM_VALUE, STATE_PARAM_QUOTED_VALUE, |
︙ | ︙ | |||
83 84 85 86 87 88 89 | } break; case STATE_PARAM_VALUE: if (UTF8String[i] == ';') { value = [OFString stringWithUTF8String: UTF8String + last length: i - last]; | | | | 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 | } break; case STATE_PARAM_VALUE: if (UTF8String[i] == ';') { value = [OFString stringWithUTF8String: UTF8String + last length: i - last]; value = value.stringByDeletingTrailingWhitespaces; if ([name isEqual: @"charset"]) charset = value; state = STATE_BEFORE_PARAM_NAME; last = i + 1; } |
︙ | ︙ | |||
117 118 119 120 121 122 123 | return OF_STRING_ENCODING_AUTODETECT; break; } } if (state == STATE_PARAM_VALUE) { value = [OFString stringWithUTF8String: UTF8String + last length: length - last]; | | | 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 | return OF_STRING_ENCODING_AUTODETECT; break; } } if (state == STATE_PARAM_VALUE) { value = [OFString stringWithUTF8String: UTF8String + last length: length - last]; value = value.stringByDeletingTrailingWhitespaces; if ([name isEqual: @"charset"]) charset = value; } @try { ret = of_string_parse_encoding(charset); |
︙ | ︙ | |||
181 182 183 184 185 186 187 | - (void)setProtocolVersionString: (OFString *)string { void *pool = objc_autoreleasePoolPush(); OFArray *components = [string componentsSeparatedByString: @"."]; intmax_t major, minor; of_http_request_protocol_version_t protocolVersion; | | | | | | 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 | - (void)setProtocolVersionString: (OFString *)string { void *pool = objc_autoreleasePoolPush(); OFArray *components = [string componentsSeparatedByString: @"."]; intmax_t major, minor; of_http_request_protocol_version_t protocolVersion; if (components.count != 2) @throw [OFInvalidFormatException exception]; major = [components.firstObject decimalValue]; minor = [components.lastObject decimalValue]; if (major < 0 || major > UINT8_MAX || minor < 0 || minor > UINT8_MAX) @throw [OFOutOfRangeException exception]; protocolVersion.major = (uint8_t)major; protocolVersion.minor = (uint8_t)minor; self.protocolVersion = protocolVersion; objc_autoreleasePoolPop(pool); } - (OFString *)protocolVersionString { return [OFString stringWithFormat: @"%u.%u", |
︙ | ︙ | |||
226 227 228 229 230 231 232 | if (encoding == OF_STRING_ENCODING_AUTODETECT) encoding = OF_STRING_ENCODING_UTF_8; data = [self readDataUntilEndOfStream]; if ((contentLength = [_headers objectForKey: @"Content-Length"]) != 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 | if (encoding == OF_STRING_ENCODING_AUTODETECT) encoding = OF_STRING_ENCODING_UTF_8; data = [self readDataUntilEndOfStream]; if ((contentLength = [_headers objectForKey: @"Content-Length"]) != nil) if (data.count != (size_t)contentLength.decimalValue) @throw [OFTruncatedDataException exception]; ret = [[OFString alloc] initWithCString: (char *)data.items encoding: encoding length: data.count]; objc_autoreleasePoolPop(pool); return [ret autorelease]; } - (OFString *)description { void *pool = objc_autoreleasePoolPush(); OFString *indentedHeaders, *ret; indentedHeaders = [_headers.description stringByReplacingOccurrencesOfString: @"\n" withString: @"\n\t"]; ret = [[OFString alloc] initWithFormat: @"<%@:\n" @"\tStatus code = %d\n" @"\tHeaders = %@\n" @">", self.class, _statusCode, indentedHeaders]; objc_autoreleasePoolPop(pool); return [ret autorelease]; } @end |
Modified src/OFHTTPServer.h from [3b876afaf6] to [3394497349].
︙ | ︙ | |||
95 96 97 98 99 100 101 | OFString *_Nullable _host; uint16_t _port; bool _usesTLS; OFString *_Nullable _certificateFile, *_Nullable _privateKeyFile; const char *_Nullable _privateKeyPassphrase; id <OFHTTPServerDelegate> _Nullable _delegate; OFString *_Nullable _name; | | | 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 | OFString *_Nullable _host; uint16_t _port; bool _usesTLS; OFString *_Nullable _certificateFile, *_Nullable _privateKeyFile; const char *_Nullable _privateKeyPassphrase; id <OFHTTPServerDelegate> _Nullable _delegate; OFString *_Nullable _name; OFTCPSocket *_Nullable _listeningSocket; #ifdef OF_HAVE_THREADS size_t _numberOfThreads, _nextThreadIndex; OFArray *_threadPool; #endif } /*! |
︙ | ︙ |
Modified src/OFHTTPServer.m from [503afee9ba] to [3cdaff788f].
︙ | ︙ | |||
53 54 55 56 57 58 59 | */ @interface OFHTTPServer () <OFTCPSocketDelegate> @end @interface OFHTTPServerResponse: OFHTTPResponse <OFReadyForWritingObserving> { | | | | | | | | 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 | */ @interface OFHTTPServer () <OFTCPSocketDelegate> @end @interface OFHTTPServerResponse: OFHTTPResponse <OFReadyForWritingObserving> { OFTCPSocket *_socket; OFHTTPServer *_server; OFHTTPRequest *_request; bool _chunked, _headersSent; } - (instancetype)initWithSocket: (OFTCPSocket *)sock server: (OFHTTPServer *)server request: (OFHTTPRequest *)request; @end @interface OFHTTPServer_Connection: OFObject <OFTCPSocketDelegate> { @public OFTCPSocket *_socket; OFHTTPServer *_server; OFTimer *_timer; enum { AWAITING_PROLOG, PARSING_HEADERS, SEND_RESPONSE } _state; uint8_t _HTTPMinorVersion; of_http_request_method_t _method; OFString *_host, *_path; uint16_t _port; OFMutableDictionary *_headers; size_t _contentLength; OFStream *_requestBody; } - (instancetype)initWithSocket: (OFTCPSocket *)sock server: (OFHTTPServer *)server; - (bool)parseProlog: (OFString *)line; - (bool)parseHeaders: (OFString *)line; - (bool)sendErrorAndClose: (short)statusCode; - (void)createResponse; @end @interface OFHTTPServerRequestBodyStream: OFStream <OFReadyForReadingObserving> { OFTCPSocket *_socket; uintmax_t _toRead; bool _atEndOfStream; } - (instancetype)initWithSocket: (OFTCPSocket *)sock contentLength: (uintmax_t)contentLength; @end #ifdef OF_HAVE_THREADS @interface OFHTTPServerThread: OFThread - (void)stop; @end |
︙ | ︙ | |||
201 202 203 204 205 206 207 | return NULL; } } static OF_INLINE OFString * normalizedKey(OFString *key) { | | | | 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 | return NULL; } } static OF_INLINE OFString * normalizedKey(OFString *key) { char *cString = of_strdup(key.UTF8String); unsigned char *tmp = (unsigned char *)cString; bool firstLetter = true; if (cString == NULL) @throw [OFOutOfMemoryException exceptionWithRequestedSize: strlen(key.UTF8String)]; while (*tmp != '\0') { if (!of_ascii_isalpha(*tmp)) { firstLetter = true; tmp++; continue; } |
︙ | ︙ | |||
229 230 231 232 233 234 235 | } return [OFString stringWithUTF8StringNoCopy: cString freeWhenDone: true]; } @implementation OFHTTPServerResponse | | | 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 | } return [OFString stringWithUTF8StringNoCopy: cString freeWhenDone: true]; } @implementation OFHTTPServerResponse - (instancetype)initWithSocket: (OFTCPSocket *)sock server: (OFHTTPServer *)server request: (OFHTTPRequest *)request { self = [super init]; _statusCode = 500; _socket = [sock retain]; |
︙ | ︙ | |||
262 263 264 265 266 267 268 | { void *pool = objc_autoreleasePoolPush(); OFMutableDictionary OF_GENERIC(OFString *, OFString *) *headers; OFEnumerator *keyEnumerator, *valueEnumerator; OFString *key, *value; [_socket writeFormat: @"HTTP/%@ %d %s\r\n", | | | | 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 | { void *pool = objc_autoreleasePoolPush(); OFMutableDictionary OF_GENERIC(OFString *, OFString *) *headers; OFEnumerator *keyEnumerator, *valueEnumerator; OFString *key, *value; [_socket writeFormat: @"HTTP/%@ %d %s\r\n", self.protocolVersionString, _statusCode, statusCodeToString(_statusCode)]; headers = [[_headers mutableCopy] autorelease]; if ([headers objectForKey: @"Date"] == nil) { OFString *date = [[OFDate date] dateStringWithFormat: @"%a, %d %b %Y %H:%M:%S GMT"]; [headers setObject: date forKey: @"Date"]; } if ([headers objectForKey: @"Server"] == nil) { OFString *name = _server.name; if (name != nil) [headers setObject: name forKey: @"Server"]; } keyEnumerator = [headers keyEnumerator]; |
︙ | ︙ | |||
340 341 342 343 344 345 346 | if (!_headersSent) [self of_sendHeaders]; if (_chunked) [_socket writeBuffer: "0\r\n\r\n" length: 5]; } @catch (OFWriteFailedException *e) { | | | | | 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 | if (!_headersSent) [self of_sendHeaders]; if (_chunked) [_socket writeBuffer: "0\r\n\r\n" length: 5]; } @catch (OFWriteFailedException *e) { id <OFHTTPServerDelegate> delegate = _server.delegate; if ([delegate respondsToSelector: @selector(server: didReceiveExceptionForResponse:request:exception:)]) [delegate server: _server didReceiveExceptionForResponse: self request: _request exception: e]; } [_socket release]; _socket = nil; [super close]; } - (int)fileDescriptorForWriting { if (_socket == nil) return -1; return _socket.fileDescriptorForWriting; } @end @implementation OFHTTPServer_Connection - (instancetype)initWithSocket: (OFTCPSocket *)sock server: (OFHTTPServer *)server { self = [super init]; @try { _socket = [sock retain]; _server = [server retain]; |
︙ | ︙ | |||
405 406 407 408 409 410 411 | [_path release]; [_headers release]; [_requestBody release]; [super dealloc]; } | | | 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 | [_path release]; [_headers release]; [_requestBody release]; [super dealloc]; } - (bool)stream: (OFStream *)sock didReadLine: (OFString *)line exception: (id)exception { if (line == nil || exception != nil) return false; @try { |
︙ | ︙ | |||
436 437 438 439 440 441 442 | { OFString *method; OFMutableString *path; size_t pos; @try { OFString *version = [line | | | < | | 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 | { OFString *method; OFMutableString *path; size_t pos; @try { OFString *version = [line substringWithRange: of_range(line.length - 9, 9)]; of_unichar_t tmp; if (![version hasPrefix: @" HTTP/1."]) return [self sendErrorAndClose: 505]; tmp = [version characterAtIndex: 8]; if (tmp < '0' || tmp > '9') return [self sendErrorAndClose: 400]; _HTTPMinorVersion = (uint8_t)(tmp - '0'); } @catch (OFOutOfRangeException *e) { return [self sendErrorAndClose: 400]; } pos = [line rangeOfString: @" "].location; if (pos == OF_NOT_FOUND) return [self sendErrorAndClose: 400]; method = [line substringWithRange: of_range(0, pos)]; @try { _method = of_http_request_method_from_string(method.UTF8String); } @catch (OFInvalidFormatException *e) { return [self sendErrorAndClose: 405]; } @try { of_range_t range = of_range(pos + 1, line.length - pos - 10); path = [[[line substringWithRange: range] mutableCopy] autorelease]; } @catch (OFOutOfRangeException *e) { return [self sendErrorAndClose: 400]; } |
︙ | ︙ | |||
490 491 492 493 494 495 496 | } - (bool)parseHeaders: (OFString *)line { OFString *key, *value, *old; size_t pos; | | | | 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 | } - (bool)parseHeaders: (OFString *)line { OFString *key, *value, *old; size_t pos; if (line.length == 0) { OFString *contentLengthString; if ((contentLengthString = [_headers objectForKey: @"Content-Length"]) != nil) { intmax_t contentLength; @try { contentLength = contentLengthString.decimalValue; } @catch (OFInvalidFormatException *e) { return [self sendErrorAndClose: 400]; } if (contentLength < 0) return [self sendErrorAndClose: 400]; |
︙ | ︙ | |||
531 532 533 534 535 536 537 | pos = [line rangeOfString: @":"].location; if (pos == OF_NOT_FOUND) return [self sendErrorAndClose: 400]; key = [line substringWithRange: of_range(0, pos)]; value = [line substringWithRange: | | | | | | | | 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 | pos = [line rangeOfString: @":"].location; if (pos == OF_NOT_FOUND) return [self sendErrorAndClose: 400]; key = [line substringWithRange: of_range(0, pos)]; value = [line substringWithRange: of_range(pos + 1, line.length - pos - 1)]; key = normalizedKey(key.stringByDeletingTrailingWhitespaces); value = value.stringByDeletingLeadingWhitespaces; old = [_headers objectForKey: key]; if (old != nil) value = [old stringByAppendingFormat: @",%@", value]; [_headers setObject: value forKey: key]; if ([key isEqual: @"Host"]) { pos = [value rangeOfString: @":" options: OF_STRING_SEARCH_BACKWARDS].location; if (pos != OF_NOT_FOUND) { [_host release]; _host = [[value substringWithRange: of_range(0, pos)] retain]; @try { of_range_t range = of_range(pos + 1, value.length - pos - 1); intmax_t portTmp = [value substringWithRange: range].decimalValue; if (portTmp < 1 || portTmp > UINT16_MAX) return [self sendErrorAndClose: 400]; _port = (uint16_t)portTmp; } @catch (OFInvalidFormatException *e) { return [self sendErrorAndClose: 400]; |
︙ | ︙ | |||
586 587 588 589 590 591 592 | dateStringWithFormat: @"%a, %d %b %Y %H:%M:%S GMT"]; [_socket writeFormat: @"HTTP/1.1 %d %s\r\n" @"Date: %@\r\n" @"Server: %@\r\n" @"\r\n", statusCode, statusCodeToString(statusCode), | | | 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 | dateStringWithFormat: @"%a, %d %b %Y %H:%M:%S GMT"]; [_socket writeFormat: @"HTTP/1.1 %d %s\r\n" @"Date: %@\r\n" @"Server: %@\r\n" @"\r\n", statusCode, statusCodeToString(statusCode), date, _server.name]; return false; } - (void)createResponse { void *pool = objc_autoreleasePoolPush(); |
︙ | ︙ | |||
610 611 612 613 614 615 616 | if (_host == nil || _port == 0) { if (_HTTPMinorVersion > 0) { [self sendErrorAndClose: 400]; return; } [_host release]; | | | | | | | | | | | | | | | | | | | | 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 | if (_host == nil || _port == 0) { if (_HTTPMinorVersion > 0) { [self sendErrorAndClose: 400]; return; } [_host release]; _host = [_server.host copy]; _port = [_server port]; } URL = [OFMutableURL URL]; URL.scheme = @"http"; URL.host = _host; if (_port != 80) URL.port = [OFNumber numberWithUInt16: _port]; if ((pos = [_path rangeOfString: @"?"].location) != OF_NOT_FOUND) { OFString *path, *query; path = [_path substringWithRange: of_range(0, pos)]; query = [_path substringWithRange: of_range(pos + 1, _path.length - pos - 1)]; URL.URLEncodedPath = path; URL.URLEncodedQuery = query; } else URL.URLEncodedPath = _path; [URL makeImmutable]; request = [OFHTTPRequest requestWithURL: URL]; request.method = _method; request.protocolVersion = (of_http_request_protocol_version_t){ 1, _HTTPMinorVersion }; request.headers = _headers; request.remoteAddress = _socket.remoteAddress; response = [[[OFHTTPServerResponse alloc] initWithSocket: _socket server: _server request: request] autorelease]; [_server.delegate server: _server didReceiveRequest: request requestBody: _requestBody response: response]; objc_autoreleasePoolPop(pool); } @end @implementation OFHTTPServerRequestBodyStream - (instancetype)initWithSocket: (OFTCPSocket *)sock contentLength: (uintmax_t)contentLength { self = [super init]; @try { _socket = [sock retain]; _toRead = contentLength; |
︙ | ︙ | |||
707 708 709 710 711 712 713 | _toRead -= ret; return ret; } - (bool)hasDataInReadBuffer { | | | | 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 | _toRead -= ret; return ret; } - (bool)hasDataInReadBuffer { return (super.hasDataInReadBuffer || _socket.hasDataInReadBuffer); } - (int)fileDescriptorForReading { return _socket.fileDescriptorForReading; } - (void)close { [_socket release]; _socket = nil; } |
︙ | ︙ | |||
855 856 857 858 859 860 861 | - (const char *)privateKeyPassphrase { return _privateKeyPassphrase; } #ifdef OF_HAVE_THREADS | | | | | | > < | | < | | 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 | - (const char *)privateKeyPassphrase { return _privateKeyPassphrase; } #ifdef OF_HAVE_THREADS - (void)setNumberOfThreads: (size_t)numberOfThreads { if (numberOfThreads == 0) @throw [OFInvalidArgumentException exception]; if (_listeningSocket != nil) @throw [OFAlreadyConnectedException exception]; _numberOfThreads = numberOfThreads; } - (size_t)numberOfThreads { return _numberOfThreads; } #endif - (void)start { void *pool = objc_autoreleasePoolPush(); if (_host == nil) @throw [OFInvalidArgumentException exception]; if (_listeningSocket != nil) @throw [OFAlreadyConnectedException exception]; if (_usesTLS) { OFTCPSocket <OFTLSSocket> *TLSSocket; if (of_tls_socket_class == Nil) @throw [OFUnsupportedProtocolException exception]; TLSSocket = [[of_tls_socket_class alloc] init]; _listeningSocket = TLSSocket; TLSSocket.certificateFile = _certificateFile; TLSSocket.privateKeyFile = _privateKeyFile; TLSSocket.privateKeyPassphrase = _privateKeyPassphrase; } else _listeningSocket = [[OFTCPSocket alloc] init]; _port = [_listeningSocket bindToHost: _host port: _port]; [_listeningSocket listen]; |
︙ | ︙ | |||
920 921 922 923 924 925 926 | } [threads makeImmutable]; _threadPool = [threads copy]; } #endif | | | | | | | 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 | } [threads makeImmutable]; _threadPool = [threads copy]; } #endif ((OFTCPSocket *)_listeningSocket).delegate = self; [_listeningSocket asyncAccept]; objc_autoreleasePoolPop(pool); } - (void)stop { [_listeningSocket cancelAsyncRequests]; [_listeningSocket release]; _listeningSocket = nil; #ifdef OF_HAVE_THREADS for (OFHTTPServerThread *thread in _threadPool) [thread stop]; [_threadPool release]; _threadPool = nil; #endif } - (void)of_handleAcceptedSocket: (OFTCPSocket *)acceptedSocket { OFHTTPServer_Connection *connection = [[[OFHTTPServer_Connection alloc] initWithSocket: acceptedSocket server: self] autorelease]; acceptedSocket.delegate = connection; [acceptedSocket asyncReadLine]; } - (bool)socket: (OFTCPSocket *)sock didAcceptSocket: (OFTCPSocket *)acceptedSocket exception: (id)exception { if (exception != nil) { if (![_delegate respondsToSelector: @selector(server:didReceiveExceptionOnListeningSocket:)]) return false; |
︙ | ︙ |
Modified src/OFINICategory.m from [1a0915adbe] to [aa5333e1f9].
︙ | ︙ | |||
77 78 79 80 81 82 83 | unescapeString(OFString *string) { OFMutableString *mutableString; if (![string hasPrefix: @"\""] || ![string hasSuffix: @"\""]) return string; | | | 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 | unescapeString(OFString *string) { OFMutableString *mutableString; if (![string hasPrefix: @"\""] || ![string hasSuffix: @"\""]) return string; string = [string substringWithRange: of_range(1, string.length - 2)]; mutableString = [[string mutableCopy] autorelease]; [mutableString replaceOccurrencesOfString: @"\\f" withString: @"\f"]; [mutableString replaceOccurrencesOfString: @"\\r" withString: @"\r"]; [mutableString replaceOccurrencesOfString: @"\\n" |
︙ | ︙ | |||
159 160 161 162 163 164 165 | size_t pos; if ((pos = [line rangeOfString: @"="].location) == OF_NOT_FOUND) @throw [OFInvalidFormatException exception]; key = [line substringWithRange: of_range(0, pos)]; value = [line substringWithRange: | | | | | 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 | size_t pos; if ((pos = [line rangeOfString: @"="].location) == OF_NOT_FOUND) @throw [OFInvalidFormatException exception]; key = [line substringWithRange: of_range(0, pos)]; value = [line substringWithRange: of_range(pos + 1, line.length - pos - 1)]; key = key.stringByDeletingEnclosingWhitespaces; value = value.stringByDeletingEnclosingWhitespaces; key = unescapeString(key); value = unescapeString(value); pair->_key = [key copy]; pair->_value = [value copy]; |
︙ | ︙ | |||
215 216 217 218 219 220 221 | void *pool = objc_autoreleasePoolPush(); OFString *value = [self stringForKey: key defaultValue: nil]; intmax_t ret; if (value != nil) { if ([value hasPrefix: @"0x"] || [value hasPrefix: @"$"]) | | | | 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 | void *pool = objc_autoreleasePoolPush(); OFString *value = [self stringForKey: key defaultValue: nil]; intmax_t ret; if (value != nil) { if ([value hasPrefix: @"0x"] || [value hasPrefix: @"$"]) ret = value.hexadecimalValue; else ret = value.decimalValue; } else ret = defaultValue; objc_autoreleasePoolPop(pool); return ret; } |
︙ | ︙ | |||
258 259 260 261 262 263 264 | { void *pool = objc_autoreleasePoolPush(); OFString *value = [self stringForKey: key defaultValue: nil]; float ret; if (value != nil) | | | | 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 | { void *pool = objc_autoreleasePoolPush(); OFString *value = [self stringForKey: key defaultValue: nil]; float ret; if (value != nil) ret = value.floatValue; else ret = defaultValue; objc_autoreleasePoolPop(pool); return ret; } - (double)doubleForKey: (OFString *)key defaultValue: (double)defaultValue { void *pool = objc_autoreleasePoolPush(); OFString *value = [self stringForKey: key defaultValue: nil]; double ret; if (value != nil) ret = value.doubleValue; else ret = defaultValue; objc_autoreleasePoolPop(pool); return ret; } |
︙ | ︙ | |||
399 400 401 402 403 404 405 | { void *pool; OFMutableArray *pairs; id const *lines; size_t count; bool replaced; | | | | | | | | | | | | | | 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 | { void *pool; OFMutableArray *pairs; id const *lines; size_t count; bool replaced; if (array.count == 0) { [self removeValueForKey: key]; return; } pool = objc_autoreleasePoolPush(); pairs = [OFMutableArray arrayWithCapacity: array.count]; for (id object in array) { OFINICategory_Pair *pair; if (![object isKindOfClass: [OFString class]]) @throw [OFInvalidArgumentException exception]; pair = [[[OFINICategory_Pair 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++) { OFINICategory_Pair *pair; if (![lines[i] isKindOfClass: [OFINICategory_Pair class]]) continue; pair = lines[i]; if ([pair->_key isEqual: key]) { [_lines removeObjectAtIndex: i]; if (!replaced) { [_lines insertObjectsFromArray: pairs atIndex: i]; replaced = true; /* Continue after inserted pairs */ i += array.count - 1; } else i--; /* Continue at same position */ lines = _lines.objects; count = _lines.count; continue; } } if (!replaced) [_lines addObjectsFromArray: pairs]; objc_autoreleasePoolPop(pool); } - (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++) { OFINICategory_Pair *pair; if (![lines[i] isKindOfClass: [OFINICategory_Pair class]]) continue; pair = lines[i]; if ([pair->_key isEqual: key]) { [_lines removeObjectAtIndex: i]; lines = _lines.objects; count = _lines.count; i--; /* Continue at same position */ continue; } } objc_autoreleasePoolPop(pool); } - (bool)of_writeToStream: (OFStream *)stream encoding: (of_string_encoding_t)encoding first: (bool)first { if (_lines.count == 0) return false; if (first) [stream writeFormat: @"[%@]\r\n", _name]; else [stream writeFormat: @"\r\n[%@]\r\n", _name]; |
︙ | ︙ |
Modified src/OFINIFile.m from [e922a1bcde] to [704c71d30b].
︙ | ︙ | |||
33 34 35 36 37 38 39 | - (void)of_parseFile: (OFString *)path encoding: (of_string_encoding_t)encoding; @end static bool isWhitespaceLine(OFString *line) { | | | | 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 | - (void)of_parseFile: (OFString *)path encoding: (of_string_encoding_t)encoding; @end static bool isWhitespaceLine(OFString *line) { const char *cString = line.UTF8String; size_t length = line.UTF8StringLength; for (size_t i = 0; i < length; i++) if (!of_ascii_isspace(cString[i])) return false; return true; } |
︙ | ︙ | |||
98 99 100 101 102 103 104 | - (OFINICategory *)categoryForName: (OFString *)name { void *pool = objc_autoreleasePoolPush(); OFINICategory *category; for (category in _categories) | | | 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 | - (OFINICategory *)categoryForName: (OFString *)name { void *pool = objc_autoreleasePoolPush(); OFINICategory *category; for (category in _categories) if ([category.name isEqual: name]) return category; category = [[[OFINICategory alloc] of_initWithName: name] autorelease]; [_categories addObject: category]; objc_autoreleasePoolPop(pool); |
︙ | ︙ | |||
122 123 124 125 126 127 128 | OFString *line; @try { file = [OFFile fileWithPath: path mode: @"r"]; } @catch (OFOpenItemFailedException *e) { /* Handle missing file like an empty file */ | | | | 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 | OFString *line; @try { file = [OFFile fileWithPath: path mode: @"r"]; } @catch (OFOpenItemFailedException *e) { /* Handle missing file like an empty file */ if (e.errNo == ENOENT) return; @throw e; } while ((line = [file readLineWithEncoding: encoding]) != nil) { if (isWhitespaceLine(line)) continue; if ([line hasPrefix: @"["]) { OFString *categoryName; if (![line hasSuffix: @"]"]) @throw [OFInvalidFormatException exception]; categoryName = [line substringWithRange: of_range(1, line.length - 2)]; category = [[[OFINICategory alloc] of_initWithName: categoryName] autorelease]; [_categories addObject: category]; } else { if (category == nil) @throw [OFInvalidFormatException exception]; |
︙ | ︙ |
Modified src/OFInflate64Stream.h from [d706b9c186] to [7e95b67f65].
︙ | ︙ | |||
32 33 34 35 36 37 38 | * underlying stream. */ @interface OFInflate64Stream: OFStream <OFReadyForReadingObserving> { #ifdef OF_INFLATE64_STREAM_M @public #endif | | | 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | * underlying stream. */ @interface OFInflate64Stream: OFStream <OFReadyForReadingObserving> { #ifdef OF_INFLATE64_STREAM_M @public #endif OFStream *_stream; unsigned char _buffer[OF_INFLATE64_STREAM_BUFFER_SIZE]; uint16_t _bufferIndex, _bufferLength; uint8_t _byte; uint8_t _bitIndex, _savedBitsLength; uint16_t _savedBits; unsigned char *_Nullable _slidingWindow; uint16_t _slidingWindowIndex, _slidingWindowMask; |
︙ | ︙ | |||
77 78 79 80 81 82 83 | /*! * @brief Creates a new OFInflate64Stream with the specified underlying stream. * * @param stream The underlying stream to which compressed data is written or * from which compressed data is read * @return A new, autoreleased OFInflate64Stream */ | | | < | 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 | /*! * @brief Creates a new OFInflate64Stream with the specified underlying stream. * * @param stream The underlying stream to which compressed data is written or * from which compressed data is read * @return A new, autoreleased OFInflate64Stream */ + (instancetype)streamWithStream: (OFStream *)stream; - (instancetype)init OF_UNAVAILABLE; /*! * @brief Initializes an already allocated OFInflate64Stream with the specified * underlying stream. * * @param stream The underlying stream to which compressed data is written or * from which compressed data is read * @return A initialized OFInflate64Stream */ - (instancetype)initWithStream: (OFStream *)stream OF_DESIGNATED_INITIALIZER; @end OF_ASSUME_NONNULL_END |
Modified src/OFInflateStream.h from [39722f3e94] to [ba3144156c].
︙ | ︙ | |||
32 33 34 35 36 37 38 | * underlying stream. */ @interface OFInflateStream: OFStream <OFReadyForReadingObserving> { #ifdef OF_INFLATE_STREAM_M @public #endif | | | 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | * underlying stream. */ @interface OFInflateStream: OFStream <OFReadyForReadingObserving> { #ifdef OF_INFLATE_STREAM_M @public #endif OFStream *_stream; unsigned char _buffer[OF_INFLATE_STREAM_BUFFER_SIZE]; uint16_t _bufferIndex, _bufferLength; uint8_t _byte; uint8_t _bitIndex, _savedBitsLength; uint16_t _savedBits; unsigned char *_Nullable _slidingWindow; uint16_t _slidingWindowIndex, _slidingWindowMask; |
︙ | ︙ | |||
77 78 79 80 81 82 83 | /*! * @brief Creates a new OFInflateStream with the specified underlying stream. * * @param stream The underlying stream to which compressed data is written or * from which compressed data is read * @return A new, autoreleased OFInflateStream */ | | | < | 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 | /*! * @brief Creates a new OFInflateStream with the specified underlying stream. * * @param stream The underlying stream to which compressed data is written or * from which compressed data is read * @return A new, autoreleased OFInflateStream */ + (instancetype)streamWithStream: (OFStream *)stream; - (instancetype)init OF_UNAVAILABLE; /*! * @brief Initializes an already allocated OFInflateStream with the specified * underlying stream. * * @param stream The underlying stream to which compressed data is written or * from which compressed data is read * @return A initialized OFInflateStream */ - (instancetype)initWithStream: (OFStream *)stream OF_DESIGNATED_INITIALIZER; @end OF_ASSUME_NONNULL_END |
Modified src/OFInflateStream.m from [b3630eb5b7] to [98e2dc75e9].
︙ | ︙ | |||
168 169 170 171 172 173 174 | for (uint16_t i = 0; i <= 31; i++) lengths[i] = 5; fixedDistTree = of_huffman_tree_construct(lengths, 32); } | | | | 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 | for (uint16_t i = 0; i <= 31; i++) lengths[i] = 5; fixedDistTree = of_huffman_tree_construct(lengths, 32); } + (instancetype)streamWithStream: (OFStream *)stream { return [[[self alloc] initWithStream: stream] autorelease]; } - (instancetype)init { OF_INVALID_INIT_METHOD } - (instancetype)initWithStream: (OFStream *)stream { self = [super init]; @try { _stream = [stream retain]; /* 0-7 address the bit, 8 means fetch next byte */ |
︙ | ︙ | |||
664 665 666 667 668 669 670 | @throw [OFNotOpenException exceptionWithObject: self]; return _atEndOfStream; } - (int)fileDescriptorForReading { | > | | | 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 | @throw [OFNotOpenException exceptionWithObject: self]; return _atEndOfStream; } - (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 |
︙ | ︙ |
Modified src/OFIntrospection.m from [cd6beb50c0] to [79c1692f33].
︙ | ︙ | |||
77 78 79 80 81 82 83 | [super dealloc]; } - (OFString *)description { return [OFString stringWithFormat: @"<%@: %@ [%s]>", | | | 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 | [super dealloc]; } - (OFString *)description { return [OFString stringWithFormat: @"<%@: %@ [%s]>", self.class, _name, _typeEncoding]; } - (bool)isEqual: (id)object { OFMethod *method; if (object == self) |
︙ | ︙ | |||
115 116 117 118 119 120 121 | - (uint32_t)hash { uint32_t hash; OF_HASH_INIT(hash); | | | 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 | - (uint32_t)hash { uint32_t hash; OF_HASH_INIT(hash); OF_HASH_ADD_HASH(hash, _name.hash); if (_typeEncoding != NULL) { size_t length = strlen(_typeEncoding); for (size_t i = 0; i < length; i++) OF_HASH_ADD(hash, _typeEncoding[i]); } |
︙ | ︙ | |||
175 176 177 178 179 180 181 | const char *attributes; _name = [[OFString alloc] initWithUTF8String: property_getName(property)]; if ((attributes = property_getAttributes(property)) == NULL) @throw [OFInitializationFailedException | | | 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 | const char *attributes; _name = [[OFString alloc] initWithUTF8String: property_getName(property)]; if ((attributes = property_getAttributes(property)) == NULL) @throw [OFInitializationFailedException exceptionWithClass: self.class]; while (*attributes != '\0') { const char *start; switch (*attributes) { case 'T': while (*attributes != ',' && |
︙ | ︙ | |||
207 208 209 210 211 212 213 | attributes++; break; case 'G': start = ++attributes; if (_getter != nil) @throw [OFInitializationFailedException | | | | 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 | attributes++; break; case 'G': start = ++attributes; if (_getter != nil) @throw [OFInitializationFailedException exceptionWithClass: self.class]; while (*attributes != ',' && *attributes != '\0') attributes++; _getter = [[OFString alloc] initWithUTF8String: start length: attributes - start]; break; case 'S': start = ++attributes; if (_setter != nil) @throw [OFInitializationFailedException exceptionWithClass: self.class]; while (*attributes != ',' && *attributes != '\0') attributes++; _setter = [[OFString alloc] initWithUTF8String: start |
︙ | ︙ | |||
250 251 252 253 254 255 256 | attributes++; break; case 'V': start = ++attributes; if (_iVar != nil) @throw [OFInitializationFailedException | | | | | 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 | attributes++; break; case 'V': start = ++attributes; if (_iVar != nil) @throw [OFInitializationFailedException exceptionWithClass: self.class]; while (*attributes != ',' && *attributes != '\0') attributes++; _iVar = [[OFString alloc] initWithUTF8String: start length: attributes - start]; break; default: @throw [OFInitializationFailedException exceptionWithClass: self.class]; } if (*attributes != ',' && *attributes != '\0') @throw [OFInitializationFailedException exceptionWithClass: self.class]; if (*attributes != '\0') attributes++; } if (!(_attributes & OF_PROPERTY_READONLY)) _attributes |= OF_PROPERTY_READWRITE; |
︙ | ︙ | |||
330 331 332 333 334 335 336 | return [OFString stringWithFormat: @"<%@: %@\n" @"\tAttributes = 0x%03X\n" @"\tGetter = %@\n" @"\tSetter = %@\n" @"\tiVar = %@\n" @">", | | | | 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 | return [OFString stringWithFormat: @"<%@: %@\n" @"\tAttributes = 0x%03X\n" @"\tGetter = %@\n" @"\tSetter = %@\n" @"\tiVar = %@\n" @">", self.class, _name, _attributes, _getter, _setter, _iVar]; } - (bool)isEqual: (id)object { OFProperty *otherProperty; if (object == self) |
︙ | ︙ | |||
364 365 366 367 368 369 370 | - (uint32_t)hash { uint32_t hash; OF_HASH_INIT(hash); | | | | | 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 | - (uint32_t)hash { uint32_t hash; OF_HASH_INIT(hash); OF_HASH_ADD_HASH(hash, _name.hash); OF_HASH_ADD(hash, (_attributes & 0xFF00) >> 8); OF_HASH_ADD(hash, _attributes & 0xFF); OF_HASH_ADD_HASH(hash, _getter.hash); OF_HASH_ADD_HASH(hash, _setter.hash); OF_HASH_FINALIZE(hash); return hash; } @end |
︙ | ︙ |
Modified src/OFInvocation.m from [df81aa2e85] to [a9afe182d2].
︙ | ︙ | |||
38 39 40 41 42 43 44 | - (instancetype)initWithMethodSignature: (OFMethodSignature *)signature { self = [super init]; @try { void *pool = objc_autoreleasePoolPush(); | | | | 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 | - (instancetype)initWithMethodSignature: (OFMethodSignature *)signature { self = [super init]; @try { void *pool = objc_autoreleasePoolPush(); size_t numberOfArguments = signature.numberOfArguments; const char *typeEncoding; size_t typeSize; _methodSignature = [signature retain]; _arguments = [[OFMutableArray alloc] init]; for (size_t i = 0; i < numberOfArguments; i++) { OFMutableData *data; typeEncoding = [_methodSignature argumentTypeAtIndex: i]; typeSize = of_sizeof_type_encoding(typeEncoding); data = [OFMutableData dataWithItemSize: typeSize capacity: 1]; [data increaseCountBy: 1]; [_arguments addObject: data]; } typeEncoding = _methodSignature.methodReturnType; typeSize = of_sizeof_type_encoding(typeEncoding); if (typeSize > 0) { _returnValue = [[OFMutableData alloc] initWithItemSize: typeSize capacity: 1]; [_returnValue increaseCountBy: 1]; |
︙ | ︙ | |||
91 92 93 94 95 96 97 | } - (void)setArgument: (const void *)buffer atIndex: (size_t)idx { OFMutableData *data = [_arguments objectAtIndex: idx]; | | | | | | 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 | } - (void)setArgument: (const void *)buffer atIndex: (size_t)idx { OFMutableData *data = [_arguments objectAtIndex: idx]; memcpy(data.mutableItems, buffer, data.itemSize); } - (void)getArgument: (void *)buffer atIndex: (size_t)idx { OFData *data = [_arguments objectAtIndex: idx]; memcpy(buffer, data.items, data.itemSize); } - (void)setReturnValue: (const void *)buffer { memcpy(_returnValue.mutableItems, buffer, _returnValue.itemSize); } - (void)getReturnValue: (void *)buffer { memcpy(buffer, _returnValue.items, _returnValue.itemSize); } #ifdef OF_INVOCATION_CAN_INVOKE - (void)invoke { of_invocation_invoke(self); } #endif @end |
Modified src/OFKernelEventObserver.m from [97baff6c86] to [68149c85a6].
︙ | ︙ | |||
110 111 112 113 114 115 116 | _readObjects = [[OFMutableArray alloc] init]; _writeObjects = [[OFMutableArray alloc] init]; #ifdef OF_HAVE_PIPE if (pipe(_cancelFD)) @throw [OFInitializationFailedException | | | | | | | 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 | _readObjects = [[OFMutableArray alloc] init]; _writeObjects = [[OFMutableArray alloc] init]; #ifdef OF_HAVE_PIPE if (pipe(_cancelFD)) @throw [OFInitializationFailedException exceptionWithClass: self.class]; #else _cancelFD[0] = _cancelFD[1] = socket(AF_INET, SOCK_DGRAM, 0); if (_cancelFD[0] == INVALID_SOCKET) @throw [OFInitializationFailedException exceptionWithClass: self.class]; _cancelAddr.sin_family = AF_INET; _cancelAddr.sin_port = 0; _cancelAddr.sin_addr.s_addr = inet_addr((const void *)"127.0.0.1"); # ifdef OF_WII _cancelAddr.sin_len = 8; # endif # if !defined(OF_WII) && !defined(OF_NINTENDO_3DS) if (bind(_cancelFD[0], (struct sockaddr *)&_cancelAddr, sizeof(_cancelAddr)) != 0) @throw [OFInitializationFailedException exceptionWithClass: self.class]; cancelAddrLen = sizeof(_cancelAddr); if (of_getsockname(_cancelFD[0], (struct sockaddr *)&_cancelAddr, &cancelAddrLen) != 0) @throw [OFInitializationFailedException exceptionWithClass: self.class]; # else for (;;) { uint16_t rnd = 0; int ret; while (rnd < 1024) rnd = (uint16_t)rand(); _cancelAddr.sin_port = OF_BSWAP16_IF_LE(rnd); ret = bind(_cancelFD[0], (struct sockaddr *)&_cancelAddr, sizeof(_cancelAddr)); if (ret == 0) break; if (of_socket_errno() != EADDRINUSE) @throw [OFInitializationFailedException exceptionWithClass: self.class]; } # endif #endif #ifdef OF_HAVE_THREADS _mutex = [[OFMutex alloc] init]; #endif |
︙ | ︙ | |||
304 305 306 307 308 309 310 | { void *pool = objc_autoreleasePoolPush(); #ifdef OF_HAVE_THREADS [_mutex lock]; @try { #endif | | | | | | 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 | { void *pool = objc_autoreleasePoolPush(); #ifdef OF_HAVE_THREADS [_mutex lock]; @try { #endif const int *queueActions = _queueActions.items; id const *queueObjects = _queueObjects.objects; size_t count = _queueActions.count; OF_ENSURE(_queueObjects.count == count); for (size_t i = 0; i < count; i++) { int action = queueActions[i]; id object = queueObjects[i]; switch (action) { case QUEUE_ADD | QUEUE_READ: |
︙ | ︙ | |||
408 409 410 411 412 413 414 | - (void)observeForTimeInterval: (of_time_interval_t)timeInterval { OF_UNRECOGNIZED_SELECTOR } - (void)observeUntilDate: (OFDate *)date { | | | 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 | - (void)observeForTimeInterval: (of_time_interval_t)timeInterval { OF_UNRECOGNIZED_SELECTOR } - (void)observeUntilDate: (OFDate *)date { [self observeForTimeInterval: date.timeIntervalSinceNow]; } - (void)cancel { #ifdef OF_HAVE_PIPE OF_ENSURE(write(_cancelFD[1], "", 1) > 0); #elif defined(OF_WII) |
︙ | ︙ |
Modified src/OFKernelEventObserver_epoll.m from [0ecb9c1ccd] to [c7d873c63a].
︙ | ︙ | |||
51 52 53 54 55 56 57 | @try { struct epoll_event event; #ifdef HAVE_EPOLL_CREATE1 if ((_epfd = epoll_create1(EPOLL_CLOEXEC)) == -1) @throw [OFInitializationFailedException | | | | | 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 | @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; } |
︙ | ︙ | |||
151 152 153 154 155 156 157 | forKey: (void *)((intptr_t)fd + 1)]; } } - (void)of_addObjectForReading: (id <OFReadyForReadingObserving>)object { [self of_addObject: object | | | | | | 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 | 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]; |
︙ | ︙ |
Modified src/OFKernelEventObserver_kqueue.m from [3386cd3187] to [48331f17e7].
︙ | ︙ | |||
51 52 53 54 55 56 57 | @try { struct kevent event; #ifdef HAVE_KQUEUE1 if ((_kernelQueue = kqueue1(O_CLOEXEC)) == -1) @throw [OFInitializationFailedException | | | | | | | | | 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 | @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]; } |
︙ | ︙ |
Modified src/OFKernelEventObserver_poll.m from [f7752f3f82] to [e0fcf68d56].
︙ | ︙ | |||
71 72 73 74 75 76 77 | [super dealloc]; } - (void)of_addObject: (id)object fileDescriptor: (int)fd events: (short)events { | | | | 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 | [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; |
︙ | ︙ | |||
102 103 104 105 106 107 108 | } } - (void)of_removeObject: (id)object fileDescriptor: (int)fd events: (short)events { | | | | 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 | } } - (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) { /* |
︙ | ︙ | |||
125 126 127 128 129 130 131 | } } } - (void)of_addObjectForReading: (id <OFReadyForReadingObserving>)object { [self of_addObject: object | | | | | | | | 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 | } } } - (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, |
︙ | ︙ |
Modified src/OFKernelEventObserver_select.m from [30b2a6d54f] to [02729f3714].
︙ | ︙ | |||
47 48 49 50 51 52 53 | - (instancetype)init { self = [super init]; #ifndef OF_WINDOWS if (_cancelFD[0] >= (int)FD_SETSIZE) @throw [OFInitializationFailedException | | | | | | | 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 | - (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]; |
︙ | ︙ | |||
185 186 187 188 189 190 191 | OF_ENSURE(read(_cancelFD[0], &buffer, 1) == 1); #else OF_ENSURE(recvfrom(_cancelFD[0], (void *)&buffer, 1, 0, NULL, NULL) == 1); #endif } | | | | | | 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 | 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: |
︙ | ︙ |
Modified src/OFLHAArchive.h from [08a1644703] to [667a6061aa].
︙ | ︙ | |||
27 28 29 30 31 32 33 | /*! * @class OFLHAArchive OFLHAArchive.h ObjFW/OFLHAArchive.h * * @brief A class for accessing and manipulating LHA files. */ @interface OFLHAArchive: OFObject { | | | | 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 | /*! * @class OFLHAArchive OFLHAArchive.h ObjFW/OFLHAArchive.h * * @brief A class for accessing and manipulating LHA files. */ @interface OFLHAArchive: OFObject { OFStream *_stream; enum { OF_LHA_ARCHIVE_MODE_READ, OF_LHA_ARCHIVE_MODE_WRITE, OF_LHA_ARCHIVE_MODE_APPEND } _mode; of_string_encoding_t _encoding; OFStream *_Nullable _lastReturnedStream; } /*! * @brief The encoding to use for the archive. Defaults to ISO 8859-1. */ @property (nonatomic) of_string_encoding_t encoding; |
︙ | ︙ | |||
63 64 65 66 67 68 69 | * @param stream A stream from which the LHA archive will be read. * For read and append mode, this needs to be an OFSeekableStream. * @param mode The mode for the LHA file. Valid modes are "r" for reading, * "w" for creating a new file and "a" for appending to an existing * archive. * @return A new, autoreleased OFLHAArchive */ | | | 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 | * @param stream A stream from which the LHA archive will be read. * For read and append mode, this needs to be an OFSeekableStream. * @param mode The mode for the LHA file. Valid modes are "r" for reading, * "w" for creating a new file and "a" for appending to an existing * archive. * @return A new, autoreleased OFLHAArchive */ + (instancetype)archiveWithStream: (OFStream *)stream mode: (OFString *)mode; #ifdef OF_HAVE_FILES /*! * @brief Creates a new OFLHAArchive object with the specified file. * * @param path The path to the LHA file |
︙ | ︙ | |||
93 94 95 96 97 98 99 | * @param stream A stream from which the LHA archive will be read. * For read and append mode, this needs to be an OFSeekableStream. * @param mode The mode for the LHA file. Valid modes are "r" for reading, * "w" for creating a new file and "a" for appending to an existing * archive. * @return An initialized OFLHAArchive */ | | | 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 | * @param stream A stream from which the LHA archive will be read. * For read and append mode, this needs to be an OFSeekableStream. * @param mode The mode for the LHA file. Valid modes are "r" for reading, * "w" for creating a new file and "a" for appending to an existing * archive. * @return An initialized OFLHAArchive */ - (instancetype)initWithStream: (OFStream *)stream mode: (OFString *)mode OF_DESIGNATED_INITIALIZER; #ifdef OF_HAVE_FILES /*! * @brief Initializes an already allocated OFLHAArchive object with the * specified file. * |
︙ | ︙ |
Modified src/OFLHAArchive.m from [9fc92038be] to [12097984b6].
︙ | ︙ | |||
36 37 38 39 40 41 42 | #import "OFNotOpenException.h" #import "OFOutOfRangeException.h" #import "OFTruncatedDataException.h" #import "OFWriteFailedException.h" @interface OFLHAArchive_FileReadStream: OFStream <OFReadyForReadingObserving> { | | | | | | | | | 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 | #import "OFNotOpenException.h" #import "OFOutOfRangeException.h" #import "OFTruncatedDataException.h" #import "OFWriteFailedException.h" @interface OFLHAArchive_FileReadStream: OFStream <OFReadyForReadingObserving> { OFStream *_stream; OFStream *_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 OFLHAArchive_FileWriteStream: OFStream <OFReadyForWritingObserving> { OFMutableLHAArchiveEntry *_entry; of_string_encoding_t _encoding; OFSeekableStream *_stream; of_offset_t _headerOffset; uint32_t _bytesWritten; uint16_t _CRC16; } - (instancetype)of_initWithStream: (OFSeekableStream *)stream entry: (OFLHAArchiveEntry *)entry encoding: (of_string_encoding_t)encoding; @end @implementation OFLHAArchive @synthesize encoding = _encoding; + (instancetype)archiveWithStream: (OFStream *)stream mode: (OFString *)mode { return [[[self alloc] initWithStream: stream mode: mode] autorelease]; } #ifdef OF_HAVE_FILES + (instancetype)archiveWithPath: (OFString *)path mode: (OFString *)mode { return [[[self alloc] initWithPath: path mode: mode] autorelease]; } #endif - (instancetype)init { OF_INVALID_INIT_METHOD } - (instancetype)initWithStream: (OFStream *)stream mode: (OFString *)mode { self = [super init]; @try { _stream = [stream retain]; |
︙ | ︙ | |||
111 112 113 114 115 116 117 | if ((_mode == OF_LHA_ARCHIVE_MODE_WRITE || _mode == OF_LHA_ARCHIVE_MODE_APPEND) && ![_stream isKindOfClass: [OFSeekableStream class]]) @throw [OFInvalidArgumentException exception]; if (_mode == OF_LHA_ARCHIVE_MODE_APPEND) | | | | 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 | if ((_mode == OF_LHA_ARCHIVE_MODE_WRITE || _mode == OF_LHA_ARCHIVE_MODE_APPEND) && ![_stream isKindOfClass: [OFSeekableStream class]]) @throw [OFInvalidArgumentException exception]; if (_mode == OF_LHA_ARCHIVE_MODE_APPEND) [(OFSeekableStream *)_stream seekToOffset: 0 whence: SEEK_END]; _encoding = OF_STRING_ENCODING_ISO_8859_1; } @catch (id e) { [self release]; @throw e; } |
︙ | ︙ | |||
163 164 165 166 167 168 169 | OFLHAArchiveEntry *entry; char header[21]; size_t headerLen; if (_mode != OF_LHA_ARCHIVE_MODE_READ) @throw [OFInvalidArgumentException exception]; | | | | 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 | OFLHAArchiveEntry *entry; char header[21]; size_t headerLen; if (_mode != OF_LHA_ARCHIVE_MODE_READ) @throw [OFInvalidArgumentException exception]; [(OFLHAArchive_FileReadStream *)_lastReturnedStream of_skip]; [_lastReturnedStream close]; [_lastReturnedStream release]; _lastReturnedStream = nil; for (headerLen = 0; headerLen < 21;) { if (_stream.atEndOfStream) { if (headerLen == 0) return nil; if (headerLen == 1 && header[0] == 0) return nil; @throw [OFTruncatedDataException exception]; |
︙ | ︙ | |||
203 204 205 206 207 208 209 | { if (_mode != OF_LHA_ARCHIVE_MODE_READ) @throw [OFInvalidArgumentException exception]; if (_lastReturnedStream == nil) @throw [OFInvalidArgumentException exception]; | > | | | > | | | | 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 | { if (_mode != OF_LHA_ARCHIVE_MODE_READ) @throw [OFInvalidArgumentException exception]; if (_lastReturnedStream == nil) @throw [OFInvalidArgumentException exception]; return [[(OFLHAArchive_FileReadStream *)_lastReturnedStream retain] autorelease]; } - (OFStream <OFReadyForWritingObserving> *) streamForWritingEntry: (OFLHAArchiveEntry *)entry { OFString *compressionMethod; if (_mode != OF_LHA_ARCHIVE_MODE_WRITE && _mode != OF_LHA_ARCHIVE_MODE_APPEND) @throw [OFInvalidArgumentException exception]; compressionMethod = entry.compressionMethod; if (![compressionMethod isEqual: @"-lh0-"] && ![compressionMethod isEqual: @"-lhd-"]) @throw [OFNotImplementedException exceptionWithSelector: _cmd object: self]; [_lastReturnedStream close]; [_lastReturnedStream release]; _lastReturnedStream = nil; _lastReturnedStream = [[OFLHAArchive_FileWriteStream alloc] of_initWithStream: (OFSeekableStream *)_stream entry: entry encoding: _encoding]; return [[(OFLHAArchive_FileWriteStream *)_lastReturnedStream retain] autorelease]; } - (void)close { if (_stream == nil) return; [_lastReturnedStream close]; [_lastReturnedStream release]; _lastReturnedStream = nil; [_stream release]; _stream = nil; } @end @implementation OFLHAArchive_FileReadStream - (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 = [[OFLHAArchive_LHStream alloc] of_initWithStream: stream distanceBits: 4 dictionaryBits: 14]; |
︙ | ︙ | |||
281 282 283 284 285 286 287 | of_initWithStream: stream distanceBits: 5 dictionaryBits: 17]; else _decompressedStream = [stream retain]; _entry = [entry copy]; | | | 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 | of_initWithStream: stream distanceBits: 5 dictionaryBits: 17]; else _decompressedStream = [stream retain]; _entry = [entry copy]; _toRead = entry.uncompressedSize; } @catch (id e) { [self release]; @throw e; } return self; } |
︙ | ︙ | |||
320 321 322 323 324 325 326 | if (_stream == nil) @throw [OFNotOpenException exceptionWithObject: self]; if (_atEndOfStream) return 0; | < | | | | | > | | | > | | | | 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 | if (_stream == nil) @throw [OFNotOpenException exceptionWithObject: self]; if (_atEndOfStream) return 0; if (_stream.atEndOfStream && !_decompressedStream.hasDataInReadBuffer) @throw [OFTruncatedDataException exception]; if (length > _toRead) length = _toRead; ret = [_decompressedStream readIntoBuffer: buffer length: length]; _toRead -= ret; _CRC16 = of_crc16(_CRC16, buffer, ret); if (_toRead == 0) { _atEndOfStream = true; if (_CRC16 != _entry.CRC16) { OFString *actualChecksum = [OFString stringWithFormat: @"%04" PRIX16, _CRC16]; OFString *expectedChecksum = [OFString stringWithFormat: @"%04" PRIX16, _entry.CRC16]; @throw [OFChecksumMismatchException exceptionWithActualChecksum: actualChecksum expectedChecksum: expectedChecksum]; } } return ret; } - (bool)hasDataInReadBuffer { return (super.hasDataInReadBuffer || _decompressedStream.hasDataInReadBuffer); } - (int)fileDescriptorForReading { return ((id <OFReadyForReadingObserving>)_decompressedStream) .fileDescriptorForReading; } - (void)of_skip { OFStream *stream; uint32_t toRead; if (_stream == nil || _skipped) return; stream = _stream; toRead = _toRead; /* * Get the number of consumed bytes and directly read from the * compressed stream, to make skipping much faster. */ if ([_decompressedStream isKindOfClass: [OFLHAArchive_LHStream class]]) { OFLHAArchive_LHStream *LHStream = (OFLHAArchive_LHStream *)_decompressedStream; [LHStream close]; toRead = _entry.compressedSize - LHStream->_bytesConsumed; stream = _stream; } if ([stream isKindOfClass: [OFSeekableStream class]] && (sizeof(of_offset_t) > 4 || toRead < INT32_MAX)) [(OFSeekableStream *)stream seekToOffset: (of_offset_t)toRead whence: SEEK_CUR]; else { while (toRead > 0) { char buffer[512]; size_t min = toRead; if (min > 512) min = 512; |
︙ | ︙ | |||
423 424 425 426 427 428 429 | _decompressedStream = nil; [super close]; } @end @implementation OFLHAArchive_FileWriteStream | | | 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 | _decompressedStream = nil; [super close]; } @end @implementation OFLHAArchive_FileWriteStream - (instancetype)of_initWithStream: (OFSeekableStream *)stream entry: (OFLHAArchiveEntry *)entry encoding: (of_string_encoding_t)encoding { self = [super init]; @try { _entry = [entry mutableCopy]; |
︙ | ︙ | |||
475 476 477 478 479 480 481 | if (UINT32_MAX - _bytesWritten < length) @throw [OFOutOfRangeException exception]; @try { bytesWritten = (uint32_t)[_stream writeBuffer: buffer length: length]; } @catch (OFWriteFailedException *e) { | | | | > | | | | | 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 | if (UINT32_MAX - _bytesWritten < length) @throw [OFOutOfRangeException exception]; @try { bytesWritten = (uint32_t)[_stream writeBuffer: buffer length: length]; } @catch (OFWriteFailedException *e) { _bytesWritten += e.bytesWritten; _CRC16 = of_crc16(_CRC16, buffer, e.bytesWritten); @throw e; } _bytesWritten += (uint32_t)bytesWritten; _CRC16 = of_crc16(_CRC16, buffer, bytesWritten); return bytesWritten; } - (bool)lowlevelIsAtEndOfStream { if (_stream == nil) @throw [OFNotOpenException exceptionWithObject: self]; return _stream.atEndOfStream; } - (int)fileDescriptorForWriting { return ((id <OFReadyForWritingObserving>)_stream) .fileDescriptorForWriting; } - (void)close { of_offset_t offset; if (_stream == nil) return; _entry.uncompressedSize = _bytesWritten; _entry.compressedSize = _bytesWritten; _entry.CRC16 = _CRC16; offset = [_stream seekToOffset: 0 whence:SEEK_CUR]; [_stream seekToOffset: _headerOffset whence: SEEK_SET]; [_entry of_writeToStream: _stream encoding: _encoding]; |
︙ | ︙ |
Modified src/OFLHAArchiveEntry.m from [000c2ce28c] to [436ef99699].
︙ | ︙ | |||
60 61 62 63 64 65 66 | parseFileNameExtension(OFLHAArchiveEntry *entry, OFData *extension, of_string_encoding_t encoding) { [entry->_fileName release]; entry->_fileName = nil; entry->_fileName = [[OFString alloc] | | | | | 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 | parseFileNameExtension(OFLHAArchiveEntry *entry, OFData *extension, of_string_encoding_t encoding) { [entry->_fileName release]; entry->_fileName = nil; entry->_fileName = [[OFString alloc] initWithCString: (char *)extension.items + 1 encoding: encoding length: [extension count] - 1]; } static void parseDirectoryNameExtension(OFLHAArchiveEntry *entry, OFData *extension, of_string_encoding_t encoding) { void *pool = objc_autoreleasePoolPush(); OFMutableData *data = [[extension mutableCopy] autorelease]; char *items = data.mutableItems; size_t count = data.count; OFMutableString *directoryName; for (size_t i = 1; i < count; i++) if (items[i] == '\xFF') items[i] = '/'; directoryName = [OFMutableString stringWithCString: items + 1 |
︙ | ︙ | |||
104 105 106 107 108 109 110 | parseCommentExtension(OFLHAArchiveEntry *entry, OFData *extension, of_string_encoding_t encoding) { [entry->_fileComment release]; entry->_fileComment = nil; entry->_fileComment = [[OFString alloc] | | | | | | | | | | | | | | | 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 | parseCommentExtension(OFLHAArchiveEntry *entry, OFData *extension, of_string_encoding_t encoding) { [entry->_fileComment release]; entry->_fileComment = nil; entry->_fileComment = [[OFString alloc] initWithCString: (char *)extension.items + 1 encoding: encoding length: extension.count - 1]; } static void parsePermissionsExtension(OFLHAArchiveEntry *entry, OFData *extension, of_string_encoding_t encoding) { uint16_t mode; if (extension.count != 3) @throw [OFInvalidFormatException exception]; memcpy(&mode, (char *)extension.items + 1, 2); mode = OF_BSWAP16_IF_BE(mode); [entry->_mode release]; entry->_mode = nil; entry->_mode = [[OFNumber alloc] initWithUInt16: mode]; } static void parseGIDUIDExtension(OFLHAArchiveEntry *entry, OFData *extension, of_string_encoding_t encoding) { uint16_t UID, GID; if (extension.count != 5) @throw [OFInvalidFormatException exception]; memcpy(&GID, (char *)extension.items + 1, 2); GID = OF_BSWAP16_IF_BE(GID); memcpy(&UID, (char *)extension.items + 3, 2); UID = OF_BSWAP16_IF_BE(UID); [entry->_GID release]; entry->_GID = nil; [entry->_UID release]; entry->_UID = nil; entry->_GID = [[OFNumber alloc] initWithUInt16: GID]; entry->_UID = [[OFNumber alloc] initWithUInt16: UID]; } static void parseGroupExtension(OFLHAArchiveEntry *entry, OFData *extension, of_string_encoding_t encoding) { [entry->_group release]; entry->_group = nil; entry->_group = [[OFString alloc] initWithCString: (char *)extension.items + 1 encoding: encoding length: extension.count - 1]; } static void parseOwnerExtension(OFLHAArchiveEntry *entry, OFData *extension, of_string_encoding_t encoding) { [entry->_owner release]; entry->_owner = nil; entry->_owner = [[OFString alloc] initWithCString: (char *)extension.items + 1 encoding: encoding length: extension.count - 1]; } static void parseModificationDateExtension(OFLHAArchiveEntry *entry, OFData *extension, of_string_encoding_t encoding) { uint32_t modificationDate; if (extension.count != 5) @throw [OFInvalidFormatException exception]; memcpy(&modificationDate, (char *)extension.items + 1, 4); modificationDate = OF_BSWAP32_IF_BE(modificationDate); [entry->_modificationDate release]; entry->_modificationDate = nil; entry->_modificationDate = [[OFDate alloc] initWithTimeIntervalSince1970: modificationDate]; |
︙ | ︙ | |||
287 288 289 290 291 292 293 | data = [OFMutableData dataWithItems: [entry->_directoryName cStringWithEncoding: encoding] count: [entry->_directoryName cStringLengthWithEncoding: encoding]]; [data addItems: [entry->_fileName cStringWithEncoding: encoding] count: [entry->_fileName cStringLengthWithEncoding: encoding]]; | | | | 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 | data = [OFMutableData dataWithItems: [entry->_directoryName cStringWithEncoding: encoding] count: [entry->_directoryName cStringLengthWithEncoding: encoding]]; [data addItems: [entry->_fileName cStringWithEncoding: encoding] count: [entry->_fileName cStringLengthWithEncoding: encoding]]; cString = data.mutableItems; length = data.count; pos = 0; for (size_t i = 0; i < length; i++) { if (cString[i] == '/' || cString[i] == '\\') { cString[i] = '\xFF'; pos = i + 1; } |
︙ | ︙ | |||
591 592 593 594 595 596 597 | [data addItems: &tmp32 count: sizeof(tmp32)]; tmp32 = OF_BSWAP32_IF_BE(_uncompressedSize); [data addItems: &tmp32 count: sizeof(tmp32)]; | | | 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 | [data addItems: &tmp32 count: sizeof(tmp32)]; tmp32 = OF_BSWAP32_IF_BE(_uncompressedSize); [data addItems: &tmp32 count: sizeof(tmp32)]; tmp32 = OF_BSWAP32_IF_BE((uint32_t)_date.timeIntervalSince1970); [data addItems: &tmp32 count: sizeof(tmp32)]; /* Reserved */ [data increaseCountBy: 1]; /* Header level */ |
︙ | ︙ | |||
653 654 655 656 657 658 659 | if (_mode != nil) { tmp16 = OF_BSWAP16_IF_BE(5); [data addItems: &tmp16 count: sizeof(tmp16)]; [data addItem: "\x50"]; | | | | | 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 | if (_mode != nil) { tmp16 = OF_BSWAP16_IF_BE(5); [data addItems: &tmp16 count: sizeof(tmp16)]; [data addItem: "\x50"]; tmp16 = OF_BSWAP16_IF_BE(_mode.uInt16Value); [data addItems: &tmp16 count: sizeof(tmp16)]; } if (_UID != nil || _GID != nil) { if (_UID == nil || _GID == nil) @throw [OFInvalidArgumentException exception]; tmp16 = OF_BSWAP16_IF_BE(7); [data addItems: &tmp16 count: sizeof(tmp16)]; [data addItem: "\x51"]; tmp16 = OF_BSWAP16_IF_BE(_GID.uInt16Value); [data addItems: &tmp16 count: sizeof(tmp16)]; tmp16 = OF_BSWAP16_IF_BE(_UID.uInt16Value); [data addItems: &tmp16 count: sizeof(tmp16)]; } if (_group != nil) { size_t groupLength = [_group cStringLengthWithEncoding: encoding]; |
︙ | ︙ | |||
713 714 715 716 717 718 719 | if (_modificationDate != nil) { tmp16 = OF_BSWAP16_IF_BE(7); [data addItems: &tmp16 count: sizeof(tmp16)]; [data addItem: "\x54"]; tmp32 = OF_BSWAP32_IF_BE( | | | | | | | | > | | | < | | | 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 | if (_modificationDate != nil) { tmp16 = OF_BSWAP16_IF_BE(7); [data addItems: &tmp16 count: sizeof(tmp16)]; [data addItem: "\x54"]; tmp32 = OF_BSWAP32_IF_BE( (uint32_t)_modificationDate.timeIntervalSince1970); [data addItems: &tmp32 count: sizeof(tmp32)]; } for (OFData *extension in _extensions) { size_t extensionLength = extension.count; if (extension.itemSize != 1) @throw [OFInvalidArgumentException exception]; if (extensionLength > UINT16_MAX - 2) @throw [OFOutOfRangeException exception]; tmp16 = OF_BSWAP16_IF_BE((uint16_t)extensionLength + 2); [data addItems: &tmp16 count: sizeof(tmp16)]; [data addItems: extension.items count: extension.count]; } /* Zero-length extension to terminate */ [data increaseCountBy: 2]; headerSize = data.count; if (headerSize > UINT16_MAX) @throw [OFOutOfRangeException exception]; /* Now fill in the size and CRC16 for the entire header */ tmp16 = OF_BSWAP16_IF_BE(headerSize); memcpy([data mutableItemAtIndex: 0], &tmp16, sizeof(tmp16)); tmp16 = of_crc16(0, data.items, data.count); tmp16 = OF_BSWAP16_IF_BE(tmp16); memcpy([data mutableItemAtIndex: 27], &tmp16, sizeof(tmp16)); [stream writeData: data]; objc_autoreleasePoolPop(pool); } - (OFString *)description { void *pool = objc_autoreleasePoolPush(); OFString *mode = (_mode == nil ? nil : [OFString stringWithFormat: @"%" PRIo16, _mode.uInt16Value]); OFString *extensions = [_extensions.description stringByReplacingOccurrencesOfString: @"\n" withString: @"\n\t"]; OFString *ret = [OFString stringWithFormat: @"<%@:\n" @"\tFile name = %@\n" @"\tCompression method = %@\n" @"\tCompressed size = %" @PRIu32 "\n" |
︙ | ︙ | |||
782 783 784 785 786 787 788 | @"\tUID = %@\n" @"\tGID = %@\n" @"\tOwner = %@\n" @"\tGroup = %@\n" @"\tModification date = %@\n" @"\tExtensions: %@" @">", | | | 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 | @"\tUID = %@\n" @"\tGID = %@\n" @"\tOwner = %@\n" @"\tGroup = %@\n" @"\tModification date = %@\n" @"\tExtensions: %@" @">", self.class, self.fileName, _compressionMethod, _compressedSize, _uncompressedSize, _date, _headerLevel, _CRC16, _operatingSystemIdentifier, _fileComment, mode, _UID, _GID, _owner, _group, _modificationDate, extensions]; [ret retain]; objc_autoreleasePoolPop(pool); return [ret autorelease]; } @end |
Modified src/OFLHAArchive_LHStream.h from [40128881b3] to [3e10c9b21e].
︙ | ︙ | |||
20 21 22 23 24 25 26 | OF_ASSUME_NONNULL_BEGIN #define OF_LHA_ARCHIVE_LHSTREAM_BUFFER_SIZE 4096 @interface OFLHAArchive_LHStream: OFStream { @public | | | | 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 | OF_ASSUME_NONNULL_BEGIN #define OF_LHA_ARCHIVE_LHSTREAM_BUFFER_SIZE 4096 @interface OFLHAArchive_LHStream: OFStream { @public OFStream *_stream; uint8_t _distanceBits, _dictionaryBits; unsigned char _buffer[OF_LHA_ARCHIVE_LHSTREAM_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 |
Modified src/OFLHAArchive_LHStream.m from [3034f7c67e] to [8ad89a82c7].
︙ | ︙ | |||
86 87 88 89 90 91 92 | stream->_savedBitsLength = 0; *bits = ret; return true; } @implementation OFLHAArchive_LHStream | | | 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 | stream->_savedBitsLength = 0; *bits = ret; return true; } @implementation OFLHAArchive_LHStream - (instancetype)of_initWithStream: (OFStream *)stream distanceBits: (uint8_t)distanceBits dictionaryBits: (uint8_t)dictionaryBits { self = [super init]; @try { _stream = [stream retain]; |
︙ | ︙ | |||
137 138 139 140 141 142 143 | unsigned char *buffer = buffer_; uint16_t bits, value; size_t bytesWritten = 0; if (_stream == nil) @throw [OFNotOpenException exceptionWithObject: self]; | | | 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 | 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)) |
︙ | ︙ | |||
490 491 492 493 494 495 496 | } - (bool)lowlevelIsAtEndOfStream { if (_stream == nil) @throw [OFNotOpenException exceptionWithObject: self]; | | > | | | 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 | } - (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 |
︙ | ︙ |
Modified src/OFList.m from [f9d90df6d5] to [b8390d9c24].
︙ | ︙ | |||
40 41 42 43 44 45 46 | - (instancetype)initWithSerialization: (OFXMLElement *)element { self = [self init]; @try { void *pool = objc_autoreleasePoolPush(); | | | | | 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 | - (instancetype)initWithSerialization: (OFXMLElement *)element { self = [self init]; @try { void *pool = objc_autoreleasePoolPush(); if (![element.name isEqual: self.className] || ![element.namespace isEqual: OF_SERIALIZATION_NS]) @throw [OFInvalidArgumentException exception]; for (OFXMLElement *child in [element elementsForNamespace: OF_SERIALIZATION_NS]) { void *pool2 = objc_autoreleasePoolPush(); [self appendObject: child.objectByDeserializing]; objc_autoreleasePoolPop(pool2); } objc_autoreleasePoolPop(pool); } @catch (id e) { [self release]; |
︙ | ︙ | |||
212 213 214 215 216 217 218 | return true; if (![object isKindOfClass: [OFList class]]) return false; list = object; | | | | 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 | return true; if (![object isKindOfClass: [OFList class]]) return false; list = object; if (list.count != _count) return false; for (iter = _firstListObject, iter2 = list.firstListObject; iter != NULL && iter2 != NULL; iter = iter->next, iter2 = iter2->next) if (![iter->object isEqual: iter2->object]) return false; /* One is bigger than the other even though we checked the count */ assert(iter == NULL && iter2 == NULL); |
︙ | ︙ | |||
352 353 354 355 356 357 358 | return ret; } - (OFXMLElement *)XMLElementBySerializing { OFXMLElement *element = | | | 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 | return ret; } - (OFXMLElement *)XMLElementBySerializing { OFXMLElement *element = [OFXMLElement elementWithName: self.className namespace: OF_SERIALIZATION_NS]; for (of_list_object_t *iter = _firstListObject; iter != NULL; iter = iter->next) { void *pool = objc_autoreleasePoolPush(); [element addChild: [iter->object XMLElementBySerializing]]; |
︙ | ︙ | |||
411 412 413 414 415 416 417 | @implementation OFListEnumerator - (instancetype)initWithList: (OFList *)list mutationsPointer: (unsigned long *)mutationsPtr { self = [super init]; _list = [list retain]; | | | 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 | @implementation OFListEnumerator - (instancetype)initWithList: (OFList *)list mutationsPointer: (unsigned long *)mutationsPtr { self = [super init]; _list = [list retain]; _current = _list.firstListObject; _mutations = *mutationsPtr; _mutationsPtr = mutationsPtr; return self; } - (void)dealloc |
︙ | ︙ | |||
448 449 450 451 452 453 454 | - (void)reset { if (*_mutationsPtr != _mutations) @throw [OFEnumerationMutationException exceptionWithObject: _list]; | | | 448 449 450 451 452 453 454 455 456 457 | - (void)reset { if (*_mutationsPtr != _mutations) @throw [OFEnumerationMutationException exceptionWithObject: _list]; _current = _list.firstListObject; } @end |
Modified src/OFLocale.m from [076e9d8203] to [eba1e0de33].
︙ | ︙ | |||
145 146 147 148 149 150 151 | + (OFLocale *)currentLocale { return currentLocale; } + (OFString *)language { | | | | | | | 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 | + (OFLocale *)currentLocale { return currentLocale; } + (OFString *)language { return currentLocale.language; } + (OFString *)territory { return currentLocale.territory; } + (of_string_encoding_t)encoding { return currentLocale.encoding; } + (OFString *)decimalPoint { return currentLocale.decimalPoint; } #ifdef OF_HAVE_FILES + (void)addLanguageDirectory: (OFString *)path { [currentLocale addLanguageDirectory: path]; } #endif - (instancetype)init { self = [super init]; @try { #ifndef OF_AMIGAOS char *locale, *messagesLocale = NULL; if (currentLocale != nil) @throw [OFInitializationFailedException exceptionWithClass: self.class]; _encoding = OF_STRING_ENCODING_UTF_8; _decimalPoint = @"."; _localizedStrings = [[OFMutableArray alloc] init]; if ((locale = setlocale(LC_ALL, "")) != NULL) _decimalPoint = [[OFString alloc] |
︙ | ︙ | |||
319 320 321 322 323 324 325 | @try { map = [[OFString stringWithContentsOfFile: mapPath] JSONValue]; } @catch (OFOpenItemFailedException *e) { objc_autoreleasePoolPop(pool); return; } | | | | < | 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 | @try { map = [[OFString stringWithContentsOfFile: mapPath] JSONValue]; } @catch (OFOpenItemFailedException *e) { objc_autoreleasePoolPop(pool); return; } language = _language.lowercaseString; territory = _territory.lowercaseString; if (territory == nil) territory = @""; languageFile = [[map objectForKey: language] objectForKey: territory]; if (languageFile == nil) languageFile = [[map objectForKey: language] objectForKey: @""]; if (languageFile == nil) { objc_autoreleasePoolPop(pool); return; } languageFile = [path stringByAppendingPathComponent: |
︙ | ︙ | |||
385 386 387 388 389 390 391 | UTF8String = [string UTF8String]; UTF8StringLength = [string UTF8StringLength]; break; } if (UTF8String == NULL) { | | | | 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 | UTF8String = [string UTF8String]; UTF8StringLength = [string UTF8StringLength]; break; } if (UTF8String == NULL) { UTF8String = fallback.UTF8String; UTF8StringLength = fallback.UTF8StringLength; } state = 0; last = 0; for (size_t i = 0; i < UTF8StringLength; i++) { switch (state) { case 0: |
︙ | ︙ |
Modified src/OFMD5Hash.m from [7e71ee5050] to [d8543cb4a1].
︙ | ︙ | |||
140 141 142 143 144 145 146 | - (instancetype)init { self = [super init]; @try { _iVarsData = [[OFSecureData alloc] initWithCount: sizeof(*_iVars)]; | | | 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 | - (instancetype)init { self = [super init]; @try { _iVarsData = [[OFSecureData alloc] initWithCount: sizeof(*_iVars)]; _iVars = _iVarsData.mutableItems; [self of_resetState]; } @catch (id e) { [self release]; @throw e; } |
︙ | ︙ | |||
168 169 170 171 172 173 174 | } - (id)copy { OFMD5Hash *copy = [[OFMD5Hash alloc] of_init]; copy->_iVarsData = [_iVarsData copy]; | | | 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 | } - (id)copy { OFMD5Hash *copy = [[OFMD5Hash alloc] of_init]; copy->_iVarsData = [_iVarsData copy]; copy->_iVars = copy->_iVarsData.mutableItems; copy->_calculated = _calculated; return copy; } - (void)of_resetState { |
︙ | ︙ |
Modified src/OFMessagePackExtension.m from [a322670b7a] to [4d6e30d967].
︙ | ︙ | |||
40 41 42 43 44 45 46 | - (instancetype)initWithType: (int8_t)type data: (OFData *)data { self = [super init]; @try { | | | 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 | - (instancetype)initWithType: (int8_t)type data: (OFData *)data { self = [super init]; @try { if (data == nil || data.itemSize != 1) @throw [OFInvalidArgumentException exception]; _type = type; _data = [data copy]; } @catch (id e) { [self release]; @throw e; |
︙ | ︙ | |||
64 65 66 67 68 69 70 | [super dealloc]; } - (OFData *)messagePackRepresentation { OFMutableData *ret; uint8_t prefix; | | | 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 | [super dealloc]; } - (OFData *)messagePackRepresentation { OFMutableData *ret; uint8_t prefix; size_t count = _data.count; if (count == 1) { ret = [OFMutableData dataWithCapacity: 3]; prefix = 0xD4; [ret addItem: &prefix]; |
︙ | ︙ | |||
141 142 143 144 145 146 147 | length = OF_BSWAP32_IF_LE((uint32_t)count); [ret addItems: &length count: 4]; [ret addItem: &_type]; } | | | | 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 | length = OF_BSWAP32_IF_LE((uint32_t)count); [ret addItems: &length count: 4]; [ret addItem: &_type]; } [ret addItems: _data.items count: _data.count]; [ret makeImmutable]; return ret; } - (OFString *)description |
︙ | ︙ | |||
180 181 182 183 184 185 186 | - (uint32_t)hash { uint32_t hash; OF_HASH_INIT(hash); OF_HASH_ADD(hash, (uint8_t)_type); | | | 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 | - (uint32_t)hash { uint32_t hash; OF_HASH_INIT(hash); OF_HASH_ADD(hash, (uint8_t)_type); OF_HASH_ADD_HASH(hash, _data.hash); OF_HASH_FINALIZE(hash); return hash; } - (id)copy { return [self retain]; } @end |
Modified src/OFMethodSignature.m from [65b8b721a8] to [90270cac7b].
︙ | ︙ | |||
675 676 677 678 679 680 681 | [_offsets release]; [super dealloc]; } - (size_t)numberOfArguments { | | | | | 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 | [_offsets release]; [super dealloc]; } - (size_t)numberOfArguments { return _typesPointers.count - 1; } - (const char *)methodReturnType { return *(const char **)_typesPointers.firstItem; } - (size_t)frameLength { return *(size_t *)_offsets.firstItem; } - (const char *)argumentTypeAtIndex: (size_t)idx { return *(const char **)[_typesPointers itemAtIndex: idx + 1]; } - (size_t)argumentOffsetAtIndex: (size_t)idx { return *(size_t *)[_offsets itemAtIndex: idx + 1]; } @end |
Modified src/OFMutableArray.m from [652f7d9468] to [d1d4c770ab].
︙ | ︙ | |||
256 257 258 259 260 261 262 | { return [[OFArray alloc] initWithArray: self]; } - (void)addObject: (id)object { [self insertObject: object | | | | 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 | { return [[OFArray alloc] initWithArray: self]; } - (void)addObject: (id)object { [self insertObject: object atIndex: self.count]; } - (void)addObjectsFromArray: (OFArray *)array { [self insertObjectsFromArray: array atIndex: self.count]; } - (void)insertObject: (id)object atIndex: (size_t)idx { OF_UNRECOGNIZED_SELECTOR } |
︙ | ︙ | |||
302 303 304 305 306 307 308 | withObject: (id)newObject { size_t count; if (oldObject == nil || newObject == nil) @throw [OFInvalidArgumentException exception]; | | | | 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 | withObject: (id)newObject { size_t count; if (oldObject == nil || newObject == nil) @throw [OFInvalidArgumentException exception]; count = self.count; for (size_t i = 0; i < count; i++) { if ([[self objectAtIndex: i] isEqual: oldObject]) { [self replaceObjectAtIndex: i withObject: newObject]; return; } } } - (void)replaceObjectIdenticalTo: (id)oldObject withObject: (id)newObject { size_t count; if (oldObject == nil || newObject == nil) @throw [OFInvalidArgumentException exception]; count = self.count; for (size_t i = 0; i < count; i++) { if ([self objectAtIndex: i] == oldObject) { [self replaceObjectAtIndex: i withObject: newObject]; return; |
︙ | ︙ | |||
345 346 347 348 349 350 351 | - (void)removeObject: (id)object { size_t count; if (object == nil) @throw [OFInvalidArgumentException exception]; | | | | | | 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 | - (void)removeObject: (id)object { size_t count; if (object == nil) @throw [OFInvalidArgumentException exception]; count = self.count; for (size_t i = 0; i < count; i++) { if ([[self objectAtIndex: i] isEqual: object]) { [self removeObjectAtIndex: i]; return; } } } - (void)removeObjectIdenticalTo: (id)object { size_t count; if (object == nil) @throw [OFInvalidArgumentException exception]; count = self.count; for (size_t i = 0; i < count; i++) { if ([self objectAtIndex: i] == object) { [self removeObjectAtIndex: i]; return; } } } - (void)removeObjectsInRange: (of_range_t)range { for (size_t i = 0; i < range.length; i++) [self removeObjectAtIndex: range.location]; } - (void)removeLastObject { size_t count = self.count; if (count == 0) return; [self removeObjectAtIndex: count - 1]; } - (void)removeAllObjects { [self removeObjectsInRange: of_range(0, self.count)]; } #ifdef OF_HAVE_BLOCKS - (void)replaceObjectsUsingBlock: (of_array_replace_block_t)block { [self enumerateObjectsUsingBlock: ^ (id object, size_t idx, bool *stop) { |
︙ | ︙ | |||
435 436 437 438 439 440 441 | [self sortUsingSelector: @selector(compare:) options: 0]; } - (void)sortUsingSelector: (SEL)selector options: (int)options { | | | | | 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 | [self sortUsingSelector: @selector(compare:) options: 0]; } - (void)sortUsingSelector: (SEL)selector options: (int)options { size_t count = self.count; if (count == 0 || count == 1) return; quicksort(self, 0, count - 1, selector, options); } #ifdef OF_HAVE_BLOCKS - (void)sortUsingComparator: (of_comparator_t)comparator options: (int)options { size_t count = self.count; if (count == 0 || count == 1) return; quicksortWithBlock(self, 0, count - 1, comparator, options); } #endif - (void)reverse { size_t i, j, count = self.count; if (count == 0 || count == 1) return; for (i = 0, j = count - 1; i < j; i++, j--) [self exchangeObjectAtIndex: i withObjectAtIndex: j]; } - (void)makeImmutable { } @end |
Modified src/OFMutableArray_adjacent.m from [feb12f542d] to [e7c93457b6].
︙ | ︙ | |||
76 77 78 79 80 81 82 | _mutations++; } - (void)insertObjectsFromArray: (OFArray *)array atIndex: (size_t)idx { | | | | 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 | _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]; |
︙ | ︙ | |||
102 103 104 105 106 107 108 | { id *objects; size_t count; if (oldObject == nil || newObject == nil) @throw [OFInvalidArgumentException exception]; | | | | 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 | { 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; |
︙ | ︙ | |||
125 126 127 128 129 130 131 | { id *objects; id oldObject; if (object == nil) @throw [OFInvalidArgumentException exception]; | | | | | | | | | | | | 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 | { 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]; |
︙ | ︙ | |||
219 220 221 222 223 224 225 | _mutations++; #endif } - (void)removeAllObjects { | | | | | > | 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 | _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]; |
︙ | ︙ | |||
255 256 257 258 259 260 261 | [self freeMemory: copy]; } } - (void)removeLastObject { #ifndef __clang_analyzer__ | | | | | | | | | | | | | 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 | [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 |
︙ | ︙ |
Modified src/OFMutableData.h from [55b86d5e3b] to [68ac1d26ec].
︙ | ︙ | |||
28 29 30 31 32 33 34 35 36 37 38 39 40 41 | * @brief A class for storing and manipulating arbitrary data in an array. */ @interface OFMutableData: OFData { size_t _capacity; } /*! * @brief Creates a new OFMutableData with an item size of 1. * * @return A new autoreleased OFMutableData */ + (instancetype)data; | > > > > > > > > > > | 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 | * @brief A class for storing and manipulating arbitrary data in an array. */ @interface OFMutableData: OFData { size_t _capacity; } /*! * @brief All items of the OFMutableData as a C array. * * @warning The pointer is only valid until the OFMutableData is changed! * * Modifying the returned array directly is allowed and will change the contents * of the data. */ @property (readonly, nonatomic) void *mutableItems OF_RETURNS_INNER_POINTER; /*! * @brief Creates a new OFMutableData with an item size of 1. * * @return A new autoreleased OFMutableData */ + (instancetype)data; |
︙ | ︙ | |||
102 103 104 105 106 107 108 109 110 111 112 113 114 115 | * @param itemSize The size of a single element in the OFMutableData * @param capacity The initial capacity for the OFMutableData * @return An initialized OFMutableData */ - (instancetype)initWithItemSize: (size_t)itemSize capacity: (size_t)capacity; /*! * @brief Adds an item to the OFMutableData. * * @param item A pointer to an arbitrary item */ - (void)addItem: (const void *)item; | > > > > > > > > > > > | 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 | * @param itemSize The size of a single element in the OFMutableData * @param capacity The initial capacity for the OFMutableData * @return An initialized OFMutableData */ - (instancetype)initWithItemSize: (size_t)itemSize capacity: (size_t)capacity; /*! * @brief Returns a specific item of the OFMutableData. * * Modifying the returned item directly is allowed and will change the contents * of the data. * * @param index The number of the item to return * @return The specified item of the OFMutableData */ - (void *)mutableItemAtIndex: (size_t)index OF_RETURNS_INNER_POINTER; /*! * @brief Adds an item to the OFMutableData. * * @param item A pointer to an arbitrary item */ - (void)addItem: (const void *)item; |
︙ | ︙ | |||
176 177 178 179 180 181 182 | /*! * @brief Converts the mutable URL to an immutable URL. */ - (void)makeImmutable; @end | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | 197 198 199 200 201 202 203 204 | /*! * @brief Converts the mutable URL to an immutable URL. */ - (void)makeImmutable; @end OF_ASSUME_NONNULL_END |
Modified src/OFMutableData.m from [fad07c6a98] to [4177ee034d].
︙ | ︙ | |||
137 138 139 140 141 142 143 144 145 146 147 148 149 150 | { self = [super initWithStringRepresentation: string]; _capacity = _count; return self; } - (OFData *)subdataWithRange: (of_range_t)range { if (range.length > SIZE_MAX - range.location || range.location + range.length > _count) @throw [OFOutOfRangeException exception]; | > > > > > > > > > > > > > | 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 | { self = [super initWithStringRepresentation: string]; _capacity = _count; return self; } - (void *)mutableItems { return _items; } - (void *)mutableItemAtIndex: (size_t)idx { if (idx >= _count) @throw [OFOutOfRangeException exception]; return _items + idx * _itemSize; } - (OFData *)subdataWithRange: (of_range_t)range { if (range.length > SIZE_MAX - range.location || range.location + range.length > _count) @throw [OFOutOfRangeException exception]; |
︙ | ︙ |
Modified src/OFMutableDictionary.m from [1ca29dfd97] to [08e850f34a].
︙ | ︙ | |||
183 184 185 186 187 188 189 | OF_UNRECOGNIZED_SELECTOR } - (void)removeAllObjects { void *pool = objc_autoreleasePoolPush(); | | | 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 | OF_UNRECOGNIZED_SELECTOR } - (void)removeAllObjects { void *pool = objc_autoreleasePoolPush(); for (id key in self.allKeys) [self removeObjectForKey: key]; objc_autoreleasePoolPop(pool); } - (id)copy { |
︙ | ︙ |
Modified src/OFMutableSet.m from [d3bbc8f1ec] to [5d818f447d].
︙ | ︙ | |||
165 166 167 168 169 170 171 | for (id object in set) [self removeObject: object]; } - (void)intersectSet: (OFSet *)set { void *pool = objc_autoreleasePoolPush(); | | | 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 | for (id object in set) [self removeObject: object]; } - (void)intersectSet: (OFSet *)set { void *pool = objc_autoreleasePoolPush(); size_t count = self.count; id *cArray; cArray = [self allocMemoryWithSize: sizeof(id) count: count]; @try { size_t i; |
︙ | ︙ |
Modified src/OFMutableString.m from [91653c54ba] to [3ed2ba1cf6].
︙ | ︙ | |||
235 236 237 238 239 240 241 | if (self == [OFMutableString class]) return (id)&placeholder; return [super alloc]; } #ifdef OF_HAVE_UNICODE_TABLES | | | | | | 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 | if (self == [OFMutableString class]) return (id)&placeholder; return [super alloc]; } #ifdef OF_HAVE_UNICODE_TABLES - (void)of_convertWithWordStartTable: (const of_unichar_t *const [])startTable wordMiddleTable: (const of_unichar_t *const [])middleTable wordStartTableSize: (size_t)startTableSize wordMiddleTableSize: (size_t)middleTableSize { void *pool = objc_autoreleasePoolPush(); const of_unichar_t *characters = self.characters; size_t length = self.length; bool isStart = true; for (size_t i = 0; i < length; i++) { const of_unichar_t *const *table; size_t tableSize; of_unichar_t c = characters[i]; |
︙ | ︙ | |||
272 273 274 275 276 277 278 | objc_autoreleasePoolPop(pool); } #else - (void)of_convertWithWordStartFunction: (char (*)(char))startFunction wordMiddleFunction: (char (*)(char))middleFunction { void *pool = objc_autoreleasePoolPush(); | | | | 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 | objc_autoreleasePoolPop(pool); } #else - (void)of_convertWithWordStartFunction: (char (*)(char))startFunction wordMiddleFunction: (char (*)(char))middleFunction { void *pool = objc_autoreleasePoolPush(); const of_unichar_t *characters = self.characters; size_t length = self.length; bool isStart = true; for (size_t i = 0; i < length; i++) { char (*function)(char) = (isStart ? startFunction : middleFunction); of_unichar_t c = characters[i]; |
︙ | ︙ | |||
310 311 312 313 314 315 316 | objc_autoreleasePoolPop(pool); } - (void)appendString: (OFString *)string { [self insertString: string | | | 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 | objc_autoreleasePoolPop(pool); } - (void)appendString: (OFString *)string { [self insertString: string atIndex: self.length]; } - (void)appendCharacters: (const of_unichar_t *)characters length: (size_t)length { void *pool = objc_autoreleasePoolPush(); |
︙ | ︙ | |||
387 388 389 390 391 392 393 | { char *UTF8String; int UTF8StringLength; if (format == nil) @throw [OFInvalidArgumentException exception]; | | | | 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 | { 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)prependString: (OFString *)string { [self insertString: string atIndex: 0]; } - (void)reverse { size_t i, j, length = self.length; for (i = 0, j = length - 1; i < length / 2; i++, j--) { of_unichar_t tmp = [self characterAtIndex: j]; [self setCharacter: [self characterAtIndex: i] atIndex: j]; [self setCharacter: tmp atIndex: i]; |
︙ | ︙ | |||
487 488 489 490 491 492 493 | - (void)replaceOccurrencesOfString: (OFString *)string withString: (OFString *)replacement { [self replaceOccurrencesOfString: string withString: replacement options: 0 | | | | | | | | | | | | | 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 | - (void)replaceOccurrencesOfString: (OFString *)string withString: (OFString *)replacement { [self replaceOccurrencesOfString: string withString: replacement options: 0 range: of_range(0, self.length)]; } - (void)replaceOccurrencesOfString: (OFString *)string withString: (OFString *)replacement options: (int)options range: (of_range_t)range { void *pool = objc_autoreleasePoolPush(), *pool2; const of_unichar_t *characters; const of_unichar_t *searchCharacters = string.characters; size_t searchLength = string.length; size_t replacementLength = replacement.length; 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 (searchLength > range.length) { objc_autoreleasePoolPop(pool); return; } pool2 = objc_autoreleasePoolPush(); characters = self.characters; for (size_t i = range.location; i <= range.length - searchLength; i++) { if (memcmp(characters + i, searchCharacters, searchLength * sizeof(of_unichar_t)) != 0) continue; [self replaceCharactersInRange: of_range(i, searchLength) withString: replacement]; range.length -= searchLength; range.length += replacementLength; i += replacementLength - 1; objc_autoreleasePoolPop(pool2); pool2 = objc_autoreleasePoolPush(); characters = self.characters; } objc_autoreleasePoolPop(pool); } - (void)deleteLeadingWhitespaces { void *pool = objc_autoreleasePoolPush(); const of_unichar_t *characters = self.characters; size_t i, length = self.length; for (i = 0; i < length; i++) { of_unichar_t c = characters[i]; if (!of_ascii_isspace(c)) break; } objc_autoreleasePoolPop(pool); [self deleteCharactersInRange: of_range(0, i)]; } - (void)deleteTrailingWhitespaces { void *pool; const of_unichar_t *characters, *p; size_t length, d; length = self.length; if (length == 0) return; pool = objc_autoreleasePoolPush(); characters = self.characters; d = 0; for (p = characters + length - 1; p >= characters; p--) { if (!of_ascii_isspace(*p)) break; d++; |
︙ | ︙ |
Modified src/OFMutableString_UTF8.m from [b9817e13bd] to [afad633464].
︙ | ︙ | |||
100 101 102 103 104 105 106 | if ((t = table[0][(uint8_t)_s->cString[i]]) != 0) _s->cString[i] = t; } return; } | | | 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 | 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) { |
︙ | ︙ | |||
356 357 358 359 360 361 362 | - (void)appendString: (OFString *)string { size_t UTF8StringLength; if (string == nil) @throw [OFInvalidArgumentException exception]; | | | | | 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 | - (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: [OFString_UTF8 class]] || [string isKindOfClass: [OFMutableString_UTF8 class]]) { if (((OFString_UTF8 *)string)->_s->isUTF8) _s->isUTF8 = true; |
︙ | ︙ | |||
427 428 429 430 431 432 433 | { char *UTF8String; int UTF8StringLength; if (format == nil) @throw [OFInvalidArgumentException exception]; | | | 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 | { 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 { |
︙ | ︙ | |||
531 532 533 534 535 536 537 | if (idx > _s->length) @throw [OFOutOfRangeException exception]; if (_s->isUTF8) idx = of_string_utf8_get_position(_s->cString, idx, _s->cStringLength); | | | | | | | 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 | 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: [OFString_UTF8 class]] || [string isKindOfClass: [OFMutableString_UTF8 class]]) { if (((OFString_UTF8 *)string)->_s->isUTF8) _s->isUTF8 = true; } else _s->isUTF8 = true; |
︙ | ︙ | |||
596 597 598 599 600 601 602 | if (replacement == nil) @throw [OFInvalidArgumentException exception]; if (range.length > SIZE_MAX - range.location || end > _s->length) @throw [OFOutOfRangeException exception]; | | | | | | | 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 | 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) |
︙ | ︙ | |||
651 652 653 654 655 656 657 | } - (void)replaceOccurrencesOfString: (OFString *)string withString: (OFString *)replacement options: (int)options range: (of_range_t)range { | | | | | | | | | | | | | 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 | } - (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 |
︙ | ︙ |
Modified src/OFMutableURL.m from [281bdc699b] to [4c8969afe8].
︙ | ︙ | |||
175 176 177 178 179 180 181 | } - (void)setPathComponents: (OFArray *)components { void *pool = objc_autoreleasePoolPush(); if (components == nil) { | | | | | | 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 | } - (void)setPathComponents: (OFArray *)components { void *pool = objc_autoreleasePoolPush(); if (components == nil) { self.path = nil; return; } if (components.count == 0) @throw [OFInvalidFormatException exception]; if ([components.firstObject length] != 0) @throw [OFInvalidFormatException exception]; self.path = [components componentsJoinedByString: @"/"]; objc_autoreleasePoolPop(pool); } - (void)setQuery: (OFString *)query { void *pool = objc_autoreleasePoolPush(); |
︙ | ︙ | |||
267 268 269 270 271 272 273 | return; pool = objc_autoreleasePoolPush(); array = [[[_URLEncodedPath componentsSeparatedByString: @"/"] mutableCopy] autorelease]; | | | | | | | | | | 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 | return; pool = objc_autoreleasePoolPush(); array = [[[_URLEncodedPath componentsSeparatedByString: @"/"] mutableCopy] autorelease]; if ([array.firstObject length] != 0) @throw [OFInvalidFormatException exception]; endsWithEmpty = ([array.lastObject length] == 0); while (!done) { size_t length = array.count; done = true; for (size_t i = 0; i < length; i++) { OFString *current = [array objectAtIndex: i]; OFString *parent = (i > 0 ? [array objectAtIndex: i - 1] : nil); if ([current isEqual: @"."] || current.length == 0) { [array removeObjectAtIndex: i]; done = false; break; } if ([current isEqual: @".."] && parent != nil && ![parent isEqual: @".."]) { [array removeObjectsInRange: of_range(i - 1, 2)]; done = false; break; } } } [array insertObject: @"" atIndex: 0]; if (endsWithEmpty) [array addObject: @""]; path = [array componentsJoinedByString: @"/"]; if (path.length == 0) path = @"/"; [self setURLEncodedPath: path]; objc_autoreleasePoolPop(pool); } - (void)makeImmutable { object_setClass(self, [OFURL class]); } @end |
Modified src/OFMutableZIPArchiveEntry.m from [477a94e0e9] to [b63548e22a].
︙ | ︙ | |||
42 43 44 45 46 47 48 | } - (void)setFileName: (OFString *)fileName { void *pool = objc_autoreleasePoolPush(); OFString *old; | | | | | | 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 | } - (void)setFileName: (OFString *)fileName { void *pool = objc_autoreleasePoolPush(); OFString *old; if (fileName.UTF8StringLength > UINT16_MAX) @throw [OFOutOfRangeException exception]; old = _fileName; _fileName = [fileName copy]; [old release]; objc_autoreleasePoolPop(pool); } - (void)setFileComment: (OFString *)fileComment { void *pool = objc_autoreleasePoolPush(); OFString *old; if (fileComment.UTF8StringLength > UINT16_MAX) @throw [OFOutOfRangeException exception]; old = _fileComment; _fileComment = [fileComment copy]; [old release]; objc_autoreleasePoolPop(pool); } - (void)setExtraField: (OFData *)extraField { void *pool = objc_autoreleasePoolPush(); OFData *old; if (extraField.itemSize != 1) @throw [OFInvalidArgumentException exception]; if (extraField.count > UINT16_MAX) @throw [OFOutOfRangeException exception]; old = _extraField; _extraField = [extraField copy]; [old release]; objc_autoreleasePoolPop(pool); |
︙ | ︙ | |||
99 100 101 102 103 104 105 | _minVersionNeeded = minVersionNeeded; } - (void)setModificationDate: (OFDate *)date { void *pool = objc_autoreleasePoolPush(); | | | | | | | 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 | _minVersionNeeded = minVersionNeeded; } - (void)setModificationDate: (OFDate *)date { void *pool = objc_autoreleasePoolPush(); _lastModifiedFileDate = (((date.localYear - 1980) & 0xFF) << 9) | ((date.localMonthOfYear & 0x0F) << 5) | (date.localDayOfMonth & 0x1F); _lastModifiedFileTime = ((date.localHour & 0x1F) << 11) | ((date.localMinute & 0x3F) << 5) | ((date.second >> 1) & 0x0F); objc_autoreleasePoolPop(pool); } - (void)setCompressionMethod: (uint16_t)compressionMethod { _compressionMethod = compressionMethod; |
︙ | ︙ |
Modified src/OFMutex.m from [08bcd2f7b5] to [99a3d0e9e5].
︙ | ︙ | |||
34 35 36 37 38 39 40 | } - (instancetype)init { self = [super init]; if (!of_mutex_new(&_mutex)) { | | | 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 | } - (instancetype)init { self = [super init]; if (!of_mutex_new(&_mutex)) { Class c = self.class; [self release]; @throw [OFInitializationFailedException exceptionWithClass: c]; } _initialized = true; return self; |
︙ | ︙ | |||
75 76 77 78 79 80 81 | if (!of_mutex_unlock(&_mutex)) @throw [OFUnlockFailedException exceptionWithLock: self]; } - (OFString *)description { if (_name == nil) | | | < | 75 76 77 78 79 80 81 82 83 84 85 86 | if (!of_mutex_unlock(&_mutex)) @throw [OFUnlockFailedException exceptionWithLock: self]; } - (OFString *)description { if (_name == nil) return super.description; return [OFString stringWithFormat: @"<%@: %@>", self.className, _name]; } @end |
Modified src/OFNull.m from [353afe99b3] to [50ff4e3845].
︙ | ︙ | |||
46 47 48 49 50 51 52 | { void *pool; [self release]; pool = objc_autoreleasePoolPush(); | | | | 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 | { void *pool; [self release]; pool = objc_autoreleasePoolPush(); if (![element.name isEqual: self.className] || ![element.namespace isEqual: OF_SERIALIZATION_NS]) @throw [OFInvalidArgumentException exception]; objc_autoreleasePoolPop(pool); return [OFNull null]; } |
︙ | ︙ | |||
70 71 72 73 74 75 76 | } - (OFXMLElement *)XMLElementBySerializing { void *pool = objc_autoreleasePoolPush(); OFXMLElement *element; | | | 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 | } - (OFXMLElement *)XMLElementBySerializing { void *pool = objc_autoreleasePoolPush(); OFXMLElement *element; element = [OFXMLElement elementWithName: self.className namespace: OF_SERIALIZATION_NS]; [element retain]; objc_autoreleasePoolPop(pool); return [element autorelease]; |
︙ | ︙ |
Modified src/OFNumber.m from [bef2101a40] to [402455fc05].
︙ | ︙ | |||
528 529 530 531 532 533 534 | { self = [super init]; @try { void *pool = objc_autoreleasePoolPush(); OFString *typeString; | | | | | | | | | 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 | { self = [super init]; @try { void *pool = objc_autoreleasePoolPush(); OFString *typeString; if (![element.name isEqual: self.className] || ![element.namespace isEqual: OF_SERIALIZATION_NS]) @throw [OFInvalidArgumentException exception]; typeString = [element attributeForName: @"type"].stringValue; if ([typeString isEqual: @"boolean"]) { _type = OF_NUMBER_TYPE_BOOL; if ([[element stringValue] isEqual: @"true"]) _value.bool_ = true; else if ([[element stringValue] isEqual: @"false"]) _value.bool_ = false; else @throw [OFInvalidArgumentException exception]; } else if ([typeString isEqual: @"unsigned"]) { /* * FIXME: This will fail if the value is bigger than * INTMAX_MAX! */ _type = OF_NUMBER_TYPE_UINTMAX; _value.uIntMax = element.decimalValue; } else if ([typeString isEqual: @"signed"]) { _type = OF_NUMBER_TYPE_INTMAX; _value.intMax = element.decimalValue; } else if ([typeString isEqual: @"float"]) { union { float f; uint32_t u; } f; f.u = OF_BSWAP32_IF_LE( (uint32_t)element.hexadecimalValue); _type = OF_NUMBER_TYPE_FLOAT; _value.float_ = OF_BSWAP_FLOAT_IF_LE(f.f); } else if ([typeString isEqual: @"double"]) { union { double d; uint64_t u; } d; d.u = OF_BSWAP64_IF_LE( (uint64_t)element.hexadecimalValue); _type = OF_NUMBER_TYPE_DOUBLE; _value.double_ = OF_BSWAP_DOUBLE_IF_LE(d.d); } else @throw [OFInvalidArgumentException exception]; objc_autoreleasePoolPop(pool); |
︙ | ︙ | |||
982 983 984 985 986 987 988 | if (![object isKindOfClass: [OFNumber class]]) return false; number = object; if (_type & OF_NUMBER_TYPE_FLOAT || number->_type & OF_NUMBER_TYPE_FLOAT) { | | | | | | | | | | | | | | | | | | | | 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 | if (![object isKindOfClass: [OFNumber class]]) return false; number = object; if (_type & OF_NUMBER_TYPE_FLOAT || number->_type & OF_NUMBER_TYPE_FLOAT) { double value1 = number.doubleValue; double value2 = self.doubleValue; if (isnan(value1) && isnan(value2)) return true; if (isnan(value1) || isnan(value2)) return false; return (value1 == value2); } if (_type & OF_NUMBER_TYPE_SIGNED || number->_type & OF_NUMBER_TYPE_SIGNED) return (number.intMaxValue == self.intMaxValue); return (number.uIntMaxValue == self.uIntMaxValue); } - (of_comparison_result_t)compare: (id <OFComparing>)object { OFNumber *number; if (![(id)object isKindOfClass: [OFNumber class]]) @throw [OFInvalidArgumentException exception]; number = (OFNumber *)object; if (_type & OF_NUMBER_TYPE_FLOAT || number->_type & OF_NUMBER_TYPE_FLOAT) { double double1 = self.doubleValue; double double2 = number.doubleValue; if (double1 > double2) return OF_ORDERED_DESCENDING; if (double1 < double2) return OF_ORDERED_ASCENDING; return OF_ORDERED_SAME; } else if (_type & OF_NUMBER_TYPE_SIGNED || number->_type & OF_NUMBER_TYPE_SIGNED) { intmax_t int1 = self.intMaxValue; intmax_t int2 = number.intMaxValue; if (int1 > int2) return OF_ORDERED_DESCENDING; if (int1 < int2) return OF_ORDERED_ASCENDING; return OF_ORDERED_SAME; } else { uintmax_t uint1 = self.uIntMaxValue; uintmax_t uint2 = number.uIntMaxValue; if (uint1 > uint2) return OF_ORDERED_DESCENDING; if (uint1 < uint2) return OF_ORDERED_ASCENDING; return OF_ORDERED_SAME; } } - (uint32_t)hash { of_number_type_t type = _type; uint32_t hash; /* Do we really need signed to represent this number? */ if (type & OF_NUMBER_TYPE_SIGNED && self.intMaxValue >= 0) type &= ~OF_NUMBER_TYPE_SIGNED; /* Do we really need floating point to represent this number? */ if (type & OF_NUMBER_TYPE_FLOAT) { double v = self.doubleValue; if (v < 0) { if (v == self.intMaxValue) { type &= ~OF_NUMBER_TYPE_FLOAT; type |= OF_NUMBER_TYPE_SIGNED; } } else { if (v == self.uIntMaxValue) type &= ~OF_NUMBER_TYPE_FLOAT; } } OF_HASH_INIT(hash); if (type & OF_NUMBER_TYPE_FLOAT) { union { double d; uint8_t b[sizeof(double)]; } d; if (isnan(self.doubleValue)) return 0; d.d = OF_BSWAP_DOUBLE_IF_BE(self.doubleValue); for (uint_fast8_t i = 0; i < sizeof(double); i++) OF_HASH_ADD(hash, d.b[i]); } else if (type & OF_NUMBER_TYPE_SIGNED) { intmax_t v = self.intMaxValue * -1; while (v != 0) { OF_HASH_ADD(hash, v & 0xFF); v >>= 8; } OF_HASH_ADD(hash, 1); } else { uintmax_t v = self.uIntMaxValue; while (v != 0) { OF_HASH_ADD(hash, v & 0xFF); v >>= 8; } } |
︙ | ︙ | |||
1130 1131 1132 1133 1134 1135 1136 | case OF_NUMBER_TYPE_UINT8: case OF_NUMBER_TYPE_UINT16: case OF_NUMBER_TYPE_UINT32: case OF_NUMBER_TYPE_UINT64: case OF_NUMBER_TYPE_SIZE: case OF_NUMBER_TYPE_UINTMAX: case OF_NUMBER_TYPE_UINTPTR: | | | | 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 | case OF_NUMBER_TYPE_UINT8: case OF_NUMBER_TYPE_UINT16: case OF_NUMBER_TYPE_UINT32: case OF_NUMBER_TYPE_UINT64: case OF_NUMBER_TYPE_SIZE: case OF_NUMBER_TYPE_UINTMAX: case OF_NUMBER_TYPE_UINTPTR: return [OFString stringWithFormat: @"%ju", self.uIntMaxValue]; case OF_NUMBER_TYPE_CHAR: case OF_NUMBER_TYPE_SHORT: case OF_NUMBER_TYPE_INT: case OF_NUMBER_TYPE_LONG: case OF_NUMBER_TYPE_LONGLONG: case OF_NUMBER_TYPE_INT8: case OF_NUMBER_TYPE_INT16: case OF_NUMBER_TYPE_INT32: case OF_NUMBER_TYPE_INT64: case OF_NUMBER_TYPE_SSIZE: case OF_NUMBER_TYPE_INTMAX: case OF_NUMBER_TYPE_PTRDIFF: case OF_NUMBER_TYPE_INTPTR: return [OFString stringWithFormat: @"%jd", self.intMaxValue]; case OF_NUMBER_TYPE_FLOAT: ret = [OFMutableString stringWithFormat: @"%g", _value.float_]; if (![ret containsString: @"."]) [ret appendString: @".0"]; [ret makeImmutable]; |
︙ | ︙ | |||
1173 1174 1175 1176 1177 1178 1179 | } - (OFXMLElement *)XMLElementBySerializing { void *pool = objc_autoreleasePoolPush(); OFXMLElement *element; | | | | 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 | } - (OFXMLElement *)XMLElementBySerializing { void *pool = objc_autoreleasePoolPush(); OFXMLElement *element; element = [OFXMLElement elementWithName: self.className namespace: OF_SERIALIZATION_NS stringValue: self.description]; switch (_type) { case OF_NUMBER_TYPE_BOOL: [element addAttributeWithName: @"type" stringValue: @"boolean"]; break; case OF_NUMBER_TYPE_UCHAR: |
︙ | ︙ | |||
1223 1224 1225 1226 1227 1228 1229 | uint32_t u; } f; f.f = OF_BSWAP_FLOAT_IF_LE(_value.float_); [element addAttributeWithName: @"type" stringValue: @"float"]; | | | | | | 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 | uint32_t u; } f; f.f = OF_BSWAP_FLOAT_IF_LE(_value.float_); [element addAttributeWithName: @"type" stringValue: @"float"]; element.stringValue = [OFString stringWithFormat: @"%08" PRIx32, OF_BSWAP32_IF_LE(f.u)]; break; case OF_NUMBER_TYPE_DOUBLE:; union { double d; uint64_t u; } d; d.d = OF_BSWAP_DOUBLE_IF_LE(_value.double_); [element addAttributeWithName: @"type" stringValue: @"double"]; element.stringValue = [OFString stringWithFormat: @"%016" PRIx64, OF_BSWAP64_IF_LE(d.u)]; break; default: @throw [OFInvalidFormatException exception]; } [element retain]; |
︙ | ︙ | |||
1274 1275 1276 1277 1278 1279 1280 | depth: (size_t)depth { double doubleValue; if (_type == OF_NUMBER_TYPE_BOOL) return (_value.bool_ ? @"true" : @"false"); | | | | 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 | depth: (size_t)depth { double doubleValue; if (_type == OF_NUMBER_TYPE_BOOL) return (_value.bool_ ? @"true" : @"false"); doubleValue = self.doubleValue; if (isinf(doubleValue)) { if (options & OF_JSON_REPRESENTATION_JSON5) { if (doubleValue > 0) return @"Infinity"; else return @"-Infinity"; } else @throw [OFInvalidArgumentException exception]; } return self.description; } - (OFData *)messagePackRepresentation { OFMutableData *data; if (_type == OF_NUMBER_TYPE_BOOL) { |
︙ | ︙ | |||
1318 1319 1320 1321 1322 1323 1324 | data = [OFMutableData dataWithItemSize: 1 capacity: 9]; [data addItem: &type]; [data addItems: &tmp count: sizeof(tmp)]; } else if (_type & OF_NUMBER_TYPE_SIGNED) { | | | 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 | data = [OFMutableData dataWithItemSize: 1 capacity: 9]; [data addItem: &type]; [data addItems: &tmp count: sizeof(tmp)]; } else if (_type & OF_NUMBER_TYPE_SIGNED) { intmax_t value = self.intMaxValue; if (value >= -32 && value < 0) { uint8_t tmp = 0xE0 | ((uint8_t)(value - 32) & 0x1F); data = [OFMutableData dataWithItems: &tmp count: 1]; } else if (value >= INT8_MIN && value <= INT8_MAX) { |
︙ | ︙ | |||
1367 1368 1369 1370 1371 1372 1373 | [data addItem: &type]; [data addItems: &tmp count: sizeof(tmp)]; } else @throw [OFOutOfRangeException exception]; } else { | | | 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 | [data addItem: &type]; [data addItems: &tmp count: sizeof(tmp)]; } else @throw [OFOutOfRangeException exception]; } else { uintmax_t value = self.uIntMaxValue; if (value <= 127) { uint8_t tmp = ((uint8_t)value & 0x7F); data = [OFMutableData dataWithItems: &tmp count: 1]; } else if (value <= UINT8_MAX) { |
︙ | ︙ |
Modified src/OFObject+KeyValueCoding.m from [06ea9a409d] to [96857463c3].
︙ | ︙ | |||
30 31 32 33 34 35 36 | #import "OFUndefinedKeyException.h" int _OFObject_KeyValueCoding_reference; @implementation OFObject (KeyValueCoding) - (id)valueForKey: (OFString *)key { | | | | | | | | 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 | #import "OFUndefinedKeyException.h" int _OFObject_KeyValueCoding_reference; @implementation OFObject (KeyValueCoding) - (id)valueForKey: (OFString *)key { SEL selector = sel_registerName(key.UTF8String); OFMethodSignature *methodSignature = [self methodSignatureForSelector: selector]; id ret; if (methodSignature == nil) { size_t keyLength; char *name; if ((keyLength = key.UTF8StringLength) < 1) return [self valueForUndefinedKey: key]; if ((name = malloc(keyLength + 3)) == NULL) @throw [OFOutOfMemoryException exceptionWithRequestedSize: keyLength + 3]; @try { memcpy(name, "is", 2); memcpy(name + 2, key.UTF8String, keyLength); name[keyLength + 2] = '\0'; name[2] = of_ascii_toupper(name[2]); selector = sel_registerName(name); } @finally { free(name); } methodSignature = [self methodSignatureForSelector: selector]; if (methodSignature == NULL) return [self valueForUndefinedKey: key]; switch (*methodSignature.methodReturnType) { case '@': case '#': return [self valueForUndefinedKey: key]; } } if (methodSignature.numberOfArguments != 2 || *[methodSignature argumentTypeAtIndex: 0] != '@' || *[methodSignature argumentTypeAtIndex: 1] != ':') return [self valueForUndefinedKey: key]; switch (*methodSignature.methodReturnType) { case '@': case '#': ret = [self performSelector: selector]; break; #define CASE(encoding, type, method) \ case encoding: \ { \ |
︙ | ︙ | |||
124 125 126 127 128 129 130 | { size_t keyLength; char *name; SEL selector; OFMethodSignature *methodSignature; const char *valueType; | | | | | | 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 | { size_t keyLength; char *name; SEL selector; OFMethodSignature *methodSignature; const char *valueType; if ((keyLength = key.UTF8StringLength) < 1) { [self setValue: value forUndefinedKey: key]; return; } if ((name = malloc(keyLength + 5)) == NULL) @throw [OFOutOfMemoryException exceptionWithRequestedSize: keyLength + 5]; @try { memcpy(name, "set", 3); memcpy(name + 3, key.UTF8String, keyLength); memcpy(name + keyLength + 3, ":", 2); name[3] = of_ascii_toupper(name[3]); selector = sel_registerName(name); } @finally { free(name); } methodSignature = [self methodSignatureForSelector: selector]; if (methodSignature == nil || methodSignature.numberOfArguments != 3 || *methodSignature.methodReturnType != 'v' || *[methodSignature argumentTypeAtIndex: 0] != '@' || *[methodSignature argumentTypeAtIndex: 1] != ':') { [self setValue: value forUndefinedKey: key]; return; } |
︙ | ︙ |
Modified src/OFObject+Serialization.m from [b584ed859f] to [1406fa2657].
︙ | ︙ | |||
37 38 39 40 41 42 43 | if (![self conformsToProtocol: @protocol(OFSerialization)]) { [self doesNotRecognizeSelector: _cmd]; abort(); } pool = objc_autoreleasePoolPush(); | | | 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 | if (![self conformsToProtocol: @protocol(OFSerialization)]) { [self doesNotRecognizeSelector: _cmd]; abort(); } pool = objc_autoreleasePoolPush(); element = ((id <OFSerialization>)self).XMLElementBySerializing; root = [OFXMLElement elementWithName: @"serialization" namespace: OF_SERIALIZATION_NS]; [root addAttributeWithName: @"version" stringValue: @"1"]; [root addChild: element]; |
︙ | ︙ |
Modified src/OFObject.m from [edba45d06c] to [2b218f823b].
︙ | ︙ | |||
672 673 674 675 676 677 678 | waitUntilDone: (bool)waitUntilDone { void *pool = objc_autoreleasePoolPush(); OFTimer *timer = [OFTimer timerWithTimeInterval: 0 target: self selector: selector repeats: false]; | | | | | 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 | waitUntilDone: (bool)waitUntilDone { void *pool = objc_autoreleasePoolPush(); OFTimer *timer = [OFTimer timerWithTimeInterval: 0 target: self selector: selector repeats: false]; [thread.runLoop addTimer: timer]; if (waitUntilDone) [timer waitUntilDone]; objc_autoreleasePoolPop(pool); } - (void)performSelector: (SEL)selector onThread: (OFThread *)thread withObject: (id)object waitUntilDone: (bool)waitUntilDone { void *pool = objc_autoreleasePoolPush(); OFTimer *timer = [OFTimer timerWithTimeInterval: 0 target: self selector: selector object: object repeats: false]; [thread.runLoop addTimer: timer]; if (waitUntilDone) [timer waitUntilDone]; objc_autoreleasePoolPop(pool); } - (void)performSelector: (SEL)selector onThread: (OFThread *)thread withObject: (id)object1 withObject: (id)object2 waitUntilDone: (bool)waitUntilDone { void *pool = objc_autoreleasePoolPush(); OFTimer *timer = [OFTimer timerWithTimeInterval: 0 target: self selector: selector object: object1 object: object2 repeats: false]; [thread.runLoop addTimer: timer]; if (waitUntilDone) [timer waitUntilDone]; objc_autoreleasePoolPop(pool); } |
︙ | ︙ | |||
735 736 737 738 739 740 741 | OFTimer *timer = [OFTimer timerWithTimeInterval: 0 target: self selector: selector object: object1 object: object2 object: object3 repeats: false]; | | | 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 | OFTimer *timer = [OFTimer timerWithTimeInterval: 0 target: self selector: selector object: object1 object: object2 object: object3 repeats: false]; [thread.runLoop addTimer: timer]; if (waitUntilDone) [timer waitUntilDone]; objc_autoreleasePoolPop(pool); } |
︙ | ︙ | |||
760 761 762 763 764 765 766 | target: self selector: selector object: object1 object: object2 object: object3 object: object4 repeats: false]; | | | 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 | target: self selector: selector object: object1 object: object2 object: object3 object: object4 repeats: false]; [thread.runLoop addTimer: timer]; if (waitUntilDone) [timer waitUntilDone]; objc_autoreleasePoolPop(pool); } |
︙ | ︙ | |||
874 875 876 877 878 879 880 | - (void)performSelector: (SEL)selector onThread: (OFThread *)thread afterDelay: (of_time_interval_t)delay { void *pool = objc_autoreleasePoolPush(); | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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 | - (void)performSelector: (SEL)selector onThread: (OFThread *)thread afterDelay: (of_time_interval_t)delay { void *pool = objc_autoreleasePoolPush(); [thread.runLoop addTimer: [OFTimer timerWithTimeInterval: delay target: self selector: selector repeats: false]]; objc_autoreleasePoolPop(pool); } - (void)performSelector: (SEL)selector onThread: (OFThread *)thread withObject: (id)object afterDelay: (of_time_interval_t)delay { void *pool = objc_autoreleasePoolPush(); [thread.runLoop addTimer: [OFTimer timerWithTimeInterval: delay target: self selector: selector object: object repeats: false]]; objc_autoreleasePoolPop(pool); } - (void)performSelector: (SEL)selector onThread: (OFThread *)thread withObject: (id)object1 withObject: (id)object2 afterDelay: (of_time_interval_t)delay { void *pool = objc_autoreleasePoolPush(); [thread.runLoop addTimer: [OFTimer timerWithTimeInterval: delay target: self selector: selector object: object1 object: object2 repeats: false]]; objc_autoreleasePoolPop(pool); } - (void)performSelector: (SEL)selector onThread: (OFThread *)thread withObject: (id)object1 withObject: (id)object2 withObject: (id)object3 afterDelay: (of_time_interval_t)delay { void *pool = objc_autoreleasePoolPush(); [thread.runLoop addTimer: [OFTimer timerWithTimeInterval: delay target: self selector: selector object: object1 object: object2 object: object3 repeats: false]]; objc_autoreleasePoolPop(pool); } - (void)performSelector: (SEL)selector onThread: (OFThread *)thread withObject: (id)object1 withObject: (id)object2 withObject: (id)object3 withObject: (id)object4 afterDelay: (of_time_interval_t)delay { void *pool = objc_autoreleasePoolPush(); [thread.runLoop addTimer: [OFTimer timerWithTimeInterval: delay target: self selector: selector object: object1 object: object2 object: object3 object: object4 repeats: false]]; objc_autoreleasePoolPop(pool); } #endif - (OFMethodSignature *)methodSignatureForSelector: (SEL)selector { |
︙ | ︙ | |||
996 997 998 999 1000 1001 1002 | return hash; } - (OFString *)description { /* Classes containing data should reimplement this! */ | | | 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 | return hash; } - (OFString *)description { /* Classes containing data should reimplement this! */ return [OFString stringWithFormat: @"<%@>", self.className]; } - (void *)allocMemoryWithSize: (size_t)size { void *pointer; struct pre_mem *preMem; |
︙ | ︙ |
Modified src/OFOptionsParser.m from [dbad6653d1] to [6af56770b0].
︙ | ︙ | |||
23 24 25 26 27 28 29 | #import "OFMapTable.h" #import "OFInvalidArgumentException.h" static uint32_t stringHash(void *object) { | | | 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | #import "OFMapTable.h" #import "OFInvalidArgumentException.h" static uint32_t stringHash(void *object) { return ((OFString *)object).hash; } static bool stringEqual(void *object1, void *object2) { return [(OFString *)object1 isEqual: (OFString *)object2]; } |
︙ | ︙ | |||
161 162 163 164 165 166 167 | } - (of_unichar_t)nextOption { of_options_parser_option_t *iter; OFString *argument; | | | | 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 | } - (of_unichar_t)nextOption { of_options_parser_option_t *iter; OFString *argument; if (_done || _index >= _arguments.count) return '\0'; [_lastLongOption release]; [_argument release]; _lastLongOption = nil; _argument = nil; argument = [_arguments objectAtIndex: _index]; if (_subIndex == 0) { if (argument.length < 2 || [argument characterAtIndex: 0] != '-') { _done = true; return '\0'; } if ([argument isEqual: @"--"]) { _done = true; |
︙ | ︙ | |||
195 196 197 198 199 200 201 | _lastOption = '-'; _index++; if ((pos = [argument rangeOfString: @"="].location) != OF_NOT_FOUND) { of_range_t range = of_range(pos + 1, | | | | 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 | _lastOption = '-'; _index++; if ((pos = [argument rangeOfString: @"="].location) != OF_NOT_FOUND) { of_range_t range = of_range(pos + 1, argument.length - pos - 1); _argument = [[argument substringWithRange: range] copy]; } else pos = argument.length; _lastLongOption = [[argument substringWithRange: of_range(2, pos - 2)] copy]; objc_autoreleasePoolPop(pool); option = [_longOptions objectForKey: _lastLongOption]; |
︙ | ︙ | |||
232 233 234 235 236 237 238 | } _subIndex = 1; } _lastOption = [argument characterAtIndex: _subIndex++]; | | | | | 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 | } _subIndex = 1; } _lastOption = [argument characterAtIndex: _subIndex++]; if (_subIndex >= argument.length) { _index++; _subIndex = 0; } for (iter = _options; iter->shortOption != '\0' || iter->longOption != nil; iter++) { if (iter->shortOption == _lastOption) { if (iter->hasArgument == 0) { if (iter->isSpecifiedPtr != NULL) *iter->isSpecifiedPtr = true; return _lastOption; } if (_index >= _arguments.count) return ':'; argument = [_arguments objectAtIndex: _index]; argument = [argument substringWithRange: of_range(_subIndex, argument.length - _subIndex)]; _argument = [argument copy]; if (iter->isSpecifiedPtr != NULL) *iter->isSpecifiedPtr = true; if (iter->argumentPtr != NULL) *iter->argumentPtr = |
︙ | ︙ | |||
275 276 277 278 279 280 281 | return '?'; } - (OFArray *)remainingArguments { return [_arguments objectsInRange: | | | 275 276 277 278 279 280 281 282 283 284 | return '?'; } - (OFArray *)remainingArguments { return [_arguments objectsInRange: of_range(_index, _arguments.count - _index)]; } @end |
Modified src/OFPlugin.m from [edc663b796] to [503261dce9].
︙ | ︙ | |||
38 39 40 41 42 43 44 | { #ifndef OF_WINDOWS return dlopen([path cStringWithEncoding: [OFLocale encoding]], flags); #else if (path == nil) return GetModuleHandle(NULL); | | | 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | { #ifndef OF_WINDOWS return dlopen([path cStringWithEncoding: [OFLocale encoding]], flags); #else if (path == nil) return GetModuleHandle(NULL); return LoadLibraryW(path.UTF16String); #endif } void * of_dlsym(of_plugin_handle_t handle, const char *symbol) { #ifndef OF_WINDOWS |
︙ | ︙ | |||
83 84 85 86 87 88 89 | void *pool = objc_autoreleasePoolPush(); of_plugin_handle_t handle; init_plugin_t initPlugin; OFPlugin *plugin; #if defined(OF_MACOS) path = [path stringByAppendingFormat: @".bundle/Contents/MacOS/%@", | | | | 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 | void *pool = objc_autoreleasePoolPush(); of_plugin_handle_t handle; init_plugin_t initPlugin; OFPlugin *plugin; #if defined(OF_MACOS) path = [path stringByAppendingFormat: @".bundle/Contents/MacOS/%@", path.lastPathComponent]; #elif defined(OF_IOS) path = [path stringByAppendingFormat: @".bundle/%@", path.lastPathComponent]; #else path = [path stringByAppendingString: @PLUGIN_SUFFIX]; #endif if ((handle = of_dlopen(path, OF_RTLD_LAZY)) == NULL) @throw [OFLoadPluginFailedException exceptionWithPath: path |
︙ | ︙ |
Modified src/OFProcess.m from [ebfcdb4565] to [c46d227848].
︙ | ︙ | |||
139 140 141 142 143 144 145 | #ifndef OF_WINDOWS void *pool = objc_autoreleasePoolPush(); const char *path; char **argv; if (pipe(_readPipe) != 0 || pipe(_writePipe) != 0) @throw [OFInitializationFailedException | | | | | | | | | 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 | #ifndef OF_WINDOWS void *pool = objc_autoreleasePoolPush(); const char *path; char **argv; if (pipe(_readPipe) != 0 || pipe(_writePipe) != 0) @throw [OFInitializationFailedException exceptionWithClass: self.class]; path = [program cStringWithEncoding: [OFLocale encoding]]; [self of_getArgv: &argv forProgramName: programName andArguments: arguments]; @try { char **env = [self of_environmentForDictionary: environment]; # ifdef HAVE_POSIX_SPAWNP posix_spawn_file_actions_t actions; posix_spawnattr_t attr; if (posix_spawn_file_actions_init(&actions) != 0) @throw [OFInitializationFailedException exceptionWithClass: self.class]; if (posix_spawnattr_init(&attr) != 0) { posix_spawn_file_actions_destroy(&actions); @throw [OFInitializationFailedException exceptionWithClass: self.class]; } @try { if (posix_spawn_file_actions_addclose(&actions, _readPipe[0]) != 0 || posix_spawn_file_actions_addclose(&actions, _writePipe[1]) != 0 || posix_spawn_file_actions_adddup2(&actions, _writePipe[0], 0) != 0 || posix_spawn_file_actions_adddup2(&actions, _readPipe[1], 1) != 0) @throw [OFInitializationFailedException exceptionWithClass: self.class]; # ifdef POSIX_SPAWN_CLOEXEC_DEFAULT if (posix_spawnattr_setflags(&attr, POSIX_SPAWN_CLOEXEC_DEFAULT) != 0) @throw [OFInitializationFailedException exceptionWithClass: self.class]; # endif if (posix_spawnp(&_pid, path, &actions, &attr, argv, env) != 0) @throw [OFInitializationFailedException exceptionWithClass: self.class]; } @finally { posix_spawn_file_actions_destroy(&actions); posix_spawnattr_destroy(&attr); } # else if ((_pid = vfork()) == 0) { environ = env; close(_readPipe[0]); close(_writePipe[1]); dup2(_writePipe[0], 0); dup2(_readPipe[1], 1); execvp(path, argv); _exit(EXIT_FAILURE); } if (_pid == -1) @throw [OFInitializationFailedException exceptionWithClass: self.class]; # endif } @finally { close(_readPipe[1]); close(_writePipe[0]); [self freeMemory: argv]; } |
︙ | ︙ | |||
230 231 232 233 234 235 236 | sa.nLength = sizeof(sa); sa.bInheritHandle = TRUE; sa.lpSecurityDescriptor = NULL; if (!CreatePipe(&_readPipe[0], &_readPipe[1], &sa, 0)) @throw [OFInitializationFailedException | | | | | | 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 | sa.nLength = sizeof(sa); sa.bInheritHandle = TRUE; sa.lpSecurityDescriptor = NULL; if (!CreatePipe(&_readPipe[0], &_readPipe[1], &sa, 0)) @throw [OFInitializationFailedException exceptionWithClass: self.class]; if (!SetHandleInformation(_readPipe[0], HANDLE_FLAG_INHERIT, 0)) @throw [OFInitializationFailedException exceptionWithClass: self.class]; if (!CreatePipe(&_writePipe[0], &_writePipe[1], &sa, 0)) @throw [OFInitializationFailedException exceptionWithClass: self.class]; if (!SetHandleInformation(_writePipe[1], HANDLE_FLAG_INHERIT, 0)) @throw [OFInitializationFailedException exceptionWithClass: self.class]; memset(&pi, 0, sizeof(pi)); memset(&si, 0, sizeof(si)); si.cb = sizeof(si); si.hStdInput = _writePipe[0]; si.hStdOutput = _readPipe[1]; |
︙ | ︙ | |||
289 290 291 292 293 294 295 | [argumentsString appendString: tmp]; if (containsSpaces) [argumentsString appendString: @"\""]; } | | | | | | | 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 | [argumentsString appendString: tmp]; if (containsSpaces) [argumentsString appendString: @"\""]; } length = argumentsString.UTF16StringLength; argumentsCopy = [self allocMemoryWithSize: sizeof(of_char16_t) count: length + 1]; memcpy(argumentsCopy, argumentsString.UTF16String, (argumentsString.UTF16StringLength + 1) * 2); @try { if (!CreateProcessW(program.UTF16String, argumentsCopy, NULL, NULL, TRUE, CREATE_UNICODE_ENVIRONMENT, [self of_environmentForDictionary: environment], NULL, &si, &pi)) @throw [OFInitializationFailedException exceptionWithClass: self.class]; } @finally { [self freeMemory: argumentsCopy]; } objc_autoreleasePoolPop(pool); _process = pi.hProcess; |
︙ | ︙ | |||
334 335 336 337 338 339 340 | } #ifndef OF_WINDOWS - (void)of_getArgv: (char ***)argv forProgramName: (OFString *)programName andArguments: (OFArray *)arguments { | | | | 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 | } #ifndef OF_WINDOWS - (void)of_getArgv: (char ***)argv forProgramName: (OFString *)programName andArguments: (OFArray *)arguments { OFString *const *objects = arguments.objects; size_t i, count = arguments.count; of_string_encoding_t encoding; *argv = [self allocMemoryWithSize: sizeof(char *) count: count + 2]; encoding = [OFLocale encoding]; |
︙ | ︙ | |||
364 365 366 367 368 369 370 | of_string_encoding_t encoding; if (environment == nil) return NULL; encoding = [OFLocale encoding]; | | | 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 | of_string_encoding_t encoding; if (environment == nil) return NULL; encoding = [OFLocale encoding]; count = environment.count; envp = [self allocMemoryWithSize: sizeof(char *) count: count + 1]; keyEnumerator = [environment keyEnumerator]; objectEnumerator = [environment objectEnumerator]; for (i = 0; i < count; i++) { |
︙ | ︙ | |||
413 414 415 416 417 418 419 | env = [OFMutableData dataWithItemSize: sizeof(of_char16_t)]; keyEnumerator = [environment keyEnumerator]; objectEnumerator = [environment objectEnumerator]; while ((key = [keyEnumerator nextObject]) != nil && (object = [objectEnumerator nextObject]) != nil) { | | | | | | | 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 | env = [OFMutableData dataWithItemSize: sizeof(of_char16_t)]; keyEnumerator = [environment keyEnumerator]; objectEnumerator = [environment objectEnumerator]; while ((key = [keyEnumerator nextObject]) != nil && (object = [objectEnumerator nextObject]) != nil) { [env addItems: key.UTF16String count: key.UTF16StringLength]; [env addItems: &equal count: 1]; [env addItems: object.UTF16String count: object.UTF16StringLength]; [env addItems: &zero count: 1]; } [env addItems: zero count: 2]; return env.items; } #endif - (bool)lowlevelIsAtEndOfStream { #ifndef OF_WINDOWS if (_readPipe[0] == -1) |
︙ | ︙ |
Modified src/OFRIPEMD160Hash.m from [089b540858] to [3842b26a7e].
︙ | ︙ | |||
154 155 156 157 158 159 160 | - (instancetype)init { self = [super init]; @try { _iVarsData = [[OFSecureData alloc] initWithCount: sizeof(*_iVars)]; | | | 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 | - (instancetype)init { self = [super init]; @try { _iVarsData = [[OFSecureData alloc] initWithCount: sizeof(*_iVars)]; _iVars = _iVarsData.mutableItems; [self of_resetState]; } @catch (id e) { [self release]; @throw e; } |
︙ | ︙ | |||
182 183 184 185 186 187 188 | } - (id)copy { OFRIPEMD160Hash *copy = [[OFRIPEMD160Hash alloc] of_init]; copy->_iVarsData = [_iVarsData copy]; | | | 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 | } - (id)copy { OFRIPEMD160Hash *copy = [[OFRIPEMD160Hash alloc] of_init]; copy->_iVarsData = [_iVarsData copy]; copy->_iVars = copy->_iVarsData.mutableItems; copy->_calculated = _calculated; return copy; } - (void)of_resetState { |
︙ | ︙ |
Modified src/OFRecursiveMutex.m from [866049a019] to [2beeb530a3].
︙ | ︙ | |||
34 35 36 37 38 39 40 | } - (instancetype)init { self = [super init]; if (!of_rmutex_new(&_rmutex)) { | | | 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 | } - (instancetype)init { self = [super init]; if (!of_rmutex_new(&_rmutex)) { Class c = self.class; [self release]; @throw [OFInitializationFailedException exceptionWithClass: c]; } _initialized = true; return self; |
︙ | ︙ | |||
75 76 77 78 79 80 81 | if (!of_rmutex_unlock(&_rmutex)) @throw [OFUnlockFailedException exceptionWithLock: self]; } - (OFString *)description { if (_name == nil) | | | < | 75 76 77 78 79 80 81 82 83 84 85 86 | if (!of_rmutex_unlock(&_rmutex)) @throw [OFUnlockFailedException exceptionWithLock: self]; } - (OFString *)description { if (_name == nil) return super.description; return [OFString stringWithFormat: @"<%@: %@>", self.className, _name]; } @end |
Modified src/OFRunLoop+Private.h from [3fce6b275d] to [b6012d804d].
︙ | ︙ | |||
24 25 26 27 28 29 30 | OF_ASSUME_NONNULL_BEGIN @class OFRunLoop_State; #ifdef OF_HAVE_SOCKETS @protocol OFTCPSocketDelegate_Private <OFObject> | | | 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | OF_ASSUME_NONNULL_BEGIN @class OFRunLoop_State; #ifdef OF_HAVE_SOCKETS @protocol OFTCPSocketDelegate_Private <OFObject> - (void)of_socketDidConnect: (OFTCPSocket *)socket exception: (nullable id)exception; @end #endif @interface OFRunLoop () + (void)of_setMainRunLoop: (OFRunLoop *)runLoop; #ifdef OF_HAVE_SOCKETS |
︙ | ︙ |
Modified src/OFRunLoop.m from [f76ad8e6f6] to [355a023a1d].
︙ | ︙ | |||
179 180 181 182 183 184 185 | self = [super init]; @try { _timersQueue = [[OFSortedList alloc] init]; #if defined(OF_HAVE_SOCKETS) _kernelEventObserver = [[OFKernelEventObserver alloc] init]; | | | 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 | self = [super init]; @try { _timersQueue = [[OFSortedList alloc] init]; #if defined(OF_HAVE_SOCKETS) _kernelEventObserver = [[OFKernelEventObserver alloc] init]; _kernelEventObserver.delegate = self; _readQueues = [[OFMutableDictionary alloc] init]; _writeQueues = [[OFMutableDictionary alloc] init]; #elif defined(OF_HAVE_THREADS) _condition = [[OFCondition alloc] init]; #endif } @catch (id e) { |
︙ | ︙ | |||
221 222 223 224 225 226 227 | */ OFList OF_GENERIC(OF_KINDOF(OFRunLoop_ReadQueueItem *)) *queue = [[_readQueues objectForKey: object] retain]; assert(queue != nil); @try { | | | | | 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 | */ OFList OF_GENERIC(OF_KINDOF(OFRunLoop_ReadQueueItem *)) *queue = [[_readQueues objectForKey: object] retain]; assert(queue != nil); @try { if (![queue.firstObject handleObject: object]) { of_list_object_t *listObject = queue.firstListObject; /* * The handler might have called -[cancelAsyncRequests] * so that our queue is now empty, in which case we * should do nothing. */ if (listObject != NULL) { /* * Make sure we keep the target until after we * are done removing the object. The reason for * this is that the target might call * -[cancelAsyncRequests] in its dealloc. */ [[listObject->object retain] autorelease]; [queue removeListObject: listObject]; if (queue.count == 0) { [_kernelEventObserver removeObjectForReading: object]; [_readQueues removeObjectForKey: object]; } } } |
︙ | ︙ | |||
264 265 266 267 268 269 270 | * handler called -[cancelAsyncRequests]. */ OFList *queue = [[_writeQueues objectForKey: object] retain]; assert(queue != nil); @try { | | | | | 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 | * handler called -[cancelAsyncRequests]. */ OFList *queue = [[_writeQueues objectForKey: object] retain]; assert(queue != nil); @try { if (![queue.firstObject handleObject: object]) { of_list_object_t *listObject = queue.firstListObject; /* * The handler might have called -[cancelAsyncRequests] * so that our queue is now empty, in which case we * should do nothing. */ if (listObject != NULL) { /* * Make sure we keep the target until after we * are done removing the object. The reason for * this is that the target might call * -[cancelAsyncRequests] in its dealloc. */ [[listObject->object retain] autorelease]; [queue removeListObject: listObject]; if (queue.count == 0) { [_kernelEventObserver removeObjectForWriting: object]; [_writeQueues removeObjectForKey: object]; } } } |
︙ | ︙ | |||
459 460 461 462 463 464 465 | @end @implementation OFRunLoop_WriteDataQueueItem - (bool)handleObject: (id)object { size_t length; id exception = nil; | | | | 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 | @end @implementation OFRunLoop_WriteDataQueueItem - (bool)handleObject: (id)object { size_t length; id exception = nil; size_t dataLength = _data.count * _data.itemSize; OFData *newData, *oldData; @try { const char *dataItems = _data.items; length = [object writeBuffer: dataItems + _writtenLength length: dataLength - _writtenLength]; } @catch (id e) { length = 0; exception = e; } |
︙ | ︙ | |||
716 717 718 719 720 721 722 | @implementation OFRunLoop_UDPSendQueueItem - (bool)handleObject: (id)object { id exception = nil; OFData *newData, *oldData; @try { | | | | 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 | @implementation OFRunLoop_UDPSendQueueItem - (bool)handleObject: (id)object { id exception = nil; OFData *newData, *oldData; @try { [object sendBuffer: _data.items length: _data.count * _data.itemSize receiver: &_receiver]; } @catch (id e) { exception = e; } # ifdef OF_HAVE_BLOCKS if (_block != NULL) { |
︙ | ︙ | |||
782 783 784 785 786 787 788 | { return mainRunLoop; } + (OFRunLoop *)currentRunLoop { #ifdef OF_HAVE_THREADS | | | 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 | { return mainRunLoop; } + (OFRunLoop *)currentRunLoop { #ifdef OF_HAVE_THREADS return [OFThread currentThread].runLoop; #else return [self mainRunLoop]; #endif } + (void)of_setMainRunLoop: (OFRunLoop *)runLoop { |
︙ | ︙ | |||
805 806 807 808 809 810 811 | create: true]; \ OFList *queue = [state->_readQueues objectForKey: object]; \ type *queueItem; \ \ if (queue == nil) { \ queue = [OFList list]; \ [state->_readQueues setObject: queue \ | | | | | 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 | 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]; \ OFRunLoop_State *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]; \ } \ \ if (queue.count == 0) \ [state->_kernelEventObserver \ addObjectForWriting: object]; \ \ queueItem = [[[type alloc] init] autorelease]; #define QUEUE_ITEM \ [queue appendObject: queueItem]; \ \ |
︙ | ︙ | |||
1034 1035 1036 1037 1038 1039 1040 | create: false]; OFList *queue; if (state == nil) return; if ((queue = [state->_writeQueues objectForKey: object]) != nil) { | | | | 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 | create: false]; OFList *queue; if (state == nil) return; if ((queue = [state->_writeQueues objectForKey: object]) != nil) { assert(queue.count > 0); /* * Clear the queue now, in case this has been called from a * handler, as otherwise, we'd do the cleanups below twice. */ [queue removeAllObjects]; [state->_kernelEventObserver removeObjectForWriting: object]; [state->_writeQueues removeObjectForKey: object]; } if ((queue = [state->_readQueues objectForKey: object]) != nil) { assert(queue.count > 0); /* * Clear the queue now, in case this has been called from a * handler, as otherwise, we'd do the cleanups below twice. */ [queue removeAllObjects]; |
︙ | ︙ | |||
1178 1179 1180 1181 1182 1183 1184 | #ifdef OF_HAVE_THREADS [state->_timersQueueMutex lock]; @try { #endif of_list_object_t *iter; | | | 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 | #ifdef OF_HAVE_THREADS [state->_timersQueueMutex lock]; @try { #endif of_list_object_t *iter; for (iter = state->_timersQueue.firstListObject; iter != NULL; iter = iter->next) { if ([iter->object isEqual: timer]) { [state->_timersQueue removeListObject: iter]; break; } } #ifdef OF_HAVE_THREADS |
︙ | ︙ | |||
1202 1203 1204 1205 1206 1207 1208 | } - (void)runUntilDate: (OFDate *)deadline { _stop = false; while (!_stop && | | | 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 | } - (void)runUntilDate: (OFDate *)deadline { _stop = false; while (!_stop && (deadline == nil || deadline.timeIntervalSinceNow >= 0)) [self runMode: of_run_loop_mode_default beforeDate: deadline]; } - (void)runMode: (of_run_loop_mode_t)mode beforeDate: (OFDate *)deadline { |
︙ | ︙ | |||
1230 1231 1232 1233 1234 1235 1236 | OFTimer *timer; #ifdef OF_HAVE_THREADS [state->_timersQueueMutex lock]; @try { #endif of_list_object_t *listObject = | | | | | | 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 | OFTimer *timer; #ifdef OF_HAVE_THREADS [state->_timersQueueMutex lock]; @try { #endif of_list_object_t *listObject = state->_timersQueue.firstListObject; if (listObject != NULL && [listObject->object fireDate].timeIntervalSinceNow <= 0) { timer = [[listObject->object retain] autorelease]; [state->_timersQueue removeListObject: listObject]; [timer of_setInRunLoop: nil mode: nil]; } else break; #ifdef OF_HAVE_THREADS } @finally { [state->_timersQueueMutex unlock]; } #endif if (timer.valid) { [timer fire]; return; } } #ifdef OF_HAVE_THREADS [state->_timersQueueMutex lock]; |
︙ | ︙ | |||
1273 1274 1275 1276 1277 1278 1279 | #endif /* Watch for I/O events until the next timer is due */ if (nextTimer != nil || deadline != nil) { of_time_interval_t timeout; if (nextTimer != nil && deadline == nil) | | | | | | | | 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 | #endif /* Watch for I/O events until the next timer is due */ if (nextTimer != nil || deadline != nil) { of_time_interval_t timeout; if (nextTimer != nil && deadline == nil) timeout = nextTimer.timeIntervalSinceNow; else if (nextTimer == nil && deadline != nil) timeout = deadline.timeIntervalSinceNow; else timeout = [nextTimer earlierDate: deadline] .timeIntervalSinceNow; if (timeout < 0) timeout = 0; #if defined(OF_HAVE_SOCKETS) @try { [state->_kernelEventObserver observeForTimeInterval: timeout]; } @catch (OFObserveFailedException *e) { if (e.errNo != EINTR) @throw e; } #elif defined(OF_HAVE_THREADS) [state->_condition lock]; [state->_condition waitForTimeInterval: timeout]; [state->_condition unlock]; #else [OFThread sleepForTimeInterval: timeout]; #endif } else { /* * No more timers and no deadline: Just watch for I/O * until we get an event. If a timer is added by * another thread, it cancels the observe. */ #if defined(OF_HAVE_SOCKETS) @try { [state->_kernelEventObserver observe]; } @catch (OFObserveFailedException *e) { if (e.errNo != EINTR) @throw e; } #elif defined(OF_HAVE_THREADS) [state->_condition lock]; [state->_condition wait]; [state->_condition unlock]; #else |
︙ | ︙ |
Modified src/OFSHA1Hash.m from [6f8e28171c] to [15c7c9a7a5].
︙ | ︙ | |||
114 115 116 117 118 119 120 | - (instancetype)init { self = [super init]; @try { _iVarsData = [[OFSecureData alloc] initWithCount: sizeof(*_iVars)]; | | | 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 | - (instancetype)init { self = [super init]; @try { _iVarsData = [[OFSecureData alloc] initWithCount: sizeof(*_iVars)]; _iVars = _iVarsData.mutableItems; [self of_resetState]; } @catch (id e) { [self release]; @throw e; } |
︙ | ︙ | |||
142 143 144 145 146 147 148 | } - (id)copy { OFSHA1Hash *copy = [[OFSHA1Hash alloc] of_init]; copy->_iVarsData = [_iVarsData copy]; | | | 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 | } - (id)copy { OFSHA1Hash *copy = [[OFSHA1Hash alloc] of_init]; copy->_iVarsData = [_iVarsData copy]; copy->_iVars = copy->_iVarsData.mutableItems; copy->_calculated = _calculated; return copy; } - (void)of_resetState { |
︙ | ︙ |
Modified src/OFSHA224Or256Hash.m from [86260419b7] to [01186e5528].
︙ | ︙ | |||
136 137 138 139 140 141 142 | - (instancetype)init { self = [super init]; @try { _iVarsData = [[OFSecureData alloc] initWithCount: sizeof(*_iVars)]; | | | | 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 | - (instancetype)init { self = [super init]; @try { _iVarsData = [[OFSecureData alloc] initWithCount: sizeof(*_iVars)]; _iVars = _iVarsData.mutableItems; if (self.class == [OFSHA224Or256Hash class]) { [self doesNotRecognizeSelector: _cmd]; abort(); } [self of_resetState]; } @catch (id e) { [self release]; |
︙ | ︙ | |||
169 170 171 172 173 174 175 | } - (id)copy { OFSHA224Or256Hash *copy = [[[self class] alloc] of_init]; copy->_iVarsData = [_iVarsData copy]; | | | 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 | } - (id)copy { OFSHA224Or256Hash *copy = [[[self class] alloc] of_init]; copy->_iVarsData = [_iVarsData copy]; copy->_iVars = copy->_iVarsData.mutableItems; copy->_calculated = _calculated; return copy; } - (void)updateWithBuffer: (const void *)buffer_ length: (size_t)length |
︙ | ︙ |
Modified src/OFSHA384Or512Hash.m from [9b71b4cd6a] to [af9afb2e15].
︙ | ︙ | |||
147 148 149 150 151 152 153 | - (instancetype)init { self = [super init]; @try { _iVarsData = [[OFSecureData alloc] initWithCount: sizeof(*_iVars)]; | | | | 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 | - (instancetype)init { self = [super init]; @try { _iVarsData = [[OFSecureData alloc] initWithCount: sizeof(*_iVars)]; _iVars = _iVarsData.mutableItems; if (self.class == [OFSHA384Or512Hash class]) { [self doesNotRecognizeSelector: _cmd]; abort(); } [self of_resetState]; } @catch (id e) { [self release]; |
︙ | ︙ | |||
180 181 182 183 184 185 186 | } - (id)copy { OFSHA384Or512Hash *copy = [[[self class] alloc] of_init]; copy->_iVarsData = [_iVarsData copy]; | | | 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 | } - (id)copy { OFSHA384Or512Hash *copy = [[[self class] alloc] of_init]; copy->_iVarsData = [_iVarsData copy]; copy->_iVars = copy->_iVarsData.mutableItems; copy->_calculated = _calculated; return copy; } - (void)updateWithBuffer: (const void *)buffer_ length: (size_t)length |
︙ | ︙ |
Modified src/OFSecureData.h from [6e70789148] to [6b81b595f7].
︙ | ︙ | |||
33 34 35 36 37 38 39 40 41 42 43 44 45 46 | struct page *_page; } #ifdef OF_HAVE_CLASS_PROPERTIES @property (class, readonly, nonatomic, getter=isSecure) bool secure; #endif /*! * @brief Whether OFSecureData is secure, meaning preventing the data from * being swapped out is supported. */ + (bool)isSecure; /*! | > > > > > > > > | 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 | struct page *_page; } #ifdef OF_HAVE_CLASS_PROPERTIES @property (class, readonly, nonatomic, getter=isSecure) bool secure; #endif /*! * @brief All items of the OFSecureData as a C array. * * Modifying the returned array directly is allowed and will change the contents * of the data. */ @property (readonly, nonatomic) void *mutableItems OF_RETURNS_INNER_POINTER; /*! * @brief Whether OFSecureData is secure, meaning preventing the data from * being swapped out is supported. */ + (bool)isSecure; /*! |
︙ | ︙ | |||
101 102 103 104 105 106 107 108 109 110 111 112 113 114 | * @param itemSize The size of a single item in the OFSecureData in bytes * @param count The number of zero items the OFSecureData should contain * @return An initialized OFSecureData */ - (instancetype)initWithItemSize: (size_t)itemSize count: (size_t)count; /*! * @brief Checks the OFSecureData for equality to another object. * * If the specified object is a subclass of @ref OFData, the comparison is * performed in constant time. * * @param object The object which should be tested for equality | > > > > > > > > > > > | 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 | * @param itemSize The size of a single item in the OFSecureData in bytes * @param count The number of zero items the OFSecureData should contain * @return An initialized OFSecureData */ - (instancetype)initWithItemSize: (size_t)itemSize count: (size_t)count; /*! * @brief Returns a specific item of the OFSecureData. * * Modifying the returned item directly is allowed and will change the contents * of the data array. * * @param index The number of the item to return * @return The specified item of the OFSecureData */ - (void *)mutableItemAtIndex: (size_t)index OF_RETURNS_INNER_POINTER; /*! * @brief Checks the OFSecureData for equality to another object. * * If the specified object is a subclass of @ref OFData, the comparison is * performed in constant time. * * @param object The object which should be tested for equality |
︙ | ︙ | |||
134 135 136 137 138 139 140 | - (void)writeToFile: (OFString *)path OF_UNAVAILABLE; #endif - (void)writeToURL: (OFURL *)URL OF_UNAVAILABLE; - (OFXMLElement *)XMLElementBySerializing OF_UNAVAILABLE; - (OFData *)messagePackRepresentation OF_UNAVAILABLE; @end | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | 153 154 155 156 157 158 159 160 | - (void)writeToFile: (OFString *)path OF_UNAVAILABLE; #endif - (void)writeToURL: (OFURL *)URL OF_UNAVAILABLE; - (OFXMLElement *)XMLElementBySerializing OF_UNAVAILABLE; - (OFData *)messagePackRepresentation OF_UNAVAILABLE; @end OF_ASSUME_NONNULL_END |
Modified src/OFSecureData.m from [e8696d3e65] to [e075377cde].
︙ | ︙ | |||
504 505 506 507 508 509 510 511 512 513 514 515 516 517 | freeMemory(_page, _items, _count * _itemSize); removePageIfEmpty(_page); } [super dealloc]; } - (void)zero { of_explicit_memset(_items, 0, _count * _itemSize); } - (id)copy | > > > > > > > > > > > > > | 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 | freeMemory(_page, _items, _count * _itemSize); removePageIfEmpty(_page); } [super dealloc]; } - (void *)mutableItems { return _items; } - (void *)mutableItemAtIndex: (size_t)idx { if (idx >= _count) @throw [OFOutOfRangeException exception]; return _items + idx * _itemSize; } - (void)zero { of_explicit_memset(_items, 0, _count * _itemSize); } - (id)copy |
︙ | ︙ |
Modified src/OFSet.m from [dff1ba0f37] to [136b012e98].
︙ | ︙ | |||
215 216 217 218 219 220 221 | - (id)valueForKey: (OFString *)key { id ret; if ([key hasPrefix: @"@"]) { void *pool = objc_autoreleasePoolPush(); | | | | | 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 | - (id)valueForKey: (OFString *)key { id ret; if ([key hasPrefix: @"@"]) { void *pool = objc_autoreleasePoolPush(); key = [key substringWithRange: of_range(1, key.length - 1)]; ret = [[super valueForKey: key] retain]; objc_autoreleasePoolPop(pool); return [ret autorelease]; } ret = [OFMutableSet setWithCapacity: self.count]; for (id object in self) { id value = [object valueForKey: key]; if (value != nil) [ret addObject: value]; } [ret makeImmutable]; return ret; } - (void)setValue: (id)value forKey: (OFString *)key { if ([key hasPrefix: @"@"]) { void *pool = objc_autoreleasePoolPush(); key = [key substringWithRange: of_range(1, key.length - 1)]; [super setValue: value forKey: key]; objc_autoreleasePoolPop(pool); return; } |
︙ | ︙ | |||
285 286 287 288 289 290 291 | return true; if (![object isKindOfClass: [OFSet class]]) return false; set = object; | | | 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 | return true; if (![object isKindOfClass: [OFSet class]]) return false; set = object; if (set.count != self.count) return false; return [set isSubsetOfSet: self]; } - (uint32_t)hash { |
︙ | ︙ | |||
308 309 310 311 312 313 314 | return hash; } - (OFString *)description { void *pool; OFMutableString *ret; | | | 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 | return hash; } - (OFString *)description { void *pool; OFMutableString *ret; size_t i, count = self.count; if (count == 0) return @"{()}"; ret = [OFMutableString stringWithString: @"{(\n"]; pool = objc_autoreleasePoolPush(); |
︙ | ︙ | |||
382 383 384 385 386 387 388 | else element = [OFXMLElement elementWithName: @"OFSet" namespace: OF_SERIALIZATION_NS]; for (id <OFSerialization> object in self) { void *pool2 = objc_autoreleasePoolPush(); | | | 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 | else element = [OFXMLElement elementWithName: @"OFSet" namespace: OF_SERIALIZATION_NS]; for (id <OFSerialization> object in self) { void *pool2 = objc_autoreleasePoolPush(); [element addChild: object.XMLElementBySerializing]; objc_autoreleasePoolPop(pool2); } [element retain]; objc_autoreleasePoolPop(pool); |
︙ | ︙ |
Modified src/OFSet_hashtable.m from [bc1b122bdb] to [58bc1233e4].
︙ | ︙ | |||
88 89 90 91 92 93 94 | { size_t count; if (set == nil) return [self init]; @try { | | | 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 | { size_t count; if (set == nil) return [self init]; @try { count = set.count; } @catch (id e) { [self release]; @throw e; } self = [self initWithCapacity: count]; |
︙ | ︙ | |||
116 117 118 119 120 121 122 | { size_t count; if (array == nil) return self; @try { | | | 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 | { size_t count; if (array == nil) return self; @try { count = array.count; } @catch (id e) { [self release]; @throw e; } self = [self initWithCapacity: count]; |
︙ | ︙ | |||
193 194 195 196 197 198 199 | - (instancetype)initWithSerialization: (OFXMLElement *)element { self = [self init]; @try { void *pool = objc_autoreleasePoolPush(); | | | | | 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 | - (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 |
︙ | ︙ |
Modified src/OFSettings_INIFile.m from [3e8385c835] to [4d0ca9211c].
︙ | ︙ | |||
65 66 67 68 69 70 71 | *category = @""; *key = path; return; } *category = [path substringWithRange: of_range(0, pos)]; *key = [path substringWithRange: | | | 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 | *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; |
︙ | ︙ |
Modified src/OFStdIOStream.m from [0fdbb22bb2] to [416043c557].
︙ | ︙ | |||
95 96 97 98 99 100 101 | OFDate *date; OFString *dateString, *me, *msg; va_list arguments; date = [OFDate date]; dateString = [date localDateStringWithFormat: @"%Y-%m-%d %H:%M:%S"]; #ifdef OF_HAVE_FILES | | | | 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 | OFDate *date; OFString *dateString, *me, *msg; va_list arguments; date = [OFDate date]; dateString = [date localDateStringWithFormat: @"%Y-%m-%d %H:%M:%S"]; #ifdef OF_HAVE_FILES me = [OFApplication programName].lastPathComponent; #else me = [OFApplication programName]; #endif va_start(arguments, format); msg = [[[OFString alloc] initWithFormat: format arguments: arguments] autorelease]; va_end(arguments); [of_stderr writeFormat: @"[%@.%03d %@(%d)] %@\n", dateString, date.microsecond / 1000, me, getpid(), msg]; objc_autoreleasePoolPop(pool); } @implementation OFStdIOStream #ifndef OF_WINDOWS + (void)load |
︙ | ︙ |
Modified src/OFStdIOStream_Win32Console.m from [8796f50f42] to [801fb56bc9].
︙ | ︙ | |||
164 165 166 167 168 169 170 | if ((c & 0xFC00) == 0xD800) { of_char16_t next; if (UTF16Len <= i + 1) { _incompleteUTF16Surrogate = c; if (rest != nil) { | | | | 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 | if ((c & 0xFC00) == 0xD800) { of_char16_t next; if (UTF16Len <= i + 1) { _incompleteUTF16Surrogate = c; if (rest != nil) { char *items = rest.items; size_t count = rest.count; [self unreadFromBuffer: items length: count]; } objc_autoreleasePoolPop(pool); |
︙ | ︙ | |||
204 205 206 207 208 209 210 | [rest addItems: UTF8 count: UTF8Len]; } } if (rest != nil) | | | | 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 | [rest addItems: UTF8 count: UTF8Len]; } } if (rest != nil) [self unreadFromBuffer: rest.items length: rest.count]; } @finally { [self freeMemory: UTF16]; } objc_autoreleasePoolPop(pool); return j; |
︙ | ︙ |
Modified src/OFStream.h from [ea84bca9b5] to [437fb045ff].
︙ | ︙ | |||
46 47 48 49 50 51 52 | * @param stream The stream on which data was read * @param buffer A buffer with the data that has been read * @param length The length of the data that has been read * @param exception An exception which occurred while reading or `nil` on * success * @return A bool whether the same block should be used for the next read */ | | < | | < | | | | | | | | 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 | * @param stream The stream on which data was read * @param buffer A buffer with the data that has been read * @param length The length of the data that has been read * @param exception An exception which occurred while reading or `nil` on * success * @return A bool whether the same block should be used for the next read */ typedef bool (^of_stream_async_read_block_t)(OFStream *_Nonnull stream, void *_Nonnull buffer, size_t length, id _Nullable exception); /*! * @brief A block which is called when a line was read asynchronously from a * stream. * * @param stream The stream on which a line was read * @param line The line which has been read or `nil` when the end of stream * occurred * @param exception An exception which occurred while reading or `nil` on * success * @return A bool whether the same block should be used for the next read */ typedef bool (^of_stream_async_read_line_block_t)(OFStream *_Nonnull stream, OFString *_Nullable line, id _Nullable exception); /*! * @brief A block which is called when data was written asynchronously to a * stream. * * @param data The data which was written to the stream * @param bytesWritten The number of bytes which have been written. This * matches the length of the specified data on the * asynchronous write if no exception was encountered. * @param exception An exception which occurred while writing or `nil` on * success * @return The data to repeat the write with or nil if it should not repeat */ typedef OFData *_Nullable (^of_stream_async_write_data_block_t)( OFStream *_Nonnull stream, OFData *_Nonnull data, size_t bytesWritten, id _Nullable exception); /*! * @brief A block which is called when a string was written asynchronously to a * stream. * * @param string The string which was written to the stream * @param bytesWritten The number of bytes which have been written. This * matches the length of the specified data on the * asynchronous write if no exception was encountered. * @param encoding The encoding in which the string was written * @param exception An exception which occurred while writing or `nil` on * success * @return The string to repeat the write with or nil if it should not repeat */ typedef OFString *_Nullable (^of_stream_async_write_string_block_t)( OFStream *_Nonnull stream, OFString *_Nonnull string, of_string_encoding_t encoding, size_t bytesWritten, id _Nullable exception); #endif /*! * @protocol OFStreamDelegate OFStream.h ObjFW/OFStream.h * * A delegate for OFStream. */ @protocol OFStreamDelegate <OFObject> @optional /*! * @brief This method is called when data was read asynchronously from a * stream. * * @param stream The stream on which data was read * @param buffer A buffer with the data that has been read * @param length The length of the data that has been read * @param exception An exception that occurred while reading, or nil on success * @return A bool whether the read should be repeated */ - (bool)stream: (OFStream *)stream didReadIntoBuffer: (void *)buffer length: (size_t)length exception: (nullable id)exception; /*! * @brief This method is called when a line was read asynchronously from a * stream. * * @param stream The stream on which a line was read * @param line The line which has been read or `nil` when the end of stream * occurred * @param exception An exception that occurred while reading, or nil on success * @return A bool whether the read should be repeated */ - (bool)stream: (OFStream *)stream didReadLine: (nullable OFString *)line exception: (nullable id)exception; /*! * @brief This method is called when data was written asynchronously to a * stream. * * @param stream The stream to which data was written * @param data The data which was written to the stream * @param bytesWritten The number of bytes which have been written. This * matches the length of the specified data on the * asynchronous write if no exception was encountered. * @param exception An exception that occurred while writing, or nil on success * @return The data to repeat the write with or nil if it should not repeat */ - (nullable OFData *)stream: (OFStream *)stream didWriteData: (OFData *)data bytesWritten: (size_t)bytesWritten exception: (nullable id)exception; /*! * @brief This method is called when a string was written asynchronously to a * stream. * * @param stream The stream to which a string was written * @param string The string which was written to the stream * @param encoding The encoding in which the string was written * @param bytesWritten The number of bytes which have been written. This * matches the length of the specified data on the * asynchronous write if no exception was encountered. * @param exception An exception that occurred while writing, or nil on success * @return The string to repeat the write with or nil if it should not repeat */ - (nullable OFString *)stream: (OFStream *)stream didWriteString: (OFString *)string encoding: (of_string_encoding_t)encoding bytesWritten: (size_t)bytesWritten exception: (nullable id)exception; @end /*! |
︙ | ︙ |
Modified src/OFStream.m from [3a06b598ab] to [9042aa5323].
︙ | ︙ | |||
182 183 184 185 186 187 188 | - (void)readIntoBuffer: (void *)buffer exactLength: (size_t)length { size_t readLength = 0; while (readLength < length) { | | | 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 | - (void)readIntoBuffer: (void *)buffer exactLength: (size_t)length { size_t readLength = 0; while (readLength < length) { if (self.atEndOfStream) @throw [OFTruncatedDataException exception]; readLength += [self readIntoBuffer: (char *)buffer + readLength length: length - readLength]; } } |
︙ | ︙ | |||
658 659 660 661 662 663 664 | - (OFData *)readDataUntilEndOfStream { OFMutableData *data = [OFMutableData data]; size_t pageSize = [OFSystemInfo pageSize]; char *buffer = [self allocMemoryWithSize: pageSize]; @try { | | | 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 | - (OFData *)readDataUntilEndOfStream { OFMutableData *data = [OFMutableData data]; size_t pageSize = [OFSystemInfo pageSize]; char *buffer = [self allocMemoryWithSize: pageSize]; @try { while (!self.atEndOfStream) { size_t length; length = [self readIntoBuffer: buffer length: pageSize]; [data addItems: buffer count: length]; } |
︙ | ︙ | |||
863 864 865 866 867 868 869 | } - (OFString *)readLineWithEncoding: (of_string_encoding_t)encoding { OFString *line = nil; while ((line = [self tryReadLineWithEncoding: encoding]) == nil) | | | 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 | } - (OFString *)readLineWithEncoding: (of_string_encoding_t)encoding { OFString *line = nil; while ((line = [self tryReadLineWithEncoding: encoding]) == nil) if (self.atEndOfStream) return nil; return line; } #ifdef OF_HAVE_SOCKETS - (void)asyncReadLine |
︙ | ︙ | |||
1110 1111 1112 1113 1114 1115 1116 | } - (OFString *)readTillDelimiter: (OFString *)delimiter encoding: (of_string_encoding_t)encoding { OFString *ret = nil; | < | | 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 | } - (OFString *)readTillDelimiter: (OFString *)delimiter encoding: (of_string_encoding_t)encoding { OFString *ret = nil; while ((ret = [self tryReadTillDelimiter: delimiter encoding: encoding]) == nil) if (self.atEndOfStream) return nil; return ret; } - (OFString *)tryReadTillDelimiter: (OFString *)delimiter { |
︙ | ︙ | |||
1692 1693 1694 1695 1696 1697 1698 | void *pool; size_t length; if (data == nil) @throw [OFInvalidArgumentException exception]; pool = objc_autoreleasePoolPush(); | | | | 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 | void *pool; size_t length; if (data == nil) @throw [OFInvalidArgumentException exception]; pool = objc_autoreleasePoolPush(); length = data.count * data.itemSize; [self writeBuffer: data.items length: length]; objc_autoreleasePoolPop(pool); return length; } |
︙ | ︙ | |||
1778 1779 1780 1781 1782 1783 1784 | { char *UTF8String; int length; if (format == nil) @throw [OFInvalidArgumentException exception]; | | | 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 | { char *UTF8String; int length; if (format == nil) @throw [OFInvalidArgumentException exception]; if ((length = of_vasprintf(&UTF8String, format.UTF8String, arguments)) == -1) @throw [OFInvalidFormatException exception]; @try { [self writeBuffer: UTF8String length: length]; } @finally { |
︙ | ︙ | |||
1810 1811 1812 1813 1814 1815 1816 | { #if defined(HAVE_FCNTL) bool readImplemented = false, writeImplemented = false; @try { int readFlags; | | | | | | | | | | 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 | { #if defined(HAVE_FCNTL) bool readImplemented = false, writeImplemented = false; @try { int readFlags; readFlags = fcntl(((id <OFReadyForReadingObserving>)self) .fileDescriptorForReading, F_GETFL, 0); readImplemented = true; if (readFlags == -1) @throw [OFSetOptionFailedException exceptionWithObject: self errNo: errno]; if (enable) readFlags &= ~O_NONBLOCK; else readFlags |= O_NONBLOCK; if (fcntl(((id <OFReadyForReadingObserving>)self) .fileDescriptorForReading, F_SETFL, readFlags) == -1) @throw [OFSetOptionFailedException exceptionWithObject: self errNo: errno]; } @catch (OFNotImplementedException *e) { } @try { int writeFlags; writeFlags = fcntl(((id <OFReadyForWritingObserving>)self) .fileDescriptorForWriting, F_GETFL, 0); writeImplemented = true; if (writeFlags == -1) @throw [OFSetOptionFailedException exceptionWithObject: self errNo: errno]; if (enable) writeFlags &= ~O_NONBLOCK; else writeFlags |= O_NONBLOCK; if (fcntl(((id <OFReadyForWritingObserving>)self) .fileDescriptorForWriting, F_SETFL, writeFlags) == -1) @throw [OFSetOptionFailedException exceptionWithObject: self errNo: errno]; } @catch (OFNotImplementedException *e) { } if (!readImplemented && !writeImplemented) |
︙ | ︙ |
Modified src/OFString+CryptoHashing.m from [cd0a1a49d0] to [d7c7a2d4d1].
︙ | ︙ | |||
34 35 36 37 38 39 40 | { void *pool = objc_autoreleasePoolPush(); id <OFCryptoHash> hash = [class cryptoHash]; size_t digestSize = [class digestSize]; const unsigned char *digest; char cString[digestSize * 2]; | | | | | 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 | { void *pool = objc_autoreleasePoolPush(); id <OFCryptoHash> hash = [class cryptoHash]; size_t digestSize = [class digestSize]; const unsigned char *digest; char cString[digestSize * 2]; [hash updateWithBuffer: self.UTF8String length: self.UTF8StringLength]; digest = hash.digest; for (size_t i = 0; i < digestSize; i++) { uint8_t high, low; high = digest[i] >> 4; low = digest[i] & 0x0F; |
︙ | ︙ |
Modified src/OFString+JSONValue.m from [487fb8caf6] to [8c09849227].
︙ | ︙ | |||
552 553 554 555 556 557 558 | string = [[OFString alloc] initWithUTF8String: *pointer length: i]; *pointer += i; @try { if (hasDecimal) number = [OFNumber numberWithDouble: | | | | | 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 | string = [[OFString alloc] initWithUTF8String: *pointer length: i]; *pointer += i; @try { if (hasDecimal) number = [OFNumber numberWithDouble: string.doubleValue]; else if (isHex) number = [OFNumber numberWithIntMax: string.hexadecimalValue]; else if ([string isEqual: @"Infinity"]) number = [OFNumber numberWithDouble: INFINITY]; else if ([string isEqual: @"-Infinity"]) number = [OFNumber numberWithDouble: -INFINITY]; else number = [OFNumber numberWithIntMax: string.decimalValue]; } @finally { [string release]; } return number; } |
︙ | ︙ | |||
646 647 648 649 650 651 652 | { return [self JSONValueWithDepthLimit: 32]; } - (id)JSONValueWithDepthLimit: (size_t)depthLimit { void *pool = objc_autoreleasePoolPush(); | | | | 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 | { return [self JSONValueWithDepthLimit: 32]; } - (id)JSONValueWithDepthLimit: (size_t)depthLimit { void *pool = objc_autoreleasePoolPush(); const char *pointer = self.UTF8String; const char *stop = pointer + self.UTF8StringLength; id object; size_t line = 1; #ifdef __clang_analyzer__ assert(pointer != NULL); #endif |
︙ | ︙ |
Modified src/OFString+PathAdditions_AmigaOS.m from [a9beed535a] to [c3941b3928].
︙ | ︙ | |||
28 29 30 31 32 33 34 | + (OFString *)pathWithComponents: (OFArray *)components { OFMutableString *ret = [OFMutableString string]; void *pool = objc_autoreleasePoolPush(); bool firstAfterDevice = true; for (OFString *component in components) { | | | 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | + (OFString *)pathWithComponents: (OFArray *)components { OFMutableString *ret = [OFMutableString string]; void *pool = objc_autoreleasePoolPush(); bool firstAfterDevice = true; for (OFString *component in components) { if (component.length == 0) continue; if (!firstAfterDevice) [ret appendString: @"/"]; [ret appendString: component]; |
︙ | ︙ | |||
56 57 58 59 60 61 62 | return [self containsString: @":"]; } - (OFArray *)pathComponents { OFMutableArray OF_GENERIC(OFString *) *ret = [OFMutableArray array]; void *pool = objc_autoreleasePoolPush(); | | | | 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 | return [self containsString: @":"]; } - (OFArray *)pathComponents { OFMutableArray OF_GENERIC(OFString *) *ret = [OFMutableArray array]; void *pool = objc_autoreleasePoolPush(); const char *cString = self.UTF8String; size_t i, last = 0, cStringLength = self.UTF8StringLength; if (cStringLength == 0) { objc_autoreleasePoolPop(pool); return ret; } for (i = 0; i < cStringLength; i++) { |
︙ | ︙ | |||
101 102 103 104 105 106 107 | { /* * AmigaOS needs the full parsing to determine the last path component. * This could be optimized by not creating the temporary objects, * though. */ void *pool = objc_autoreleasePoolPush(); | | | | | | | | | | | | | | | | | | | 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 | { /* * AmigaOS needs the full parsing to determine the last path component. * This could be optimized by not creating the temporary objects, * though. */ void *pool = objc_autoreleasePoolPush(); OFString *ret = self.pathComponents.lastObject; [ret retain]; objc_autoreleasePoolPop(pool); return [ret autorelease]; } - (OFString *)pathExtension { void *pool = objc_autoreleasePoolPush(); OFString *ret, *fileName; size_t pos; fileName = self.lastPathComponent; pos = [fileName rangeOfString: @"." options: OF_STRING_SEARCH_BACKWARDS].location; if (pos == OF_NOT_FOUND || pos == 0) { objc_autoreleasePoolPop(pool); return @""; } ret = [fileName substringWithRange: of_range(pos + 1, fileName.length - pos - 1)]; [ret retain]; objc_autoreleasePoolPop(pool); return [ret autorelease]; } - (OFString *)stringByDeletingLastPathComponent { /* * AmigaOS needs the full parsing to delete the last path component. * This could be optimized, though. */ void *pool = objc_autoreleasePoolPush(); OFArray OF_GENERIC(OFString *) *components = self.pathComponents; size_t count = components.count; OFString *ret; if (count < 2) { if ([components.firstObject hasSuffix: @":"]) { ret = [components.firstObject retain]; objc_autoreleasePoolPop(pool); return [ret autorelease]; } objc_autoreleasePoolPop(pool); return @""; } components = [components objectsInRange: of_range(0, components.count - 1)]; ret = [OFString pathWithComponents: components]; [ret retain]; objc_autoreleasePoolPop(pool); return [ret autorelease]; } - (OFString *)stringByDeletingPathExtension { void *pool; OFMutableArray OF_GENERIC(OFString *) *components; OFString *ret, *fileName; size_t pos; if (self.length == 0) return [[self copy] autorelease]; pool = objc_autoreleasePoolPush(); components = [[self.pathComponents mutableCopy] autorelease]; fileName = components.lastObject; pos = [fileName rangeOfString: @"." options: OF_STRING_SEARCH_BACKWARDS].location; if (pos == OF_NOT_FOUND || pos == 0) { objc_autoreleasePoolPop(pool); return [[self copy] autorelease]; } fileName = [fileName substringWithRange: of_range(0, pos)]; [components replaceObjectAtIndex: components.count - 1 withObject: fileName]; ret = [OFString pathWithComponents: components]; [ret retain]; objc_autoreleasePoolPop(pool); return [ret autorelease]; } - (OFString *)stringByStandardizingPath { void *pool = objc_autoreleasePoolPush(); OFArray OF_GENERIC(OFString *) *components; OFMutableArray OF_GENERIC(OFString *) *array; OFString *ret; bool done = false; if (self.length == 0) return @""; components = self.pathComponents; if (components.count == 1) { objc_autoreleasePoolPop(pool); return [[self copy] autorelease]; } array = [[components mutableCopy] autorelease]; while (!done) { size_t length = array.count; done = true; for (size_t i = 0; i < length; i++) { OFString *component = [array objectAtIndex: i]; OFString *parent = (i > 0 ? [array objectAtIndex: i - 1] : 0); if (component.length == 0) { [array removeObjectAtIndex: i]; done = false; break; } if ([component isEqual: @"/"] && |
︙ | ︙ |
Modified src/OFString+PathAdditions_DOS.m from [3467d9c05a] to [b920b866ec].
︙ | ︙ | |||
28 29 30 31 32 33 34 | + (OFString *)pathWithComponents: (OFArray *)components { OFMutableString *ret = [OFMutableString string]; void *pool = objc_autoreleasePoolPush(); bool first = true; for (OFString *component in components) { | | | 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | + (OFString *)pathWithComponents: (OFArray *)components { OFMutableString *ret = [OFMutableString string]; void *pool = objc_autoreleasePoolPush(); bool first = true; for (OFString *component in components) { if (component.length == 0) continue; if ([component isEqual: @"\\"] || [component isEqual: @"/"]) continue; if (!first && ![ret hasSuffix: @"\\"] && ![ret hasSuffix: @"/"]) [ret appendString: @"\\"]; |
︙ | ︙ | |||
61 62 63 64 65 66 67 | return ([self containsString: @":\\"] || [self containsString: @":/"]); } - (OFArray *)pathComponents { OFMutableArray OF_GENERIC(OFString *) *ret = [OFMutableArray array]; void *pool = objc_autoreleasePoolPush(); | | | | 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 | return ([self containsString: @":\\"] || [self containsString: @":/"]); } - (OFArray *)pathComponents { OFMutableArray OF_GENERIC(OFString *) *ret = [OFMutableArray array]; void *pool = objc_autoreleasePoolPush(); const char *cString = self.UTF8String; size_t i, last = 0, cStringLength = self.UTF8StringLength; if (cStringLength == 0) { objc_autoreleasePoolPop(pool); return ret; } for (i = 0; i < cStringLength; i++) { |
︙ | ︙ | |||
101 102 103 104 105 106 107 | size_t cStringLength; ssize_t i; OFString *ret; if ([self hasSuffix: @":\\"] || [self hasSuffix: @":/"]) return self; | | | | 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 | size_t cStringLength; ssize_t i; OFString *ret; if ([self hasSuffix: @":\\"] || [self hasSuffix: @":/"]) return self; cString = self.UTF8String; cStringLength = self.UTF8StringLength; if (cStringLength == 0) { objc_autoreleasePoolPop(pool); return @""; } if (cString[cStringLength - 1] == '\\' || |
︙ | ︙ | |||
149 150 151 152 153 154 155 | - (OFString *)pathExtension { void *pool = objc_autoreleasePoolPush(); OFString *ret, *fileName; size_t pos; | | | | | | 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 | - (OFString *)pathExtension { void *pool = objc_autoreleasePoolPush(); OFString *ret, *fileName; size_t pos; fileName = self.lastPathComponent; pos = [fileName rangeOfString: @"." options: OF_STRING_SEARCH_BACKWARDS].location; if (pos == OF_NOT_FOUND || pos == 0) { objc_autoreleasePoolPop(pool); return @""; } ret = [fileName substringWithRange: of_range(pos + 1, fileName.length - pos - 1)]; [ret retain]; objc_autoreleasePoolPop(pool); return [ret autorelease]; } - (OFString *)stringByDeletingLastPathComponent { void *pool = objc_autoreleasePoolPush(); const char *cString; size_t cStringLength; OFString *ret; if ([self hasSuffix: @":\\"] || [self hasSuffix: @":/"]) return self; cString = self.UTF8String; cStringLength = self.UTF8StringLength; if (cStringLength == 0) { objc_autoreleasePoolPop(pool); return @""; } if (cString[cStringLength - 1] == '\\' || |
︙ | ︙ | |||
215 216 217 218 219 220 221 | - (OFString *)stringByDeletingPathExtension { void *pool; OFMutableArray OF_GENERIC(OFString *) *components; OFString *ret, *fileName; size_t pos; | | | | | | | | | | | 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 | - (OFString *)stringByDeletingPathExtension { void *pool; OFMutableArray OF_GENERIC(OFString *) *components; OFString *ret, *fileName; size_t pos; if (self.length == 0) return [[self copy] autorelease]; pool = objc_autoreleasePoolPush(); components = [[self.pathComponents mutableCopy] autorelease]; fileName = components.lastObject; pos = [fileName rangeOfString: @"." options: OF_STRING_SEARCH_BACKWARDS].location; if (pos == OF_NOT_FOUND || pos == 0) { objc_autoreleasePoolPop(pool); return [[self copy] autorelease]; } fileName = [fileName substringWithRange: of_range(0, pos)]; [components replaceObjectAtIndex: components.count - 1 withObject: fileName]; ret = [OFString pathWithComponents: components]; [ret retain]; objc_autoreleasePoolPop(pool); return [ret autorelease]; } - (OFString *)stringByStandardizingPath { void *pool = objc_autoreleasePoolPush(); OFArray OF_GENERIC(OFString *) *components; OFMutableArray OF_GENERIC(OFString *) *array; OFString *ret; bool done = false; if (self.length == 0) return @""; components = self.pathComponents; if (components.count == 1) { objc_autoreleasePoolPop(pool); return [[self copy] autorelease]; } array = [[components mutableCopy] autorelease]; while (!done) { size_t length = array.count; done = true; for (size_t i = 0; i < length; i++) { OFString *component = [array objectAtIndex: i]; OFString *parent = (i > 0 ? [array objectAtIndex: i - 1] : 0); if ([component isEqual: @"."] || component.length == 0) { [array removeObjectAtIndex: i]; done = false; break; } if ([component isEqual: @".."] && |
︙ | ︙ |
Modified src/OFString+PathAdditions_UNIX.m from [e75f2cd214] to [f40ca2e186].
︙ | ︙ | |||
28 29 30 31 32 33 34 | + (OFString *)pathWithComponents: (OFArray *)components { OFMutableString *ret = [OFMutableString string]; void *pool = objc_autoreleasePoolPush(); bool first = true; for (OFString *component in components) { | | | 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | + (OFString *)pathWithComponents: (OFArray *)components { OFMutableString *ret = [OFMutableString string]; void *pool = objc_autoreleasePoolPush(); bool first = true; for (OFString *component in components) { if (component.length == 0) continue; if (!first && [component isEqual: @"/"]) continue; if (!first && ![ret hasSuffix: @"/"]) [ret appendString: @"/"]; |
︙ | ︙ | |||
58 59 60 61 62 63 64 | return [self hasPrefix: @"/"]; } - (OFArray *)pathComponents { OFMutableArray OF_GENERIC(OFString *) *ret = [OFMutableArray array]; void *pool = objc_autoreleasePoolPush(); | | | | 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 | return [self hasPrefix: @"/"]; } - (OFArray *)pathComponents { OFMutableArray OF_GENERIC(OFString *) *ret = [OFMutableArray array]; void *pool = objc_autoreleasePoolPush(); const char *cString = self.UTF8String; size_t i, last = 0, cStringLength = self.UTF8StringLength; if (cStringLength == 0) { objc_autoreleasePoolPop(pool); return ret; } for (i = 0; i < cStringLength; i++) { |
︙ | ︙ | |||
92 93 94 95 96 97 98 | return ret; } - (OFString *)lastPathComponent { void *pool = objc_autoreleasePoolPush(); | | | | 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 | return ret; } - (OFString *)lastPathComponent { void *pool = objc_autoreleasePoolPush(); const char *cString = self.UTF8String; size_t cStringLength = self.UTF8StringLength; ssize_t i; OFString *ret; if (cStringLength == 0) { objc_autoreleasePoolPop(pool); return @""; } |
︙ | ︙ | |||
141 142 143 144 145 146 147 | - (OFString *)pathExtension { void *pool = objc_autoreleasePoolPush(); OFString *ret, *fileName; size_t pos; | | | | | | 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 | - (OFString *)pathExtension { void *pool = objc_autoreleasePoolPush(); OFString *ret, *fileName; size_t pos; fileName = self.lastPathComponent; pos = [fileName rangeOfString: @"." options: OF_STRING_SEARCH_BACKWARDS].location; if (pos == OF_NOT_FOUND || pos == 0) { objc_autoreleasePoolPop(pool); return @""; } ret = [fileName substringWithRange: of_range(pos + 1, fileName.length - pos - 1)]; [ret retain]; objc_autoreleasePoolPop(pool); return [ret autorelease]; } - (OFString *)stringByDeletingLastPathComponent { void *pool = objc_autoreleasePoolPush(); const char *cString = self.UTF8String; size_t cStringLength = self.UTF8StringLength; OFString *ret; if (cStringLength == 0) { objc_autoreleasePoolPop(pool); return @""; } |
︙ | ︙ | |||
205 206 207 208 209 210 211 | - (OFString *)stringByDeletingPathExtension { void *pool; OFMutableArray OF_GENERIC(OFString *) *components; OFString *ret, *fileName; size_t pos; | | | | | 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 | - (OFString *)stringByDeletingPathExtension { void *pool; OFMutableArray OF_GENERIC(OFString *) *components; OFString *ret, *fileName; size_t pos; if (self.length == 0) return [[self copy] autorelease]; pool = objc_autoreleasePoolPush(); components = [[self.pathComponents mutableCopy] autorelease]; fileName = components.lastObject; pos = [fileName rangeOfString: @"." options: OF_STRING_SEARCH_BACKWARDS].location; if (pos == OF_NOT_FOUND || pos == 0) { objc_autoreleasePoolPop(pool); return [[self copy] autorelease]; } |
︙ | ︙ | |||
238 239 240 241 242 243 244 | { void *pool = objc_autoreleasePoolPush(); OFArray OF_GENERIC(OFString *) *components; OFMutableArray OF_GENERIC(OFString *) *array; OFString *ret; bool done = false, startsWithSlash; | | | | | | | 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 | { void *pool = objc_autoreleasePoolPush(); OFArray OF_GENERIC(OFString *) *components; OFMutableArray OF_GENERIC(OFString *) *array; OFString *ret; bool done = false, startsWithSlash; if (self.length == 0) return @""; components = self.pathComponents; if (components.count == 1) { objc_autoreleasePoolPop(pool); return [[self copy] autorelease]; } array = [[components mutableCopy] autorelease]; startsWithSlash = [self hasPrefix: @"/"]; if (startsWithSlash) [array removeObjectAtIndex: 0]; while (!done) { size_t length = array.count; done = true; for (size_t i = 0; i < length; i++) { OFString *component = [array objectAtIndex: i]; OFString *parent = (i > 0 ? [array objectAtIndex: i - 1] : 0); if ([component isEqual: @"."] || component.length == 0) { [array removeObjectAtIndex: i]; done = false; break; } if ([component isEqual: @".."] && |
︙ | ︙ |
Modified src/OFString+PathAdditions_libfat.m from [7ddc0d03b5] to [d93f3d266a].
︙ | ︙ | |||
28 29 30 31 32 33 34 | + (OFString *)pathWithComponents: (OFArray *)components { OFMutableString *ret = [OFMutableString string]; void *pool = objc_autoreleasePoolPush(); bool first = true; for (OFString *component in components) { | | | 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | + (OFString *)pathWithComponents: (OFArray *)components { OFMutableString *ret = [OFMutableString string]; void *pool = objc_autoreleasePoolPush(); bool first = true; for (OFString *component in components) { if (component.length == 0) continue; if ([component isEqual: @"/"]) continue; if (!first && ![ret hasSuffix: @"/"]) [ret appendString: @"/"]; |
︙ | ︙ | |||
61 62 63 64 65 66 67 | return [self containsString: @":/"]; } - (OFArray *)pathComponents { OFMutableArray OF_GENERIC(OFString *) *ret = [OFMutableArray array]; void *pool = objc_autoreleasePoolPush(); | | | | 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 | return [self containsString: @":/"]; } - (OFArray *)pathComponents { OFMutableArray OF_GENERIC(OFString *) *ret = [OFMutableArray array]; void *pool = objc_autoreleasePoolPush(); const char *cString = self.UTF8String; size_t i, last = 0, cStringLength = self.UTF8StringLength; if (cStringLength == 0) { objc_autoreleasePoolPop(pool); return ret; } for (i = 0; i < cStringLength; i++) { |
︙ | ︙ | |||
101 102 103 104 105 106 107 | size_t cStringLength; ssize_t i; OFString *ret; if ([self hasSuffix: @":/"]) return self; | | | | 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 | size_t cStringLength; ssize_t i; OFString *ret; if ([self hasSuffix: @":/"]) return self; cString = self.UTF8String; cStringLength = self.UTF8StringLength; if (cStringLength == 0) { objc_autoreleasePoolPop(pool); return @""; } if (cString[cStringLength - 1] == '/') |
︙ | ︙ | |||
148 149 150 151 152 153 154 | - (OFString *)pathExtension { void *pool = objc_autoreleasePoolPush(); OFString *ret, *fileName; size_t pos; | | | | | | 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 | - (OFString *)pathExtension { void *pool = objc_autoreleasePoolPush(); OFString *ret, *fileName; size_t pos; fileName = self.lastPathComponent; pos = [fileName rangeOfString: @"." options: OF_STRING_SEARCH_BACKWARDS].location; if (pos == OF_NOT_FOUND || pos == 0) { objc_autoreleasePoolPop(pool); return @""; } ret = [fileName substringWithRange: of_range(pos + 1, fileName.length - pos - 1)]; [ret retain]; objc_autoreleasePoolPop(pool); return [ret autorelease]; } - (OFString *)stringByDeletingLastPathComponent { void *pool = objc_autoreleasePoolPush(); const char *cString; size_t cStringLength; OFString *ret; if ([self hasSuffix: @":/"]) return self; cString = self.UTF8String; cStringLength = self.UTF8StringLength; if (cStringLength == 0) { objc_autoreleasePoolPop(pool); return @""; } if (cString[cStringLength - 1] == '/') |
︙ | ︙ | |||
213 214 215 216 217 218 219 | - (OFString *)stringByDeletingPathExtension { void *pool; OFMutableArray OF_GENERIC(OFString *) *components; OFString *ret, *fileName; size_t pos; | | | | | | | | | | | 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 | - (OFString *)stringByDeletingPathExtension { void *pool; OFMutableArray OF_GENERIC(OFString *) *components; OFString *ret, *fileName; size_t pos; if (self.length == 0) return [[self copy] autorelease]; pool = objc_autoreleasePoolPush(); components = [[self.pathComponents mutableCopy] autorelease]; fileName = components.lastObject; pos = [fileName rangeOfString: @"." options: OF_STRING_SEARCH_BACKWARDS].location; if (pos == OF_NOT_FOUND || pos == 0) { objc_autoreleasePoolPop(pool); return [[self copy] autorelease]; } fileName = [fileName substringWithRange: of_range(0, pos)]; [components replaceObjectAtIndex: components.count - 1 withObject: fileName]; ret = [OFString pathWithComponents: components]; [ret retain]; objc_autoreleasePoolPop(pool); return [ret autorelease]; } - (OFString *)stringByStandardizingPath { void *pool = objc_autoreleasePoolPush(); OFArray OF_GENERIC(OFString *) *components; OFMutableArray OF_GENERIC(OFString *) *array; OFString *ret; bool done = false; if (self.length == 0) return @""; components = self.pathComponents; if (components.count == 1) { objc_autoreleasePoolPop(pool); return [[self copy] autorelease]; } array = [[components mutableCopy] autorelease]; while (!done) { size_t length = array.count; done = true; for (size_t i = 0; i < length; i++) { OFString *component = [array objectAtIndex: i]; OFString *parent = (i > 0 ? [array objectAtIndex: i - 1] : 0); if ([component isEqual: @"."] || component.length == 0) { [array removeObjectAtIndex: i]; done = false; break; } if ([component isEqual: @".."] && |
︙ | ︙ |
Modified src/OFString+PropertyListValue.m from [97be60a350] to [06291ad3fb].
︙ | ︙ | |||
35 36 37 38 39 40 41 | static OFArray * parseArrayElement(OFXMLElement *element) { OFMutableArray *ret = [OFMutableArray array]; void *pool = objc_autoreleasePoolPush(); | | | | | | | | | | | | | | < | < | | 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 | static OFArray * parseArrayElement(OFXMLElement *element) { OFMutableArray *ret = [OFMutableArray array]; void *pool = objc_autoreleasePoolPush(); for (OFXMLElement *child in element.elements) [ret addObject: parseElement(child)]; [ret makeImmutable]; objc_autoreleasePoolPop(pool); return ret; } static OFDictionary * parseDictElement(OFXMLElement *element) { OFMutableDictionary *ret = [OFMutableDictionary dictionary]; void *pool = objc_autoreleasePoolPush(); OFArray OF_GENERIC(OFXMLElement *) *children = element.elements; OFEnumerator OF_GENERIC(OFXMLElement *) *enumerator; OFXMLElement *key, *object; if (children.count % 2 != 0) @throw [OFInvalidFormatException exception]; enumerator = [children objectEnumerator]; while ((key = [enumerator nextObject]) && (object = [enumerator nextObject])) { if (key.namespace != nil || key.attributes.count != 0 || ![key.name isEqual: @"key"]) @throw [OFInvalidFormatException exception]; [ret setObject: parseElement(object) forKey: key.stringValue]; } [ret makeImmutable]; objc_autoreleasePoolPop(pool); return ret; } static OFString * parseStringElement(OFXMLElement *element) { return element.stringValue; } static OFData * parseDataElement(OFXMLElement *element) { return [OFData dataWithBase64EncodedString: element.stringValue]; } static OFDate * parseDateElement(OFXMLElement *element) { return [OFDate dateWithDateString: element.stringValue format: @"%Y-%m-%dT%H:%M:%SZ"]; } static OFNumber * parseTrueElement(OFXMLElement *element) { if (element.children.count != 0) @throw [OFInvalidFormatException exception]; return [OFNumber numberWithBool: true]; } static OFNumber * parseFalseElement(OFXMLElement *element) { if (element.children.count != 0) @throw [OFInvalidFormatException exception]; return [OFNumber numberWithBool: false]; } static OFNumber * parseRealElement(OFXMLElement *element) { return [OFNumber numberWithDouble: element.stringValue.doubleValue]; } static OFNumber * parseIntegerElement(OFXMLElement *element) { return [OFNumber numberWithIntMax: element.stringValue.decimalValue]; } static id parseElement(OFXMLElement *element) { OFString *elementName; if (element.namespace != nil || element.attributes.count != 0) @throw [OFInvalidFormatException exception]; elementName = element.name; if ([elementName isEqual: @"array"]) return parseArrayElement(element); else if ([elementName isEqual: @"dict"]) return parseDictElement(element); else if ([elementName isEqual: @"string"]) return parseStringElement(element); |
︙ | ︙ | |||
167 168 169 170 171 172 173 | { void *pool = objc_autoreleasePoolPush(); OFXMLElement *rootElement = [OFXMLElement elementWithXMLString: self]; OFXMLAttribute *versionAttribute; OFArray OF_GENERIC(OFXMLElement *) *elements; id ret; | | | | | | | | 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 | { void *pool = objc_autoreleasePoolPush(); OFXMLElement *rootElement = [OFXMLElement elementWithXMLString: self]; OFXMLAttribute *versionAttribute; OFArray OF_GENERIC(OFXMLElement *) *elements; id ret; if (![rootElement.name isEqual: @"plist"] || rootElement.namespace != nil) @throw [OFInvalidFormatException exception]; versionAttribute = [rootElement attributeForName: @"version"]; if (versionAttribute == nil) @throw [OFInvalidFormatException exception]; if (![versionAttribute.stringValue isEqual: @"1.0"]) @throw [OFUnsupportedVersionException exceptionWithVersion: [versionAttribute stringValue]]; elements = rootElement.elements; if (elements.count != 1) @throw [OFInvalidFormatException exception]; ret = parseElement(elements.firstObject); [ret retain]; objc_autoreleasePoolPop(pool); return [ret autorelease]; } @end |
Modified src/OFString+Serialization.m from [bfb40bb476] to [323b28b85f].
︙ | ︙ | |||
44 45 46 47 48 49 50 | root = [OFXMLElement elementWithXMLString: self]; } @catch (OFMalformedXMLException *e) { @throw [OFInvalidArgumentException exception]; } @catch (OFUnboundNamespaceException *e) { @throw [OFInvalidArgumentException exception]; } | | | | | | 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 | root = [OFXMLElement elementWithXMLString: self]; } @catch (OFMalformedXMLException *e) { @throw [OFInvalidArgumentException exception]; } @catch (OFUnboundNamespaceException *e) { @throw [OFInvalidArgumentException exception]; } version = [root attributeForName: @"version"].stringValue; if (version == nil) @throw [OFInvalidArgumentException exception]; if (version.decimalValue != 1) @throw [OFUnsupportedVersionException exceptionWithVersion: version]; elements = [root elementsForNamespace: OF_SERIALIZATION_NS]; if (elements.count != 1) @throw [OFInvalidArgumentException exception]; object = [[elements.firstObject objectByDeserializing] retain]; objc_autoreleasePoolPop(pool); return [object autorelease]; } @end |
Modified src/OFString+URLEncoding.m from [eb3c914e3d] to [b31ee5c6f5].
︙ | ︙ | |||
32 33 34 35 36 37 38 | @implementation OFString (URLEncoding) - (OFString *)stringByURLEncodingWithAllowedCharacters: (OFCharacterSet *)allowedCharacters { OFMutableString *ret = [OFMutableString string]; void *pool = objc_autoreleasePoolPush(); | | | | 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | @implementation OFString (URLEncoding) - (OFString *)stringByURLEncodingWithAllowedCharacters: (OFCharacterSet *)allowedCharacters { OFMutableString *ret = [OFMutableString string]; void *pool = objc_autoreleasePoolPush(); const of_unichar_t *characters = self.characters; size_t length = self.length; bool (*characterIsMember)(id, SEL, of_unichar_t) = (bool (*)(id, SEL, of_unichar_t))[allowedCharacters methodForSelector: @selector(characterIsMember:)]; for (size_t i = 0; i < length; i++) { of_unichar_t c = characters[i]; |
︙ | ︙ | |||
78 79 80 81 82 83 84 | return ret; } - (OFString *)stringByURLDecoding { void *pool = objc_autoreleasePoolPush(); | | | | 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 | return ret; } - (OFString *)stringByURLDecoding { void *pool = objc_autoreleasePoolPush(); const char *string = self.UTF8String; size_t length = self.UTF8StringLength; char *retCString, *retCString2; char byte = 0; int state = 0; size_t i = 0; if ((retCString = malloc(length + 1)) == NULL) @throw [OFOutOfMemoryException |
︙ | ︙ |
Modified src/OFString+XMLEscaping.m from [57e70e6dc2] to [93579edbe8].
︙ | ︙ | |||
33 34 35 36 37 38 39 | void *pool = objc_autoreleasePoolPush(); char *retCString; const char *string, *append; size_t length, retLength, appendLen; size_t j; OFString *ret; | | | | 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 | void *pool = objc_autoreleasePoolPush(); char *retCString; const char *string, *append; size_t length, retLength, appendLen; size_t j; OFString *ret; string = self.UTF8String; length = self.UTF8StringLength; j = 0; retLength = length; /* * We can't use allocMemoryWithSize: here as it might be a @"" literal */ |
︙ | ︙ |
Modified src/OFString+XMLUnescaping.m from [ca15662616] to [8d9a1c8db6].
︙ | ︙ | |||
84 85 86 87 88 89 90 | size_t i, last, length; bool inEntity; ret = [OFMutableString string]; pool = objc_autoreleasePoolPush(); | | | | 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 | size_t i, last, length; bool inEntity; ret = [OFMutableString string]; pool = objc_autoreleasePoolPush(); string = self.UTF8String; length = self.UTF8StringLength; last = 0; inEntity = false; for (i = 0; i < length; i++) { if (!inEntity && string[i] == '&') { [ret appendUTF8String: string + last |
︙ | ︙ |
Modified src/OFString.m from [b076cd8540] to [fd85923ed1].
︙ | ︙ | |||
144 145 146 147 148 149 150 | of_string_encoding_t of_string_parse_encoding(OFString *string) { void *pool = objc_autoreleasePoolPush(); of_string_encoding_t encoding; | | | 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 | of_string_encoding_t of_string_parse_encoding(OFString *string) { void *pool = objc_autoreleasePoolPush(); of_string_encoding_t encoding; string = string.lowercaseString; if ([string isEqual: @"utf8"] || [string isEqual: @"utf-8"]) encoding = OF_STRING_ENCODING_UTF_8; else if ([string isEqual: @"ascii"] || [string isEqual: @"us-ascii"]) encoding = OF_STRING_ENCODING_ASCII; else if ([string isEqual: @"iso-8859-1"] || [string isEqual: @"iso_8859-1"]) |
︙ | ︙ | |||
336 337 338 339 340 341 342 | #ifdef OF_HAVE_UNICODE_TABLES static OFString * decomposedString(OFString *self, const char *const *const *table, size_t size) { OFMutableString *ret = [OFMutableString string]; void *pool = objc_autoreleasePoolPush(); | | | | 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 | #ifdef OF_HAVE_UNICODE_TABLES static OFString * decomposedString(OFString *self, const char *const *const *table, size_t size) { OFMutableString *ret = [OFMutableString string]; void *pool = objc_autoreleasePoolPush(); const of_unichar_t *characters = self.characters; size_t length = self.length; for (size_t i = 0; i < length; i++) { of_unichar_t c = characters[i]; const char *const *page; if (c >= size) { [ret appendCharacters: &c |
︙ | ︙ | |||
871 872 873 874 875 876 877 | OF_INVALID_INIT_METHOD } - (instancetype)initWithData: (OFData *)data encoding: (of_string_encoding_t)encoding { @try { | | | | | 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 | OF_INVALID_INIT_METHOD } - (instancetype)initWithData: (OFData *)data encoding: (of_string_encoding_t)encoding { @try { if (data.itemSize != 1) @throw [OFInvalidArgumentException exception]; } @catch (id e) { [self release]; @throw e; } self = [self initWithCString: data.items encoding: encoding length: data.count]; return self; } - (instancetype)initWithString: (OFString *)string { OF_INVALID_INIT_METHOD |
︙ | ︙ | |||
993 994 995 996 997 998 999 | uintmax_t fileSize; @try { void *pool = objc_autoreleasePoolPush(); OFFile *file = nil; @try { | | | | | 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 | uintmax_t fileSize; @try { void *pool = objc_autoreleasePoolPush(); OFFile *file = nil; @try { fileSize = [[OFFileManager defaultManager] attributesOfItemAtPath: path].fileSize; } @catch (OFRetrieveItemAttributesFailedException *e) { @throw [OFOpenItemFailedException exceptionWithPath: path mode: @"r" errNo: e.errNo]; } objc_autoreleasePoolPop(pool); # if UINTMAX_MAX > SIZE_MAX if (fileSize > SIZE_MAX) @throw [OFOutOfRangeException exception]; |
︙ | ︙ | |||
1076 1077 1078 1079 1080 1081 1082 | @try { data = [OFData dataWithContentsOfURL: URL]; } @catch (id e) { [self release]; @throw e; } | | | | | | | | | | 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 | @try { data = [OFData dataWithContentsOfURL: URL]; } @catch (id e) { [self release]; @throw e; } self = [self initWithCString: data.items encoding: encoding length: data.count * data.itemSize]; objc_autoreleasePoolPop(pool); return self; } - (instancetype)initWithSerialization: (OFXMLElement *)element { void *pool = objc_autoreleasePoolPush(); OFString *stringValue; @try { if (![element.namespace isEqual: OF_SERIALIZATION_NS]) @throw [OFInvalidArgumentException exception]; if ([self isKindOfClass: [OFMutableString class]]) { if (![element.name isEqual: @"OFMutableString"]) @throw [OFInvalidArgumentException exception]; } else { if (![element.name isEqual: @"OFString"]) @throw [OFInvalidArgumentException exception]; } stringValue = element.stringValue; } @catch (id e) { [self release]; @throw e; } self = [self initWithString: stringValue]; objc_autoreleasePoolPop(pool); return self; } - (size_t)of_getCString: (char *)cString maxLength: (size_t)maxLength encoding: (of_string_encoding_t)encoding lossy: (bool)lossy { const of_unichar_t *characters = self.characters; size_t i, length = self.length; switch (encoding) { case OF_STRING_ENCODING_UTF_8:; size_t j = 0; for (i = 0; i < length; i++) { char buffer[4]; |
︙ | ︙ | |||
1370 1371 1372 1373 1374 1375 1376 | lossy: true]; } - (const char *)of_cStringWithEncoding: (of_string_encoding_t)encoding lossy: (bool)lossy { OFObject *object = [[[OFObject alloc] init] autorelease]; | | | 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 | lossy: true]; } - (const char *)of_cStringWithEncoding: (of_string_encoding_t)encoding lossy: (bool)lossy { OFObject *object = [[[OFObject alloc] init] autorelease]; size_t length = self.length; char *cString; switch (encoding) { case OF_STRING_ENCODING_UTF_8:; size_t cStringLength; cString = [object allocMemoryWithSize: (length * 4) + 1]; |
︙ | ︙ | |||
1449 1450 1451 1452 1453 1454 1455 | - (size_t)cStringLengthWithEncoding: (of_string_encoding_t)encoding { switch (encoding) { case OF_STRING_ENCODING_UTF_8:; const of_unichar_t *characters; size_t length, UTF8StringLength = 0; | | | | 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 | - (size_t)cStringLengthWithEncoding: (of_string_encoding_t)encoding { switch (encoding) { case OF_STRING_ENCODING_UTF_8:; const of_unichar_t *characters; size_t length, UTF8StringLength = 0; characters = self.characters; length = self.length; for (size_t i = 0; i < length; i++) { char buffer[4]; size_t len = of_string_utf8_encode(characters[i], buffer); if (len == 0) |
︙ | ︙ | |||
1477 1478 1479 1480 1481 1482 1483 | case OF_STRING_ENCODING_WINDOWS_1252: case OF_STRING_ENCODING_CODEPAGE_437: case OF_STRING_ENCODING_CODEPAGE_850: case OF_STRING_ENCODING_CODEPAGE_858: case OF_STRING_ENCODING_MAC_ROMAN: case OF_STRING_ENCODING_KOI8_R: case OF_STRING_ENCODING_KOI8_U: | | | 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 | case OF_STRING_ENCODING_WINDOWS_1252: case OF_STRING_ENCODING_CODEPAGE_437: case OF_STRING_ENCODING_CODEPAGE_850: case OF_STRING_ENCODING_CODEPAGE_858: case OF_STRING_ENCODING_MAC_ROMAN: case OF_STRING_ENCODING_KOI8_R: case OF_STRING_ENCODING_KOI8_U: return self.length; default: @throw [OFInvalidEncodingException exception]; } } - (size_t)UTF8StringLength { |
︙ | ︙ | |||
1514 1515 1516 1517 1518 1519 1520 | if (object == self) return true; if (![object isKindOfClass: [OFString class]]) return false; otherString = object; | | | | | | 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 | if (object == self) return true; if (![object isKindOfClass: [OFString class]]) return false; otherString = object; length = self.length; if (otherString.length != length) return false; pool = objc_autoreleasePoolPush(); characters = self.characters; otherCharacters = otherString.characters; if (memcmp(characters, otherCharacters, length * sizeof(of_unichar_t)) != 0) { objc_autoreleasePoolPop(pool); return false; } |
︙ | ︙ | |||
1559 1560 1561 1562 1563 1564 1565 | if (object == self) return OF_ORDERED_SAME; if (![(id)object isKindOfClass: [OFString class]]) @throw [OFInvalidArgumentException exception]; otherString = (OFString *)object; | | | | | | | | | | | | 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 | if (object == self) return OF_ORDERED_SAME; if (![(id)object isKindOfClass: [OFString class]]) @throw [OFInvalidArgumentException exception]; otherString = (OFString *)object; minimumLength = (self.length > otherString.length ? otherString.length : self.length); pool = objc_autoreleasePoolPush(); characters = self.characters; otherCharacters = otherString.characters; for (size_t i = 0; i < minimumLength; i++) { if (characters[i] > otherCharacters[i]) { objc_autoreleasePoolPop(pool); return OF_ORDERED_DESCENDING; } if (characters[i] < otherCharacters[i]) { objc_autoreleasePoolPop(pool); return OF_ORDERED_ASCENDING; } } objc_autoreleasePoolPop(pool); if (self.length > otherString.length) return OF_ORDERED_DESCENDING; if (self.length < otherString.length) return OF_ORDERED_ASCENDING; return OF_ORDERED_SAME; } - (of_comparison_result_t)caseInsensitiveCompare: (OFString *)otherString { void *pool = objc_autoreleasePoolPush(); const of_unichar_t *characters, *otherCharacters; size_t length, otherLength, minimumLength; if (otherString == self) return OF_ORDERED_SAME; characters = self.characters; otherCharacters = otherString.characters; length = self.length; otherLength = otherString.length; minimumLength = (length > otherLength ? otherLength : length); for (size_t i = 0; i < minimumLength; i++) { of_unichar_t c = characters[i]; of_unichar_t oc = otherCharacters[i]; |
︙ | ︙ | |||
1651 1652 1653 1654 1655 1656 1657 | return OF_ORDERED_ASCENDING; return OF_ORDERED_SAME; } - (uint32_t)hash { | | | | | | 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 | return OF_ORDERED_ASCENDING; return OF_ORDERED_SAME; } - (uint32_t)hash { const of_unichar_t *characters = self.characters; size_t length = self.length; uint32_t hash; OF_HASH_INIT(hash); for (size_t i = 0; i < length; i++) { const of_unichar_t c = characters[i]; OF_HASH_ADD(hash, (c & 0xFF0000) >> 16); OF_HASH_ADD(hash, (c & 0x00FF00) >> 8); OF_HASH_ADD(hash, c & 0x0000FF); } OF_HASH_FINALIZE(hash); return hash; } |
︙ | ︙ | |||
1733 1734 1735 1736 1737 1738 1739 | withString: @"\\t"]; if (options & OF_JSON_REPRESENTATION_JSON5) { [JSON replaceOccurrencesOfString: @"\n" withString: @"\\\n"]; if (options & OF_JSON_REPRESENTATION_IDENTIFIER) { | | | 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 | withString: @"\\t"]; if (options & OF_JSON_REPRESENTATION_JSON5) { [JSON replaceOccurrencesOfString: @"\n" withString: @"\\\n"]; if (options & OF_JSON_REPRESENTATION_IDENTIFIER) { const char *cString = self.UTF8String; if ((!of_ascii_isalpha(cString[0]) && cString[0] != '_' && cString[0] != '$') || strpbrk(cString, " \n\r\t\b\f\\\"'") != NULL) { [JSON prependString: @"\""]; [JSON appendString: @"\""]; } |
︙ | ︙ | |||
1763 1764 1765 1766 1767 1768 1769 | } - (OFData *)messagePackRepresentation { OFMutableData *data; size_t length; | | | 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 | } - (OFData *)messagePackRepresentation { OFMutableData *data; size_t length; length = self.UTF8StringLength; if (length <= 31) { uint8_t tmp = 0xA0 | ((uint8_t)length & 0x1F); data = [OFMutableData dataWithItemSize: 1 capacity: length + 1]; |
︙ | ︙ | |||
1804 1805 1806 1807 1808 1809 1810 | [data addItem: &type]; [data addItems: &tmp count: sizeof(tmp)]; } else @throw [OFOutOfRangeException exception]; | | | | | | | 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 | [data addItem: &type]; [data addItems: &tmp count: sizeof(tmp)]; } else @throw [OFOutOfRangeException exception]; [data addItems: self.UTF8String count: length]; return data; } - (of_range_t)rangeOfString: (OFString *)string { return [self rangeOfString: string options: 0 range: of_range(0, self.length)]; } - (of_range_t)rangeOfString: (OFString *)string options: (int)options { return [self rangeOfString: string options: options range: of_range(0, self.length)]; } - (of_range_t)rangeOfString: (OFString *)string options: (int)options range: (of_range_t)range { void *pool; const of_unichar_t *searchCharacters; of_unichar_t *characters; size_t searchLength; if ((searchLength = string.length) == 0) return of_range(0, 0); if (searchLength > range.length) return of_range(OF_NOT_FOUND, 0); if (range.length > SIZE_MAX / sizeof(of_unichar_t)) @throw [OFOutOfRangeException exception]; pool = objc_autoreleasePoolPush(); searchCharacters = string.characters; if ((characters = malloc(range.length * sizeof(of_unichar_t))) == NULL) @throw [OFOutOfMemoryException exceptionWithRequestedSize: range.length * sizeof(of_unichar_t)]; @try { [self getCharacters: characters |
︙ | ︙ | |||
1892 1893 1894 1895 1896 1897 1898 | return of_range(OF_NOT_FOUND, 0); } - (size_t)indexOfCharacterFromSet: (OFCharacterSet *)characterSet { return [self indexOfCharacterFromSet: characterSet options: 0 | | | | 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 | return of_range(OF_NOT_FOUND, 0); } - (size_t)indexOfCharacterFromSet: (OFCharacterSet *)characterSet { return [self indexOfCharacterFromSet: characterSet options: 0 range: of_range(0, self.length)]; } - (size_t)indexOfCharacterFromSet: (OFCharacterSet *)characterSet options: (int)options { return [self indexOfCharacterFromSet: characterSet options: options range: of_range(0, self.length)]; } - (size_t)indexOfCharacterFromSet: (OFCharacterSet *)characterSet options: (int)options range: (of_range_t)range { bool (*characterIsMember)(id, SEL, of_unichar_t) = |
︙ | ︙ | |||
1957 1958 1959 1960 1961 1962 1963 | - (bool)containsString: (OFString *)string { void *pool; const of_unichar_t *characters, *searchCharacters; size_t length, searchLength; | | | | | | | | 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 | - (bool)containsString: (OFString *)string { void *pool; const of_unichar_t *characters, *searchCharacters; size_t length, searchLength; if ((searchLength = string.length) == 0) return true; if (searchLength > (length = self.length)) return false; pool = objc_autoreleasePoolPush(); characters = self.characters; searchCharacters = string.characters; for (size_t i = 0; i <= length - searchLength; i++) { if (memcmp(characters + i, searchCharacters, searchLength * sizeof(of_unichar_t)) == 0) { objc_autoreleasePoolPop(pool); return true; } } objc_autoreleasePoolPop(pool); return false; } - (OFString *)substringWithRange: (of_range_t)range { void *pool; OFString *ret; if (range.length > SIZE_MAX - range.location || range.location + range.length > self.length) @throw [OFOutOfRangeException exception]; pool = objc_autoreleasePoolPush(); ret = [[OFString alloc] initWithCharacters: self.characters + range.location length: range.length]; objc_autoreleasePoolPop(pool); return [ret autorelease]; } - (OFString *)stringByAppendingString: (OFString *)string |
︙ | ︙ | |||
2148 2149 2150 2151 2152 2153 2154 | return new; } - (bool)hasPrefix: (OFString *)prefix { of_unichar_t *tmp; | < | < | | | | | 2148 2149 2150 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 2196 2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 2208 | return new; } - (bool)hasPrefix: (OFString *)prefix { of_unichar_t *tmp; size_t prefixLength; bool hasPrefix; if ((prefixLength = prefix.length) > self.length) return false; tmp = [self allocMemoryWithSize: sizeof(of_unichar_t) count: prefixLength]; @try { void *pool = objc_autoreleasePoolPush(); [self getCharacters: tmp inRange: of_range(0, prefixLength)]; hasPrefix = (memcmp(tmp, prefix.characters, prefixLength * sizeof(of_unichar_t)) == 0); objc_autoreleasePoolPop(pool); } @finally { [self freeMemory: tmp]; } return hasPrefix; } - (bool)hasSuffix: (OFString *)suffix { of_unichar_t *tmp; const of_unichar_t *suffixCharacters; size_t length, suffixLength; bool hasSuffix; if ((suffixLength = suffix.length) > self.length) return false; length = self.length; tmp = [self allocMemoryWithSize: sizeof(of_unichar_t) count: suffixLength]; @try { void *pool = objc_autoreleasePoolPush(); [self getCharacters: tmp inRange: of_range(length - suffixLength, suffixLength)]; suffixCharacters = suffix.characters; hasSuffix = (memcmp(tmp, suffixCharacters, suffixLength * sizeof(of_unichar_t)) == 0); objc_autoreleasePoolPop(pool); } @finally { [self freeMemory: tmp]; } |
︙ | ︙ | |||
2221 2222 2223 2224 2225 2226 2227 | - (OFArray *)componentsSeparatedByString: (OFString *)delimiter options: (int)options { void *pool; OFMutableArray *array = [OFMutableArray array]; const of_unichar_t *characters, *delimiterCharacters; bool skipEmpty = (options & OF_STRING_SKIP_EMPTY); | | | | | | | | 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 2245 2246 2247 2248 2249 2250 2251 2252 2253 2254 2255 2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 | - (OFArray *)componentsSeparatedByString: (OFString *)delimiter options: (int)options { void *pool; OFMutableArray *array = [OFMutableArray array]; const of_unichar_t *characters, *delimiterCharacters; bool skipEmpty = (options & OF_STRING_SKIP_EMPTY); size_t length = self.length; size_t delimiterLength = delimiter.length; size_t last; OFString *component; pool = objc_autoreleasePoolPush(); characters = self.characters; delimiterCharacters = delimiter.characters; if (delimiterLength > length) { [array addObject: [[self copy] autorelease]]; [array makeImmutable]; objc_autoreleasePoolPop(pool); return array; } last = 0; for (size_t i = 0; i <= length - delimiterLength; i++) { if (memcmp(characters + i, delimiterCharacters, delimiterLength * sizeof(of_unichar_t)) != 0) continue; component = [self substringWithRange: of_range(last, i - last)]; if (!skipEmpty || component.length > 0) [array addObject: component]; i += delimiterLength - 1; last = i + 1; } component = [self substringWithRange: of_range(last, length - last)]; if (!skipEmpty || component.length > 0) [array addObject: component]; [array makeImmutable]; objc_autoreleasePoolPop(pool); return array; |
︙ | ︙ | |||
2278 2279 2280 2281 2282 2283 2284 | - (OFArray *) componentsSeparatedByCharactersInSet: (OFCharacterSet *)characterSet options: (int)options { OFMutableArray *array = [OFMutableArray array]; void *pool = objc_autoreleasePoolPush(); bool skipEmpty = (options & OF_STRING_SKIP_EMPTY); | | | | 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 2288 2289 2290 2291 | - (OFArray *) componentsSeparatedByCharactersInSet: (OFCharacterSet *)characterSet options: (int)options { OFMutableArray *array = [OFMutableArray array]; void *pool = objc_autoreleasePoolPush(); bool skipEmpty = (options & OF_STRING_SKIP_EMPTY); const of_unichar_t *characters = self.characters; size_t length = self.length; bool (*characterIsMember)(id, SEL, of_unichar_t) = (bool (*)(id, SEL, of_unichar_t))[characterSet methodForSelector: @selector(characterIsMember:)]; size_t last; last = 0; for (size_t i = 0; i < length; i++) { |
︙ | ︙ | |||
2314 2315 2316 2317 2318 2319 2320 | return array; } - (intmax_t)decimalValue { void *pool = objc_autoreleasePoolPush(); | | | | 2312 2313 2314 2315 2316 2317 2318 2319 2320 2321 2322 2323 2324 2325 2326 2327 | return array; } - (intmax_t)decimalValue { void *pool = objc_autoreleasePoolPush(); const of_unichar_t *characters = self.characters; size_t i = 0, length = self.length; intmax_t value = 0; bool expectWhitespace = false; while (length > 0 && of_ascii_isspace(*characters)) { characters++; length--; } |
︙ | ︙ | |||
2363 2364 2365 2366 2367 2368 2369 | return value; } - (uintmax_t)hexadecimalValue { void *pool = objc_autoreleasePoolPush(); | | | | 2361 2362 2363 2364 2365 2366 2367 2368 2369 2370 2371 2372 2373 2374 2375 2376 | return value; } - (uintmax_t)hexadecimalValue { void *pool = objc_autoreleasePoolPush(); const of_unichar_t *characters = self.characters; size_t i = 0, length = self.length; uintmax_t value = 0; bool expectWhitespace = false, foundValue = false; while (length > 0 && of_ascii_isspace(*characters)) { characters++; length--; } |
︙ | ︙ | |||
2426 2427 2428 2429 2430 2431 2432 | return value; } - (uintmax_t)octalValue { void *pool = objc_autoreleasePoolPush(); | | | | 2424 2425 2426 2427 2428 2429 2430 2431 2432 2433 2434 2435 2436 2437 2438 2439 | return value; } - (uintmax_t)octalValue { void *pool = objc_autoreleasePoolPush(); const of_unichar_t *characters = self.characters; size_t i = 0, length = self.length; uintmax_t value = 0; bool expectWhitespace = false; while (length > 0 && of_ascii_isspace(*characters)) { characters++; length--; } |
︙ | ︙ | |||
2475 2476 2477 2478 2479 2480 2481 | } - (float)floatValue { void *pool = objc_autoreleasePoolPush(); #if defined(OF_AMIGAOS_M68K) || defined(OF_MORPHOS) | | | | | | 2473 2474 2475 2476 2477 2478 2479 2480 2481 2482 2483 2484 2485 2486 2487 2488 2489 2490 2491 2492 2493 2494 2495 2496 2497 2498 2499 2500 2501 2502 2503 2504 2505 2506 2507 | } - (float)floatValue { void *pool = objc_autoreleasePoolPush(); #if defined(OF_AMIGAOS_M68K) || defined(OF_MORPHOS) OFString *stripped = self.stringByDeletingEnclosingWhitespaces; if ([stripped caseInsensitiveCompare: @"INF"] == OF_ORDERED_SAME || [stripped caseInsensitiveCompare: @"INFINITY"] == OF_ORDERED_SAME) return INFINITY; if ([stripped caseInsensitiveCompare: @"-INF"] == OF_ORDERED_SAME || [stripped caseInsensitiveCompare: @"-INFINITY"] == OF_ORDERED_SAME) return -INFINITY; #endif #ifdef HAVE_STRTOF_L const char *UTF8String = self.UTF8String; #else /* * If we have no strtof_l, we have no other choice but to replace "." * with the locale's decimal point. */ OFString *decimalPoint = [OFLocale decimalPoint]; const char *UTF8String = [self stringByReplacingOccurrencesOfString: @"." withString: decimalPoint].UTF8String; #endif char *endPointer = NULL; float value; while (of_ascii_isspace(*UTF8String)) UTF8String++; |
︙ | ︙ | |||
2525 2526 2527 2528 2529 2530 2531 | } - (double)doubleValue { void *pool = objc_autoreleasePoolPush(); #if defined(OF_AMIGAOS_M68K) || defined(OF_MORPHOS) | | | | | | 2523 2524 2525 2526 2527 2528 2529 2530 2531 2532 2533 2534 2535 2536 2537 2538 2539 2540 2541 2542 2543 2544 2545 2546 2547 2548 2549 2550 2551 2552 2553 2554 2555 2556 2557 | } - (double)doubleValue { void *pool = objc_autoreleasePoolPush(); #if defined(OF_AMIGAOS_M68K) || defined(OF_MORPHOS) OFString *stripped = self.stringByDeletingEnclosingWhitespaces; if ([stripped caseInsensitiveCompare: @"INF"] == OF_ORDERED_SAME || [stripped caseInsensitiveCompare: @"INFINITY"] == OF_ORDERED_SAME) return INFINITY; if ([stripped caseInsensitiveCompare: @"-INF"] == OF_ORDERED_SAME || [stripped caseInsensitiveCompare: @"-INFINITY"] == OF_ORDERED_SAME) return -INFINITY; #endif #ifdef HAVE_STRTOD_L const char *UTF8String = self.UTF8String; #else /* * If we have no strtod_l, we have no other choice but to replace "." * with the locale's decimal point. */ OFString *decimalPoint = [OFLocale decimalPoint]; const char *UTF8String = [self stringByReplacingOccurrencesOfString: @"." withString: decimalPoint].UTF8String; #endif char *endPointer = NULL; double value; while (of_ascii_isspace(*UTF8String)) UTF8String++; |
︙ | ︙ | |||
2573 2574 2575 2576 2577 2578 2579 | return value; } - (const of_unichar_t *)characters { OFObject *object = [[[OFObject alloc] init] autorelease]; | | | | | 2571 2572 2573 2574 2575 2576 2577 2578 2579 2580 2581 2582 2583 2584 2585 2586 2587 2588 2589 2590 2591 2592 2593 2594 2595 2596 2597 2598 2599 2600 2601 2602 2603 2604 2605 2606 | return value; } - (const of_unichar_t *)characters { OFObject *object = [[[OFObject alloc] init] autorelease]; size_t length = self.length; of_unichar_t *ret; ret = [object allocMemoryWithSize: sizeof(of_unichar_t) count: length]; [self getCharacters: ret inRange: of_range(0, length)]; return ret; } - (const of_char16_t *)UTF16String { return [self UTF16StringWithByteOrder: OF_BYTE_ORDER_NATIVE]; } - (const of_char16_t *)UTF16StringWithByteOrder: (of_byte_order_t)byteOrder { OFObject *object = [[[OFObject alloc] init] autorelease]; void *pool = objc_autoreleasePoolPush(); const of_unichar_t *characters = self.characters; size_t length = self.length; of_char16_t *ret; size_t j; bool swap = (byteOrder != OF_BYTE_ORDER_NATIVE); /* Allocate memory for the worst case */ ret = [object allocMemoryWithSize: sizeof(of_char16_t) count: (length + 1) * 2]; |
︙ | ︙ | |||
2643 2644 2645 2646 2647 2648 2649 | objc_autoreleasePoolPop(pool); return ret; } - (size_t)UTF16StringLength { | | | | | 2641 2642 2643 2644 2645 2646 2647 2648 2649 2650 2651 2652 2653 2654 2655 2656 2657 2658 2659 2660 2661 2662 2663 2664 2665 2666 2667 2668 2669 2670 2671 2672 2673 2674 2675 | objc_autoreleasePoolPop(pool); return ret; } - (size_t)UTF16StringLength { const of_unichar_t *characters = self.characters; size_t length, UTF16StringLength; length = UTF16StringLength = self.length; for (size_t i = 0; i < length; i++) if (characters[i] > 0xFFFF) UTF16StringLength++; return UTF16StringLength; } - (const of_char32_t *)UTF32String { return [self UTF32StringWithByteOrder: OF_BYTE_ORDER_NATIVE]; } - (const of_char32_t *)UTF32StringWithByteOrder: (of_byte_order_t)byteOrder { OFObject *object = [[[OFObject alloc] init] autorelease]; size_t length = self.length; of_char32_t *ret; ret = [object allocMemoryWithSize: sizeof(of_char32_t) count: length + 1]; [self getCharacters: ret inRange: of_range(0, length)]; ret[length] = 0; |
︙ | ︙ | |||
2757 2758 2759 2760 2761 2762 2763 | objc_autoreleasePoolPop(pool); } #ifdef OF_HAVE_BLOCKS - (void)enumerateLinesUsingBlock: (of_string_line_enumeration_block_t)block { void *pool = objc_autoreleasePoolPush(); | | | | 2755 2756 2757 2758 2759 2760 2761 2762 2763 2764 2765 2766 2767 2768 2769 2770 | objc_autoreleasePoolPop(pool); } #ifdef OF_HAVE_BLOCKS - (void)enumerateLinesUsingBlock: (of_string_line_enumeration_block_t)block { void *pool = objc_autoreleasePoolPush(); const of_unichar_t *characters = self.characters; size_t i, last = 0, length = self.length; bool stop = false, lastCarriageReturn = false; for (i = 0; i < length && !stop; i++) { if (lastCarriageReturn && characters[i] == '\n') { lastCarriageReturn = false; last++; |
︙ | ︙ |
Modified src/OFString_UTF8.m from [0962ed33d1] to [b5bfc583a1].
︙ | ︙ | |||
446 447 448 449 450 451 452 | - (instancetype)initWithString: (OFString *)string { self = [super init]; @try { _s = &_storage; | | | | | 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 | - (instancetype)initWithString: (OFString *)string { self = [super init]; @try { _s = &_storage; _s->cStringLength = string.UTF8StringLength; if ([string isKindOfClass: [OFString_UTF8 class]] || [string isKindOfClass: [OFMutableString_UTF8 class]]) _s->isUTF8 = ((OFString_UTF8 *)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; } |
︙ | ︙ | |||
676 677 678 679 680 681 682 | int cStringLength; if (format == nil) @throw [OFInvalidArgumentException exception]; _s = &_storage; | | | 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 | 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, |
︙ | ︙ | |||
789 790 791 792 793 794 795 | return true; if (![object isKindOfClass: [OFString class]]) return false; otherString = object; | | | | | | | 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 | 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: [OFString_UTF8 class]] || [otherString isKindOfClass: [OFMutableString_UTF8 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; } |
︙ | ︙ | |||
852 853 854 855 856 857 858 | if (otherString == self) return OF_ORDERED_SAME; if (![otherString isKindOfClass: [OFString class]]) @throw [OFInvalidArgumentException exception]; | | | | 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 | 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); |
︙ | ︙ | |||
943 944 945 946 947 948 949 | 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); | | | | 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 | 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; |
︙ | ︙ | |||
981 982 983 984 985 986 987 | } - (void)getCharacters: (of_unichar_t *)buffer inRange: (of_range_t)range { /* TODO: Could be slightly optimized */ void *pool = objc_autoreleasePoolPush(); | | | | | 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 | } - (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) { |
︙ | ︙ | |||
1028 1029 1030 1031 1032 1033 1034 | 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); | | | | | | 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 | 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; |
︙ | ︙ | |||
1092 1093 1094 1095 1096 1097 1098 | return [OFString stringWithUTF8String: _s->cString + start length: end - start]; } - (bool)hasPrefix: (OFString *)prefix { | | | | | | | | 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 | 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(); |
︙ | ︙ | |||
1139 1140 1141 1142 1143 1144 1145 | 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]; | | | | 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 | 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; |
︙ | ︙ |
Modified src/OFSystemInfo.m from [ee4e3a6986] to [a2974f4317].
︙ | ︙ | |||
145 146 147 148 149 150 151 | initOperatingSystemVersion(void) { #if defined(OF_IOS) || defined(OF_MACOS) # ifdef OF_HAVE_FILES void *pool = objc_autoreleasePoolPush(); @try { | | | > | | 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 | initOperatingSystemVersion(void) { #if defined(OF_IOS) || defined(OF_MACOS) # ifdef OF_HAVE_FILES void *pool = objc_autoreleasePoolPush(); @try { OFDictionary *propertyList = [OFString stringWithContentsOfFile: @"/System/Library/CoreServices/SystemVersion.plist"] .propertyListValue; operatingSystemVersion = [[propertyList objectForKey: @"ProductVersion"] copy]; } @finally { objc_autoreleasePoolPop(pool); } # endif #elif defined(OF_WINDOWS) # ifdef OF_HAVE_FILES |
︙ | ︙ | |||
173 174 175 176 177 178 179 | systemDirLen = GetSystemDirectoryW(systemDir, PATH_MAX); if (systemDirLen == 0) return; systemDirString = [OFString stringWithUTF16String: systemDir length: systemDirLen]; | | | | 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 | systemDirLen = GetSystemDirectoryW(systemDir, PATH_MAX); if (systemDirLen == 0) return; systemDirString = [OFString stringWithUTF16String: systemDir length: systemDirLen]; path = [systemDirString stringByAppendingPathComponent: @"kernel32.dll"].UTF16String; if ((bufferLen = GetFileVersionInfoSizeW(path, NULL)) == 0) return; if ((buffer = malloc(bufferLen)) == 0) return; @try { |
︙ | ︙ | |||
433 434 435 436 437 438 439 | return @"PROGDIR:"; # else OFDictionary *env = [OFApplication environment]; OFString *var; void *pool; if ((var = [env objectForKey: @"XDG_DATA_HOME"]) != nil && | | | 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 | return @"PROGDIR:"; # else OFDictionary *env = [OFApplication environment]; OFString *var; void *pool; if ((var = [env objectForKey: @"XDG_DATA_HOME"]) != nil && var.length > 0) return var; if ((var = [env objectForKey: @"HOME"]) == nil) @throw [OFNotImplementedException exceptionWithSelector: _cmd object: self]; pool = objc_autoreleasePoolPush(); |
︙ | ︙ | |||
526 527 528 529 530 531 532 | # elif defined(OF_AMIGAOS) return @"PROGDIR:"; # else OFDictionary *env = [OFApplication environment]; OFString *var; if ((var = [env objectForKey: @"XDG_CONFIG_HOME"]) != nil && | | | 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 | # elif defined(OF_AMIGAOS) return @"PROGDIR:"; # else OFDictionary *env = [OFApplication environment]; OFString *var; if ((var = [env objectForKey: @"XDG_CONFIG_HOME"]) != nil && var.length > 0) return var; if ((var = [env objectForKey: @"HOME"]) == nil) @throw [OFNotImplementedException exceptionWithSelector: _cmd object: self]; return [var stringByAppendingPathComponent: @".config"]; |
︙ | ︙ |
Modified src/OFTCPSocket.h from [7fc0a58cc9] to [0da62ee227].
︙ | ︙ | |||
31 32 33 34 35 36 37 | /*! * @brief A block which is called when the socket connected. * * @param socket The socket which connected * @param exception An exception which occurred while connecting the socket or * `nil` on success */ | | | | < | | | | | 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 | /*! * @brief A block which is called when the socket connected. * * @param socket The socket which connected * @param exception An exception which occurred while connecting the socket or * `nil` on success */ typedef void (^of_tcp_socket_async_connect_block_t)(OFTCPSocket *socket, id _Nullable exception); /*! * @brief A block which is called when the socket accepted a connection. * * @param socket The socket which accepted the connection * @param acceptedSocket The socket which has been accepted * @param exception An exception which occurred while accepting the socket or * `nil` on success * @return A bool whether the same block should be used for the next incoming * connection */ typedef bool (^of_tcp_socket_async_accept_block_t)(OFTCPSocket *socket, OFTCPSocket *acceptedSocket, id _Nullable exception); #endif /*! * @protocol OFTCPSocketDelegate OFTCPSocket.h ObjFW/OFTCPSocket.h * * A delegate for OFTCPSocket. */ @protocol OFTCPSocketDelegate <OFStreamDelegate> @optional /*! * @brief A method which is called when a socket connected. * * @param socket The socket which connected * @param host The host connected to * @param port The port on the host connected to * @param exception An exception that occurred while connecting, or nil on * success */ - (void)socket: (OFTCPSocket *)socket didConnectToHost: (OFString *)host port: (uint16_t)port exception: (nullable id)exception; /*! * @brief A method which is called when a socket accepted a connection. * * @param socket The socket which accepted the connection * @param acceptedSocket The socket which has been accepted * @param exception An exception that occurred while accepting, or nil on * success * @return A bool whether to accept the next incoming connection */ - (bool)socket: (OFTCPSocket *)socket didAcceptSocket: (OFTCPSocket *)acceptedSocket exception: (nullable id)exception; @end /*! * @class OFTCPSocket OFTCPSocket.h ObjFW/OFTCPSocket.h * * @brief A class which provides methods to create and use TCP sockets. |
︙ | ︙ |
Modified src/OFTCPSocket.m from [909cd558d8] to [e57d0397dd].
︙ | ︙ | |||
134 135 136 137 138 139 140 | _socket = [sock retain]; _host = [host copy]; _port = port; _SOCKS5Host = [SOCKS5Host copy]; _SOCKS5Port = SOCKS5Port; _delegate = [delegate retain]; | | | 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 | _socket = [sock retain]; _host = [host copy]; _port = port; _SOCKS5Host = [SOCKS5Host copy]; _SOCKS5Port = SOCKS5Port; _delegate = [delegate retain]; _socket.delegate = self; } @catch (id e) { [self release]; @throw e; } return self; } |
︙ | ︙ | |||
172 173 174 175 176 177 178 | return self; } #endif - (void)dealloc { #ifdef OF_HAVE_BLOCKS | | | | | | | | | | 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 | return self; } #endif - (void)dealloc { #ifdef OF_HAVE_BLOCKS if (_block == NULL) #endif if (_socket.delegate == self) _socket.delegate = _delegate; [_socket release]; [_host release]; [_SOCKS5Host release]; [_delegate release]; #ifdef OF_HAVE_BLOCKS [_block release]; #endif [_exception release]; [_socketAddresses release]; [_request release]; [super dealloc]; } - (void)didConnect { if (_exception == nil) _socket.blocking = true; #ifdef OF_HAVE_BLOCKS if (_block != NULL) _block(_socket, _exception); else { #endif _socket.delegate = _delegate; if ([_delegate respondsToSelector: @selector(socket:didConnectToHost:port:exception:)]) [_delegate socket: _socket didConnectToHost: _host port: _port exception: _exception]; #ifdef OF_HAVE_BLOCKS } #endif } - (void)of_socketDidConnect: (OFTCPSocket *)sock exception: (id)exception { if (exception != nil) { if (_socketAddressesIndex >= _socketAddresses.count) { _exception = [exception retain]; [self didConnect]; } else { [self tryNextAddressWithRunLoopMode: [OFRunLoop currentRunLoop].currentMode]; } return; } if (_SOCKS5Host != nil) [self sendSOCKS5Request]; |
︙ | ︙ | |||
248 249 250 251 252 253 254 | if (_SOCKS5Host != nil) of_socket_address_set_port(&address, _SOCKS5Port); else of_socket_address_set_port(&address, _port); if (![_socket of_createSocketForAddress: &address errNo: &errNo]) { | | | 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 | if (_SOCKS5Host != nil) of_socket_address_set_port(&address, _SOCKS5Port); else of_socket_address_set_port(&address, _port); if (![_socket of_createSocketForAddress: &address errNo: &errNo]) { if (_socketAddressesIndex >= _socketAddresses.count) { _exception = [[OFConnectionFailedException alloc] initWithHost: _host port: _port socket: _socket errNo: errNo]; [self didConnect]; return; |
︙ | ︙ | |||
273 274 275 276 277 278 279 | * Additionally, on Wii, there is no getsockopt(), so it would not be * possible to get the error (or success) after connecting anyway. * * So for now, connecting is blocking on Wii and 3DS. * * FIXME: Use a different thread as a work around. */ | | | | | | | | 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 | * Additionally, on Wii, there is no getsockopt(), so it would not be * possible to get the error (or success) after connecting anyway. * * So for now, connecting is blocking on Wii and 3DS. * * FIXME: Use a different thread as a work around. */ _socket.blocking = true; #else _socket.blocking = false; #endif if (![_socket of_connectSocketToAddress: &address errNo: &errNo]) { #if !defined(OF_NINTENDO_3DS) && !defined(OF_WII) if (errNo == EINPROGRESS) { [OFRunLoop of_addAsyncConnectForTCPSocket: _socket mode: runLoopMode delegate: self]; return; } else { #endif [_socket of_closeSocket]; if (_socketAddressesIndex >= _socketAddresses.count) { _exception = [[OFConnectionFailedException alloc] initWithHost: _host port: _port socket: _socket errNo: errNo]; [self didConnect]; return; } [self tryNextAddressWithRunLoopMode: runLoopMode]; return; #if !defined(OF_NINTENDO_3DS) && !defined(OF_WII) } #endif } #if defined(OF_NINTENDO_3DS) || defined(OF_WII) _socket.blocking = false; #endif [self didConnect]; } - (void)resolver: (OFDNSResolver *)resolver didResolveDomainName: (OFString *)domainName socketAddresses: (OFData *)socketAddresses exception: (id)exception { if (exception != nil) { _exception = [exception retain]; [self didConnect]; return; } _socketAddresses = [socketAddresses copy]; [self tryNextAddressWithRunLoopMode: [OFRunLoop currentRunLoop].currentMode]; } - (void)startWithRunLoopMode: (of_run_loop_mode_t)runLoopMode { OFString *host; uint16_t port; if (_SOCKS5Host != nil) { if (_host.UTF8StringLength > 255) @throw [OFOutOfRangeException exception]; host = _SOCKS5Host; port = _SOCKS5Port; } else { host = _host; port = _port; |
︙ | ︙ | |||
375 376 377 378 379 380 381 | - (void)sendSOCKS5Request { OFData *data = [OFData dataWithItems: "\x05\x01\x00" count: 3]; _SOCKS5State = SOCKS5_STATE_SEND_AUTHENTICATION; [_socket asyncWriteData: data | | | | | 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 | - (void)sendSOCKS5Request { OFData *data = [OFData dataWithItems: "\x05\x01\x00" count: 3]; _SOCKS5State = SOCKS5_STATE_SEND_AUTHENTICATION; [_socket asyncWriteData: data runLoopMode: [OFRunLoop currentRunLoop].currentMode]; } - (bool)stream: (OFStream *)sock didReadIntoBuffer: (void *)buffer length: (size_t)length exception: (id)exception { of_run_loop_mode_t runLoopMode; unsigned char *SOCKSVersion; uint8_t hostLength; unsigned char port[2]; unsigned char *response, *addressLength; if (exception != nil) { _exception = [exception retain]; [self didConnect]; return false; } runLoopMode = [OFRunLoop currentRunLoop].currentMode; switch (_SOCKS5State) { case SOCKS5_STATE_READ_VERSION: SOCKSVersion = buffer; if (SOCKSVersion[0] != 5 || SOCKSVersion[1] != 0) { _exception = [[OFConnectionFailedException alloc] |
︙ | ︙ | |||
417 418 419 420 421 422 423 | [_request release]; _request = [[OFMutableData alloc] init]; [_request addItems: "\x05\x01\x00\x03" count: 4]; | | | | | 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 | [_request release]; _request = [[OFMutableData alloc] init]; [_request addItems: "\x05\x01\x00\x03" count: 4]; hostLength = (uint8_t)_host.UTF8StringLength; [_request addItem: &hostLength]; [_request addItems: _host.UTF8String count: hostLength]; port[0] = _port >> 8; port[1] = _port & 0xFF; [_request addItems: port count: 2]; _SOCKS5State = SOCKS5_STATE_SEND_REQUEST; [_socket asyncWriteData: _request runLoopMode: runLoopMode]; return false; case SOCKS5_STATE_READ_RESPONSE: response = buffer; |
︙ | ︙ | |||
531 532 533 534 535 536 537 | return false; default: assert(0); return false; } } | | | | 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 | return false; default: assert(0); return false; } } - (OFData *)stream: (OFStream *)sock didWriteData: (OFData *)data bytesWritten: (size_t)bytesWritten exception: (id)exception { of_run_loop_mode_t runLoopMode; if (exception != nil) { _exception = [exception retain]; [self didConnect]; return nil; } runLoopMode = [OFRunLoop currentRunLoop].currentMode; switch (_SOCKS5State) { case SOCKS5_STATE_SEND_AUTHENTICATION: _SOCKS5State = SOCKS5_STATE_READ_VERSION; [_socket asyncReadIntoBuffer: _buffer exactLength: 2 runLoopMode: runLoopMode]; |
︙ | ︙ | |||
577 578 579 580 581 582 583 | - (void)dealloc { [_exception release]; [super dealloc]; } | | | 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 | - (void)dealloc { [_exception release]; [super dealloc]; } - (void)socket: (OFTCPSocket *)sock didConnectToHost: (OFString *)host port: (uint16_t)port exception: (id)exception { _done = true; _exception = [exception retain]; } |
︙ | ︙ | |||
704 705 706 707 708 709 710 | { void *pool = objc_autoreleasePoolPush(); id <OFTCPSocketDelegate> delegate = [_delegate retain]; OFTCPSocket_ConnectDelegate *connectDelegate = [[[OFTCPSocket_ConnectDelegate alloc] init] autorelease]; OFRunLoop *runLoop = [OFRunLoop currentRunLoop]; | | | | 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 | { void *pool = objc_autoreleasePoolPush(); id <OFTCPSocketDelegate> delegate = [_delegate retain]; OFTCPSocket_ConnectDelegate *connectDelegate = [[[OFTCPSocket_ConnectDelegate alloc] init] autorelease]; OFRunLoop *runLoop = [OFRunLoop currentRunLoop]; self.delegate = connectDelegate; [self asyncConnectToHost: host port: port runLoopMode: connectRunLoopMode]; while (!connectDelegate->_done) [runLoop runMode: connectRunLoopMode beforeDate: nil]; /* Cleanup */ [runLoop runMode: connectRunLoopMode beforeDate: [OFDate date]]; if (connectDelegate->_exception != nil) @throw connectDelegate->_exception; self.delegate = delegate; objc_autoreleasePoolPop(pool); } - (void)asyncConnectToHost: (OFString *)host port: (uint16_t)port { |
︙ | ︙ |
Modified src/OFTarArchive.h from [12a3337977] to [c1cedd4497].
︙ | ︙ | |||
27 28 29 30 31 32 33 | /*! * @class OFTarArchive OFTarArchive.h ObjFW/OFTarArchive.h * * @brief A class for accessing and manipulating tar archives. */ @interface OFTarArchive: OFObject { | | | | 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 | /*! * @class OFTarArchive OFTarArchive.h ObjFW/OFTarArchive.h * * @brief A class for accessing and manipulating tar archives. */ @interface OFTarArchive: OFObject { OFStream *_stream; enum { OF_TAR_ARCHIVE_MODE_READ, OF_TAR_ARCHIVE_MODE_WRITE, OF_TAR_ARCHIVE_MODE_APPEND } _mode; of_string_encoding_t _encoding; OFStream *_Nullable _lastReturnedStream; } /*! * @brief The encoding to use for the archive. Defaults to UTF-8. */ @property (nonatomic) of_string_encoding_t encoding; |
︙ | ︙ | |||
63 64 65 66 67 68 69 | * @param stream A stream from which the tar archive will be read. * For append mode, this needs to be an OFSeekableStream. * @param mode The mode for the tar file. Valid modes are "r" for reading, * "w" for creating a new file and "a" for appending to an existing * archive. * @return A new, autoreleased OFTarArchive */ | | | 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 | * @param stream A stream from which the tar archive will be read. * For append mode, this needs to be an OFSeekableStream. * @param mode The mode for the tar file. Valid modes are "r" for reading, * "w" for creating a new file and "a" for appending to an existing * archive. * @return A new, autoreleased OFTarArchive */ + (instancetype)archiveWithStream: (OFStream *)stream mode: (OFString *)mode; #ifdef OF_HAVE_FILES /*! * @brief Creates a new OFTarArchive object with the specified file. * * @param path The path to the tar archive |
︙ | ︙ | |||
93 94 95 96 97 98 99 | * @param stream A stream from which the tar archive will be read. * For append mode, this needs to be an OFSeekableStream. * @param mode The mode for the tar file. Valid modes are "r" for reading, * "w" for creating a new file and "a" for appending to an existing * archive. * @return An initialized OFTarArchive */ | | | 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 | * @param stream A stream from which the tar archive will be read. * For append mode, this needs to be an OFSeekableStream. * @param mode The mode for the tar file. Valid modes are "r" for reading, * "w" for creating a new file and "a" for appending to an existing * archive. * @return An initialized OFTarArchive */ - (instancetype)initWithStream: (OFStream *)stream mode: (OFString *)mode OF_DESIGNATED_INITIALIZER; #ifdef OF_HAVE_FILES /*! * @brief Initializes an already allocated OFTarArchive object with the * specified file. * |
︙ | ︙ |
Modified src/OFTarArchive.m from [cfc88dc079] to [c1512afd3b].
︙ | ︙ | |||
16 17 18 19 20 21 22 | */ #include "config.h" #import "OFTarArchive.h" #import "OFTarArchiveEntry.h" #import "OFTarArchiveEntry+Private.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 89 90 91 92 | */ #include "config.h" #import "OFTarArchive.h" #import "OFTarArchiveEntry.h" #import "OFTarArchiveEntry+Private.h" #import "OFDate.h" #import "OFSeekableStream.h" #import "OFStream.h" #ifdef OF_HAVE_FILES # import "OFFile.h" #endif #import "OFInvalidArgumentException.h" #import "OFInvalidFormatException.h" #import "OFNotOpenException.h" #import "OFOutOfRangeException.h" #import "OFTruncatedDataException.h" #import "OFWriteFailedException.h" @interface OFTarArchive_FileReadStream: 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 OFTarArchive_FileWriteStream: OFStream <OFReadyForWritingObserving> { OFTarArchiveEntry *_entry; OFStream *_stream; uint64_t _toWrite; } - (instancetype)of_initWithStream: (OFStream *)stream entry: (OFTarArchiveEntry *)entry; @end @implementation OFTarArchive: OFObject @synthesize encoding = _encoding; + (instancetype)archiveWithStream: (OFStream *)stream mode: (OFString *)mode { return [[[self alloc] initWithStream: stream mode: mode] autorelease]; } #ifdef OF_HAVE_FILES + (instancetype)archiveWithPath: (OFString *)path mode: (OFString *)mode { return [[[self alloc] initWithPath: path mode: mode] autorelease]; } #endif - (instancetype)init { OF_INVALID_INIT_METHOD } - (instancetype)initWithStream: (OFStream *)stream mode: (OFString *)mode { self = [super init]; @try { _stream = [stream retain]; |
︙ | ︙ | |||
105 106 107 108 109 110 111 | uint32_t u32[1024 / sizeof(uint32_t)]; } buffer; bool empty = true; if (![_stream isKindOfClass: [OFSeekableStream class]]) @throw [OFInvalidArgumentException exception]; | | | | | | | 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 | uint32_t u32[1024 / sizeof(uint32_t)]; } buffer; bool empty = true; if (![_stream isKindOfClass: [OFSeekableStream class]]) @throw [OFInvalidArgumentException exception]; [(OFSeekableStream *)stream seekToOffset: -1024 whence: SEEK_END]; [stream readIntoBuffer: buffer.c exactLength: 1024]; for (size_t i = 0; i < 1024 / sizeof(uint32_t); i++) if (buffer.u32[i] != 0) empty = false; if (!empty) @throw [OFInvalidFormatException exception]; [(OFSeekableStream *)stream seekToOffset: -1024 whence: SEEK_END]; } _encoding = OF_STRING_ENCODING_UTF_8; } @catch (id e) { [self release]; @throw e; } |
︙ | ︙ | |||
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 188 189 190 191 192 | uint32_t u32[512 / sizeof(uint32_t)]; } buffer; bool empty = true; if (_mode != OF_TAR_ARCHIVE_MODE_READ) @throw [OFInvalidArgumentException exception]; [(OFTarArchive_FileReadStream *)_lastReturnedStream of_skip]; [_lastReturnedStream close]; [_lastReturnedStream release]; _lastReturnedStream = nil; if (_stream.atEndOfStream) return nil; [_stream readIntoBuffer: buffer.c exactLength: 512]; for (size_t i = 0; i < 512 / sizeof(uint32_t); i++) if (buffer.u32[i] != 0) |
︙ | ︙ | |||
218 219 220 221 222 223 224 | { if (_mode != OF_TAR_ARCHIVE_MODE_READ) @throw [OFInvalidArgumentException exception]; if (_lastReturnedStream == nil) @throw [OFInvalidArgumentException exception]; | > | | 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 | { if (_mode != OF_TAR_ARCHIVE_MODE_READ) @throw [OFInvalidArgumentException exception]; if (_lastReturnedStream == nil) @throw [OFInvalidArgumentException exception]; return [[(OFTarArchive_FileReadStream *)_lastReturnedStream retain] autorelease]; } - (OFStream <OFReadyForWritingObserving> *) streamForWritingEntry: (OFTarArchiveEntry *)entry { void *pool; |
︙ | ︙ | |||
245 246 247 248 249 250 251 | _lastReturnedStream = [[OFTarArchive_FileWriteStream alloc] of_initWithStream: _stream entry: entry]; objc_autoreleasePoolPop(pool); | > | | 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 | _lastReturnedStream = [[OFTarArchive_FileWriteStream alloc] of_initWithStream: _stream entry: entry]; objc_autoreleasePoolPop(pool); return [[(OFTarArchive_FileWriteStream *)_lastReturnedStream retain] autorelease]; } - (void)close { if (_stream == nil) return; |
︙ | ︙ | |||
279 280 281 282 283 284 285 | entry: (OFTarArchiveEntry *)entry { self = [super init]; @try { _entry = [entry copy]; _stream = [stream retain]; | | | 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 | entry: (OFTarArchiveEntry *)entry { self = [super init]; @try { _entry = [entry copy]; _stream = [stream retain]; _toRead = entry.size; } @catch (id e) { [self release]; @throw e; } return self; } |
︙ | ︙ | |||
337 338 339 340 341 342 343 | @throw [OFNotOpenException exceptionWithObject: self]; return _atEndOfStream; } - (bool)hasDataInReadBuffer { | | > | | 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 | @throw [OFNotOpenException exceptionWithObject: self]; return _atEndOfStream; } - (bool)hasDataInReadBuffer { return (super.hasDataInReadBuffer || _stream.hasDataInReadBuffer); } - (int)fileDescriptorForReading { return ((id <OFReadyForReadingObserving>)_stream) .fileDescriptorForReading; } - (void)close { [self of_skip]; [_stream release]; |
︙ | ︙ | |||
364 365 366 367 368 369 370 | if (_stream == nil || _skipped) return; if ([_stream isKindOfClass: [OFSeekableStream class]] && _toRead <= INT64_MAX && (of_offset_t)_toRead == (int64_t)_toRead) { uint64_t size; | | | | > | | | | | | 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 | if (_stream == nil || _skipped) return; if ([_stream isKindOfClass: [OFSeekableStream class]] && _toRead <= INT64_MAX && (of_offset_t)_toRead == (int64_t)_toRead) { uint64_t size; [(OFSeekableStream *)_stream seekToOffset: (of_offset_t)_toRead whence: SEEK_CUR]; _toRead = 0; size = _entry.size; if (size % 512 != 0) [(OFSeekableStream *)_stream seekToOffset: 512 - (size % 512) whence: SEEK_CUR]; } else { char buffer[512]; uint64_t size; while (_toRead >= 512) { [_stream readIntoBuffer: buffer exactLength: 512]; _toRead -= 512; } if (_toRead > 0) { [_stream readIntoBuffer: buffer exactLength: (size_t)_toRead]; _toRead = 0; } size = _entry.size; if (size % 512 != 0) [_stream readIntoBuffer: buffer exactLength: (size_t)(512 - (size % 512))]; } _skipped = true; } @end @implementation OFTarArchive_FileWriteStream - (instancetype)of_initWithStream: (OFStream *)stream entry: (OFTarArchiveEntry *)entry { self = [super init]; @try { _entry = [entry copy]; _stream = [stream retain]; _toWrite = entry.size; } @catch (id e) { [self release]; @throw e; } return self; } |
︙ | ︙ | |||
443 444 445 446 447 448 449 | if ((uint64_t)length > _toWrite) @throw [OFOutOfRangeException exception]; @try { bytesWritten = [_stream writeBuffer: buffer length: length]; } @catch (OFWriteFailedException *e) { | | > | | | | | 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 | if ((uint64_t)length > _toWrite) @throw [OFOutOfRangeException exception]; @try { bytesWritten = [_stream writeBuffer: buffer length: length]; } @catch (OFWriteFailedException *e) { _toWrite -= e.bytesWritten; @throw e; } _toWrite -= bytesWritten; return bytesWritten; } - (bool)lowlevelIsAtEndOfStream { if (_stream == nil) @throw [OFNotOpenException exceptionWithObject: self]; return (_toWrite == 0); } - (int)fileDescriptorForWriting { return ((id <OFReadyForWritingObserving>)_stream) .fileDescriptorForWriting; } - (void)close { if (_stream == nil) return; uint64_t remainder = 512 - _entry.size % 512; if (_toWrite > 0) @throw [OFTruncatedDataException exception]; if (remainder != 512) { bool wasWriteBuffered = _stream.writeBuffered; [_stream setWriteBuffered: true]; while (remainder--) [_stream writeInt8: 0]; [_stream flushWriteBuffer]; _stream.writeBuffered = wasWriteBuffered; } [_stream release]; _stream = nil; [super close]; } @end |
Modified src/OFTarArchiveEntry.m from [f5aca25b8d] to [cfb25a345f].
︙ | ︙ | |||
61 62 63 64 65 66 67 | if (length == 0) return 0; if (buffer[0] == 0x80) { for (size_t i = 1; i < length; i++) value = (value << 8) | buffer[i]; } else | | | | 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 | if (length == 0) return 0; if (buffer[0] == 0x80) { for (size_t i = 1; i < length; i++) value = (value << 8) | buffer[i]; } else value = stringFromBuffer(buffer, length, OF_STRING_ENCODING_ASCII).octalValue; if (value > max) @throw [OFOutOfRangeException exception]; return value; } |
︙ | ︙ | |||
106 107 108 109 110 111 112 | _modificationDate = [[OFDate alloc] initWithTimeIntervalSince1970: (of_time_interval_t)octalValueFromBuffer( header + 136, 12, UINTMAX_MAX)]; _type = header[156]; targetFileName = stringFromBuffer(header + 157, 100, encoding); | | | | 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 | _modificationDate = [[OFDate alloc] initWithTimeIntervalSince1970: (of_time_interval_t)octalValueFromBuffer( header + 136, 12, UINTMAX_MAX)]; _type = header[156]; targetFileName = stringFromBuffer(header + 157, 100, encoding); if (targetFileName.length > 0) _targetFileName = [targetFileName copy]; if (_type == '\0') _type = OF_TAR_ARCHIVE_ENTRY_TYPE_FILE; if (memcmp(header + 257, "ustar\0" "00", 8) == 0) { OFString *prefix; _owner = [stringFromBuffer(header + 265, 32, encoding) copy]; _group = [stringFromBuffer(header + 297, 32, encoding) copy]; _deviceMajor = (uint32_t)octalValueFromBuffer( header + 329, 8, UINT32_MAX); _deviceMinor = (uint32_t)octalValueFromBuffer( header + 337, 8, UINT32_MAX); prefix = stringFromBuffer(header + 345, 155, encoding); if (prefix.length > 0) { OFString *fileName = [OFString stringWithFormat: @"%@/%@", prefix, _fileName]; [_fileName release]; _fileName = [fileName copy]; } } |
︙ | ︙ | |||
276 277 278 279 280 281 282 | @"\tType = %u\n" @"\tTarget file name = %@\n" @"\tOwner = %@\n" @"\tGroup = %@\n" @"\tDevice major = %" PRIu32 @"\n" @"\tDevice minor = %" PRIu32 @"\n" @">", | | | < | 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 | @"\tType = %u\n" @"\tTarget file name = %@\n" @"\tOwner = %@\n" @"\tGroup = %@\n" @"\tDevice major = %" PRIu32 @"\n" @"\tDevice minor = %" PRIu32 @"\n" @">", self.class, _fileName, _mode, _UID, _GID, _size, _modificationDate, _type, _targetFileName, _owner, _group, _deviceMajor, _deviceMinor]; [ret retain]; objc_autoreleasePoolPop(pool); return [ret autorelease]; } |
︙ | ︙ | |||
307 308 309 310 311 312 313 | OF_STRING_ENCODING_ASCII); stringToBuffer(buffer + 116, [OFString stringWithFormat: @"%06" PRIo16 " ", _GID], 8, OF_STRING_ENCODING_ASCII); stringToBuffer(buffer + 124, [OFString stringWithFormat: @"%011" PRIo64 " ", _size], 12, OF_STRING_ENCODING_ASCII); | | | 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 | OF_STRING_ENCODING_ASCII); stringToBuffer(buffer + 116, [OFString stringWithFormat: @"%06" PRIo16 " ", _GID], 8, OF_STRING_ENCODING_ASCII); stringToBuffer(buffer + 124, [OFString stringWithFormat: @"%011" PRIo64 " ", _size], 12, OF_STRING_ENCODING_ASCII); modificationDate = _modificationDate.timeIntervalSince1970; stringToBuffer(buffer + 136, [OFString stringWithFormat: @"%011" PRIo64 " ", modificationDate], 12, OF_STRING_ENCODING_ASCII); /* * During checksumming, the checksum field is expected to be set to 8 * spaces. |
︙ | ︙ |
Modified src/OFThread.m from [8c84f260e2] to [5653a804be].
︙ | ︙ | |||
118 119 120 121 122 123 124 | callMain(id object) { OFThread *thread = (OFThread *)object; OFString *name; if (!of_tlskey_set(threadSelfKey, thread)) @throw [OFInitializationFailedException | | | | 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 | callMain(id object) { OFThread *thread = (OFThread *)object; OFString *name; if (!of_tlskey_set(threadSelfKey, thread)) @throw [OFInitializationFailedException exceptionWithClass: thread.class]; thread->_pool = objc_autoreleasePoolPush(); name = thread.name; if (name != nil) of_thread_set_name( [name cStringWithEncoding: [OFLocale encoding]]); else of_thread_set_name(object_getClassName(thread)); /* |
︙ | ︙ | |||
294 295 296 297 298 299 300 | usleep((unsigned int)lrint( (timeInterval - trunc(timeInterval)) * 1000000)); #endif } + (void)sleepUntilDate: (OFDate *)date { | | | 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 | usleep((unsigned int)lrint( (timeInterval - trunc(timeInterval)) * 1000000)); #endif } + (void)sleepUntilDate: (OFDate *)date { [self sleepForTimeInterval: date.timeIntervalSinceNow]; } + (void)yield { #ifdef OF_HAVE_SCHED_YIELD sched_yield(); #else |
︙ | ︙ | |||
341 342 343 344 345 346 347 | [thread release]; of_thread_exit(); } + (void)setName: (OFString *)name { | | | | | | 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 | [thread release]; of_thread_exit(); } + (void)setName: (OFString *)name { [OFThread currentThread].name = name; if (name != nil) of_thread_set_name( [name cStringWithEncoding: [OFLocale encoding]]); else of_thread_set_name(class_getName(self.class)); } + (OFString *)name { return [OFThread currentThread].name; } + (void)of_createMainThread { mainThread = [[OFThread alloc] init]; mainThread->_thread = of_thread_current(); if (!of_tlskey_set(threadSelfKey, mainThread)) @throw [OFInitializationFailedException exceptionWithClass: self]; } - (instancetype)init { self = [super init]; @try { if (!of_thread_attr_init(&_attr)) @throw [OFInitializationFailedException exceptionWithClass: self.class]; } @catch (id e) { [self release]; @throw e; } return self; } |
︙ | ︙ |
Modified src/OFThreadPool.m from [751d46c26d] to [ff320a5fa0].
︙ | ︙ | |||
165 166 167 168 169 170 171 | of_list_object_t *listObject; if (_terminate) { objc_autoreleasePoolPop(pool); return nil; } | | | | 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 | of_list_object_t *listObject; if (_terminate) { objc_autoreleasePoolPop(pool); return nil; } listObject = _queue.firstListObject; while (listObject == NULL) { [_queueCondition wait]; if (_terminate) { objc_autoreleasePoolPop(pool); return nil; } listObject = _queue.firstListObject; } job = [[listObject->object retain] autorelease]; [_queue removeListObject: listObject]; } @finally { [_queueCondition unlock]; } |
︙ | ︙ |
Modified src/OFTimer.m from [b2973aea61] to [3990e4e136].
︙ | ︙ | |||
541 542 543 544 545 546 547 | id object3 = [[_object3 retain] autorelease]; id object4 = [[_object4 retain] autorelease]; OF_ENSURE(_arguments <= 4); if (_repeats && _valid) { int64_t missedIntervals = | | | | | 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 | id object3 = [[_object3 retain] autorelease]; id object4 = [[_object4 retain] autorelease]; OF_ENSURE(_arguments <= 4); if (_repeats && _valid) { int64_t missedIntervals = -_fireDate.timeIntervalSinceNow / _interval; of_time_interval_t newFireDate; OFRunLoop *runLoop; /* In case the clock was changed backwards */ if (missedIntervals < 0) missedIntervals = 0; newFireDate = _fireDate.timeIntervalSince1970 + (missedIntervals + 1) * _interval; [_fireDate release]; _fireDate = [[OFDate alloc] initWithTimeIntervalSince1970: newFireDate]; runLoop = [OFRunLoop currentRunLoop]; [runLoop addTimer: self forMode: runLoop.currentMode]; } else [self invalidate]; #ifdef OF_HAVE_BLOCKS if (_block != NULL) _block(self); else { |
︙ | ︙ |
Modified src/OFUDPSocket.h from [3a88d52639] to [55c0fec4d8].
︙ | ︙ | |||
72 73 74 75 76 77 78 | * @param buffer The buffer the packet has been written to * @param length The length of the packet * @param sender The address of the sender of the packet * @param exception An exception that occurred while receiving, or nil on * success * @return A bool whether the same block should be used for the next receive */ | | | | 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 | * @param buffer The buffer the packet has been written to * @param length The length of the packet * @param sender The address of the sender of the packet * @param exception An exception that occurred while receiving, or nil on * success * @return A bool whether the same block should be used for the next receive */ - (bool)socket: (OFUDPSocket *)socket didReceiveIntoBuffer: (void *)buffer length: (size_t)length sender: (const of_socket_address_t *_Nonnull)sender exception: (nullable id)exception; /*! * @brief This which is called when a packet has been sent. * * @param socket The UDP socket which sent a packet * @param data The data which was sent * @param receiver The receiver for the UDP packet * @param exception An exception that occurred while sending, or nil on success * @return The data to repeat the send with or nil if it should not repeat */ - (nullable OFData *)socket: (OFUDPSocket *)socket didSendData: (OFData *)data receiver: (const of_socket_address_t *_Nonnull)receiver exception: (nullable id)exception; @end /*! * @class OFUDPSocket OFUDPSocket.h ObjFW/OFUDPSocket.h |
︙ | ︙ |
Modified src/OFURL.m from [614bfb9897] to [3539c64da7].
︙ | ︙ | |||
68 69 70 71 72 73 74 | # if defined(OF_WINDOWS) || defined(OF_MSDOS) path = [path stringByReplacingOccurrencesOfString: @"\\" withString: @"/"]; path = [path stringByPrependingString: @"/"]; return path; # elif defined(OF_AMIGAOS) | | | | 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 | # if defined(OF_WINDOWS) || defined(OF_MSDOS) path = [path stringByReplacingOccurrencesOfString: @"\\" withString: @"/"]; path = [path stringByPrependingString: @"/"]; return path; # elif defined(OF_AMIGAOS) OFArray OF_GENERIC(OFString *) *components = path.pathComponents; OFMutableString *ret = [OFMutableString string]; for (OFString *component in components) { if (component.length == 0) continue; if ([component isEqual: @"/"]) [ret appendString: @"/.."]; else { [ret appendString: @"/"]; [ret appendString: component]; |
︙ | ︙ | |||
97 98 99 100 101 102 103 | # endif } static OFString * URLPathToPath(OFString *path) { # if defined(OF_WINDOWS) || defined(OF_MSDOS) | | | | | | 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 | # endif } static OFString * URLPathToPath(OFString *path) { # if defined(OF_WINDOWS) || defined(OF_MSDOS) path = [path substringWithRange: of_range(1, path.length - 1)]; path = [path stringByReplacingOccurrencesOfString: @"/" withString: @"\\"]; return path; # elif defined(OF_AMIGAOS) OFMutableArray OF_GENERIC(OFString *) *components; size_t count; path = [path substringWithRange: of_range(1, path.length - 1)]; components = [[[path componentsSeparatedByString: @"/"] mutableCopy] autorelease]; count = components.count; for (size_t i = 0; i < count; i++) { OFString *component = [components objectAtIndex: i]; if ([component isEqual: @"."]) { [components removeObjectAtIndex: i]; count--; i--; continue; } if ([component isEqual: @".."]) [components replaceObjectAtIndex: i withObject: @"/"]; } return [OFString pathWithComponents: components]; # elif defined(OF_NINTENDO_3DS) || defined(OF_WII) return [path substringWithRange: of_range(1, path.length - 1)]; # else return path; # endif } #endif @interface OFCharacterSet_invertedSetWithPercent: OFCharacterSet |
︙ | ︙ | |||
469 470 471 472 473 474 475 | self = [super init]; @try { void *pool = objc_autoreleasePoolPush(); char *tmp, *tmp2; | | | | 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 | self = [super init]; @try { void *pool = objc_autoreleasePoolPush(); char *tmp, *tmp2; if ((UTF8String2 = of_strdup(string.UTF8String)) == NULL) @throw [OFOutOfMemoryException exceptionWithRequestedSize: string.UTF8StringLength]; UTF8String = UTF8String2; if ((tmp = strchr(UTF8String, ':')) == NULL) @throw [OFInvalidFormatException exception]; if (strncmp(tmp, "://", 3) != 0) |
︙ | ︙ | |||
538 539 540 541 542 543 544 | tmp2++; _URLEncodedHost = [[OFString alloc] initWithUTF8String: UTF8String]; portString = [OFString stringWithUTF8String: tmp2]; | | | | 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 | tmp2++; _URLEncodedHost = [[OFString alloc] initWithUTF8String: UTF8String]; portString = [OFString stringWithUTF8String: tmp2]; if (portString.decimalValue > 65535) @throw [OFInvalidFormatException exception]; _port = [[OFNumber alloc] initWithUInt16: (uint16_t)portString.decimalValue]; } else _URLEncodedHost = [[OFString alloc] initWithUTF8String: UTF8String]; of_url_verify_escaped(_URLEncodedHost, [OFCharacterSet URLHostAllowedCharacterSet]); |
︙ | ︙ | |||
614 615 616 617 618 619 620 | _URLEncodedScheme = [URL->_URLEncodedScheme copy]; _URLEncodedHost = [URL->_URLEncodedHost copy]; _port = [URL->_port copy]; _URLEncodedUser = [URL->_URLEncodedUser copy]; _URLEncodedPassword = [URL->_URLEncodedPassword copy]; | | | | 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 | _URLEncodedScheme = [URL->_URLEncodedScheme copy]; _URLEncodedHost = [URL->_URLEncodedHost copy]; _port = [URL->_port copy]; _URLEncodedUser = [URL->_URLEncodedUser copy]; _URLEncodedPassword = [URL->_URLEncodedPassword copy]; if ((UTF8String2 = of_strdup(string.UTF8String)) == NULL) @throw [OFOutOfMemoryException exceptionWithRequestedSize: string.UTF8StringLength]; UTF8String = UTF8String2; if ((tmp = strchr(UTF8String, '#')) != NULL) { *tmp = '\0'; _URLEncodedFragment = [[OFString alloc] initWithUTF8String: tmp + 1]; |
︙ | ︙ | |||
665 666 667 668 669 670 671 | options: OF_STRING_SEARCH_BACKWARDS]; if (range.location == OF_NOT_FOUND) @throw [OFInvalidFormatException exception]; range.location++; | | | 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 | options: OF_STRING_SEARCH_BACKWARDS]; if (range.location == OF_NOT_FOUND) @throw [OFInvalidFormatException exception]; range.location++; range.length = path.length - range.location; [path replaceCharactersInRange: range withString: relativePath]; [path makeImmutable]; _URLEncodedPath = [path copy]; } |
︙ | ︙ | |||
730 731 732 733 734 735 736 | isDirectory: (bool)isDirectory { self = [super init]; @try { void *pool = objc_autoreleasePoolPush(); | | | | | | 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 | isDirectory: (bool)isDirectory { self = [super init]; @try { void *pool = objc_autoreleasePoolPush(); if (!path.absolutePath) { OFString *currentDirectoryPath = [OFFileManager defaultManager].currentDirectoryPath; path = [currentDirectoryPath stringByAppendingPathComponent: path]; path = path.stringByStandardizingPath; } path = pathToURLPath(path); if (isDirectory && ![path hasSuffix: @"/"]) path = [path stringByAppendingString: @"/"]; |
︙ | ︙ | |||
765 766 767 768 769 770 771 | - (instancetype)initWithSerialization: (OFXMLElement *)element { void *pool = objc_autoreleasePoolPush(); OFString *stringValue; @try { | | | | | 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 | - (instancetype)initWithSerialization: (OFXMLElement *)element { void *pool = objc_autoreleasePoolPush(); OFString *stringValue; @try { if (![element.name isEqual: self.className] || ![element.namespace isEqual: OF_SERIALIZATION_NS]) @throw [OFInvalidArgumentException exception]; stringValue = element.stringValue; } @catch (id e) { [self release]; @throw e; } self = [self initWithString: stringValue]; |
︙ | ︙ | |||
841 842 843 844 845 846 847 | - (uint32_t)hash { uint32_t hash; OF_HASH_INIT(hash); | | | | | | | | | | | | | | | | | < | | | | | 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 | - (uint32_t)hash { uint32_t hash; OF_HASH_INIT(hash); OF_HASH_ADD_HASH(hash, _URLEncodedScheme.hash); OF_HASH_ADD_HASH(hash, _URLEncodedHost.hash); OF_HASH_ADD_HASH(hash, _port.hash); OF_HASH_ADD_HASH(hash, _URLEncodedUser.hash); OF_HASH_ADD_HASH(hash, _URLEncodedPassword.hash); OF_HASH_ADD_HASH(hash, _URLEncodedPath.hash); OF_HASH_ADD_HASH(hash, _URLEncodedQuery.hash); OF_HASH_ADD_HASH(hash, _URLEncodedFragment.hash); OF_HASH_FINALIZE(hash); return hash; } - (OFString *)scheme { return _URLEncodedScheme.stringByURLDecoding; } - (OFString *)URLEncodedScheme { return _URLEncodedScheme; } - (OFString *)host { return _URLEncodedHost.stringByURLDecoding; } - (OFString *)URLEncodedHost { return _URLEncodedHost; } - (OFNumber *)port { return _port; } - (OFString *)user { return _URLEncodedUser.stringByURLDecoding; } - (OFString *)URLEncodedUser { return _URLEncodedUser; } - (OFString *)password { return _URLEncodedPassword.stringByURLDecoding; } - (OFString *)URLEncodedPassword { return _URLEncodedPassword; } - (OFString *)path { return _URLEncodedPath.stringByURLDecoding; } - (OFString *)URLEncodedPath { return _URLEncodedPath; } - (OFArray *)pathComponents { return [self.path componentsSeparatedByString: @"/"]; } - (OFString *)lastPathComponent { void *pool = objc_autoreleasePoolPush(); OFString *path = self.path; const char *UTF8String, *lastComponent; size_t length; OFString *ret; if (path == nil) { objc_autoreleasePoolPop(pool); return nil; } if ([path isEqual: @"/"]) { objc_autoreleasePoolPop(pool); return @""; } if ([path hasSuffix: @"/"]) path = [path substringWithRange: of_range(0, path.length - 1)]; UTF8String = lastComponent = path.UTF8String; length = path.UTF8StringLength; for (size_t i = 1; i <= length; i++) { if (UTF8String[length - i] == '/') { lastComponent = UTF8String + (length - i) + 1; break; } } ret = [[OFString alloc] initWithUTF8String: lastComponent length: length - (lastComponent - UTF8String)]; objc_autoreleasePoolPop(pool); return [ret autorelease]; } - (OFString *)query { return _URLEncodedQuery.stringByURLDecoding; } - (OFString *)URLEncodedQuery { return _URLEncodedQuery; } - (OFString *)fragment { return _URLEncodedFragment.stringByURLDecoding; } - (OFString *)URLEncodedFragment { return _URLEncodedFragment; } |
︙ | ︙ | |||
1051 1052 1053 1054 1055 1056 1057 | if (![_URLEncodedScheme isEqual: @"file"]) @throw [OFInvalidArgumentException exception]; if (![_URLEncodedPath hasPrefix: @"/"]) @throw [OFInvalidFormatException exception]; | | | < | | | | | | | | | 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 | if (![_URLEncodedScheme isEqual: @"file"]) @throw [OFInvalidArgumentException exception]; if (![_URLEncodedPath hasPrefix: @"/"]) @throw [OFInvalidFormatException exception]; path = self.path; if ([path hasSuffix: @"/"]) path = [path substringWithRange: of_range(0, path.length - 1)]; path = URLPathToPath(path); [path retain]; objc_autoreleasePoolPop(pool); return [path autorelease]; } #endif - (OFMutableURL *)of_URLByAppendingPathComponent: (OFString *)component { OFMutableURL *ret = [[self mutableCopy] autorelease]; void *pool; OFMutableString *URLEncodedPath; if ([component hasPrefix: @"/"]) { ret.path = component; return ret; } pool = objc_autoreleasePoolPush(); URLEncodedPath = [[self.URLEncodedPath mutableCopy] autorelease]; if (![URLEncodedPath hasSuffix: @"/"]) [URLEncodedPath appendString: @"/"]; [URLEncodedPath appendString: [component stringByURLEncodingWithAllowedCharacters: [OFCharacterSet URLPathAllowedCharacterSet]]]; ret.URLEncodedPath = URLEncodedPath; objc_autoreleasePoolPop(pool); return ret; } - (OFURL *)URLByAppendingPathComponent: (OFString *)component { OFMutableURL *ret = [self of_URLByAppendingPathComponent: component]; #ifdef OF_HAVE_FILES if ([ret.scheme isEqual: @"file"]) { void *pool = objc_autoreleasePoolPush(); if ([[OFFileManager defaultManager] directoryExistsAtURL: ret]) ret.URLEncodedPath = [ret.URLEncodedPath stringByAppendingString: @"/"]; objc_autoreleasePoolPop(pool); } #endif [ret makeImmutable]; return ret; } - (OFURL *)URLByAppendingPathComponent: (OFString *)component isDirectory: (bool)isDirectory { OFMutableURL *ret = [self of_URLByAppendingPathComponent: component]; if (isDirectory) { void *pool = objc_autoreleasePoolPush(); ret.URLEncodedPath = [ret.URLEncodedPath stringByAppendingString: @"/"]; objc_autoreleasePoolPop(pool); } [ret makeImmutable]; return ret; |
︙ | ︙ | |||
1148 1149 1150 1151 1152 1153 1154 | return URL; } - (OFString *)description { return [OFString stringWithFormat: @"<%@: %@>", | | | | | 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 | return URL; } - (OFString *)description { return [OFString stringWithFormat: @"<%@: %@>", self.class, self.string]; } - (OFXMLElement *)XMLElementBySerializing { void *pool = objc_autoreleasePoolPush(); OFXMLElement *element; element = [OFXMLElement elementWithName: self.className namespace: OF_SERIALIZATION_NS stringValue: self.string]; [element retain]; objc_autoreleasePoolPop(pool); return [element autorelease]; } @end |
Modified src/OFURLHandler.m from [e9b99833f4] to [097dcd213e].
︙ | ︙ | |||
139 140 141 142 143 144 145 | + (OF_KINDOF(OFURLHandler *))handlerForURL: (OFURL *)URL { #ifdef OF_HAVE_THREADS [mutex lock]; @try { #endif | | | 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 | + (OF_KINDOF(OFURLHandler *))handlerForURL: (OFURL *)URL { #ifdef OF_HAVE_THREADS [mutex lock]; @try { #endif return [handlers objectForKey: URL.scheme]; #ifdef OF_HAVE_THREADS } @finally { [mutex unlock]; } #endif } |
︙ | ︙ |
Modified src/OFURLHandler_file.m from [111f6cb51f] to [701f79185c].
︙ | ︙ | |||
134 135 136 137 138 139 140 | } #endif static int of_stat(OFString *path, of_stat_t *buffer) { #if defined(OF_WINDOWS) | | | 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 | } #endif static int of_stat(OFString *path, of_stat_t *buffer) { #if defined(OF_WINDOWS) return _wstat64(path.UTF16String, buffer); #elif defined(OF_AMIGAOS) BPTR lock; # ifdef OF_AMIGAOS4 struct ExamineData *ed; # else struct FileInfoBlock fib; # endif |
︙ | ︙ | |||
340 341 342 343 344 345 346 | } static void setSymbolicLinkDestinationAttribute(of_mutable_file_attributes_t attributes, of_stat_t *s, OFURL *URL) { #ifdef OF_FILE_MANAGER_SUPPORTS_SYMLINKS | | | 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 | } static void setSymbolicLinkDestinationAttribute(of_mutable_file_attributes_t attributes, of_stat_t *s, OFURL *URL) { #ifdef OF_FILE_MANAGER_SUPPORTS_SYMLINKS OFString *path = URL.fileSystemRepresentation; # ifndef OF_WINDOWS if (S_ISLNK(s->st_mode)) { of_string_encoding_t encoding = [OFLocale encoding]; char destinationC[PATH_MAX]; ssize_t length; OFString *destination; |
︙ | ︙ | |||
370 371 372 373 374 375 376 | [attributes setObject: destination forKey: key]; } # else WIN32_FIND_DATAW data; if (func_CreateSymbolicLinkW != NULL && | | | | 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 | [attributes setObject: destination forKey: key]; } # else WIN32_FIND_DATAW data; if (func_CreateSymbolicLinkW != NULL && FindFirstFileW(path.UTF16String, &data) && (data.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) && data.dwReserved0 == IO_REPARSE_TAG_SYMLINK) { HANDLE handle; OFString *destination; 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]; |
︙ | ︙ | |||
494 495 496 497 498 499 500 | } - (OFStream *)openItemAtURL: (OFURL *)URL mode: (OFString *)mode { void *pool = objc_autoreleasePoolPush(); OFFile *file = [[OFFile alloc] | | | | 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 | } - (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) |
︙ | ︙ | |||
547 548 549 550 551 552 553 | } - (void)of_setPOSIXPermissions: (OFNumber *)permissions ofItemAtURL: (OFURL *)URL attributes: (of_file_attributes_t)attributes { #ifdef OF_FILE_MANAGER_SUPPORTS_PERMISSIONS | | | | | | 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 | } - (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]; |
︙ | ︙ | |||
642 643 644 645 646 647 648 | OFEnumerator *objectEnumerator; of_file_attribute_key_t key; id object; if (URL == nil) @throw [OFInvalidArgumentException exception]; | | | 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 | 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) { |
︙ | ︙ | |||
682 683 684 685 686 687 688 | void *pool = objc_autoreleasePoolPush(); of_stat_t s; bool ret; if (URL == nil) @throw [OFInvalidArgumentException exception]; | | | | | | | | | 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 | 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) 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) 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( |
︙ | ︙ | |||
790 791 792 793 794 795 796 | OFMutableArray *files = [OFMutableArray array]; void *pool = objc_autoreleasePoolPush(); OFString *path; if (URL == nil) @throw [OFInvalidArgumentException exception]; | | | | | 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 | 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 |
︙ | ︙ | |||
1004 1005 1006 1007 1008 1009 1010 | void *pool = objc_autoreleasePoolPush(); OFString *path; of_stat_t s; if (URL == nil) @throw [OFInvalidArgumentException exception]; | | | | 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 | 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; |
︙ | ︙ | |||
1047 1048 1049 1050 1051 1052 1053 | objc_autoreleasePoolPop(pool2); } #ifndef OF_AMIGAOS # ifndef OF_WINDOWS if (rmdir([path cStringWithEncoding: [OFLocale encoding]]) != 0) # else | | | | 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 | 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 } |
︙ | ︙ | |||
1106 1107 1108 1109 1110 1111 1112 | { void *pool = objc_autoreleasePoolPush(); OFString *sourcePath, *destinationPath; if (source == nil || destination == nil) @throw [OFInvalidArgumentException exception]; | | | | | | | | | | < | | | | | | | 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 | { 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; |
︙ | ︙ | |||
1239 1240 1241 1242 1243 1244 1245 | exceptionWithSourceURL: source destinationURL: destination errNo: errNo]; } #else of_string_encoding_t encoding = [OFLocale encoding]; | | | | 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 | 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/OFValue.m from [3dfa97e178] to [a898bac105].
︙ | ︙ | |||
168 169 170 171 172 173 174 | const char *objCType; size_t size; void *value, *otherValue; if (![object isKindOfClass: [OFValue class]]) return false; | | | 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 | const char *objCType; size_t size; void *value, *otherValue; if (![object isKindOfClass: [OFValue class]]) return false; objCType = self.objCType; if (strcmp([object objCType], objCType) != 0) return false; size = of_sizeof_type_encoding(objCType); if ((value = malloc(size)) == NULL) |
︙ | ︙ | |||
200 201 202 203 204 205 206 | free(value); free(otherValue); } } - (uint32_t)hash { | | | 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 | free(value); free(otherValue); } } - (uint32_t)hash { size_t size = of_sizeof_type_encoding(self.objCType); unsigned char *value; uint32_t hash; if ((value = malloc(size)) == NULL) @throw [OFOutOfMemoryException exceptionWithRequestedSize: size]; |
︙ | ︙ | |||
305 306 307 308 309 310 311 | return ret; } - (OFString *)description { OFMutableString *ret = [OFMutableString stringWithString: @"<OFValue: "]; | | | 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 | return ret; } - (OFString *)description { OFMutableString *ret = [OFMutableString stringWithString: @"<OFValue: "]; size_t size = of_sizeof_type_encoding(self.objCType); unsigned char *value; if ((value = malloc(size)) == NULL) @throw [OFOutOfMemoryException exceptionWithRequestedSize: size]; @try { |
︙ | ︙ |
Modified src/OFWindowsRegistryKey.m from [393e6cb19f] to [e2b1c254bf].
︙ | ︙ | |||
103 104 105 106 107 108 109 | options: (DWORD)options securityAndAccessRights: (REGSAM)securityAndAccessRights { void *pool = objc_autoreleasePoolPush(); LSTATUS status; HKEY subKey; | | | 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 | options: (DWORD)options securityAndAccessRights: (REGSAM)securityAndAccessRights { void *pool = objc_autoreleasePoolPush(); LSTATUS status; HKEY subKey; if ((status = RegOpenKeyExW(_hKey, path.UTF16String, options, securityAndAccessRights, &subKey)) != ERROR_SUCCESS) { if (status == ERROR_FILE_NOT_FOUND) { objc_autoreleasePoolPop(pool); return nil; } @throw [OFOpenWindowsRegistryKeyFailedException |
︙ | ︙ | |||
146 147 148 149 150 151 152 | securityAttributes: (LPSECURITY_ATTRIBUTES)securityAttributes disposition: (LPDWORD)disposition { void *pool = objc_autoreleasePoolPush(); LSTATUS status; HKEY subKey; | | | 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 | securityAttributes: (LPSECURITY_ATTRIBUTES)securityAttributes disposition: (LPDWORD)disposition { void *pool = objc_autoreleasePoolPush(); LSTATUS status; HKEY subKey; if ((status = RegCreateKeyExW(_hKey, path.UTF16String, 0, NULL, options, securityAndAccessRights, securityAttributes, &subKey, NULL)) != ERROR_SUCCESS) @throw [OFCreateWindowsRegistryKeyFailedException exceptionWithRegistryKey: self path: path options: options securityAndAccessRights: securityAndAccessRights |
︙ | ︙ | |||
176 177 178 179 180 181 182 | void *pool = objc_autoreleasePoolPush(); char stackBuffer[256], *buffer = stackBuffer; DWORD length = sizeof(stackBuffer); OFMutableData *ret = nil; LSTATUS status; for (;;) { | | | | 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 | void *pool = objc_autoreleasePoolPush(); char stackBuffer[256], *buffer = stackBuffer; DWORD length = sizeof(stackBuffer); OFMutableData *ret = nil; LSTATUS status; for (;;) { status = RegGetValueW(_hKey, subkeyPath.UTF16String, value.UTF16String, flags, type, buffer, &length); switch (status) { case ERROR_SUCCESS: if (buffer == stackBuffer) { objc_autoreleasePoolPop(pool); return [OFData dataWithItems: buffer |
︙ | ︙ | |||
204 205 206 207 208 209 210 | return nil; case ERROR_MORE_DATA: objc_autoreleasePoolPop(pool); pool = objc_autoreleasePoolPush(); ret = [OFMutableData dataWithCapacity: length]; [ret increaseCountBy: length]; | | | | | | 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 | return nil; case ERROR_MORE_DATA: objc_autoreleasePoolPop(pool); pool = objc_autoreleasePoolPush(); ret = [OFMutableData dataWithCapacity: length]; [ret increaseCountBy: length]; buffer = ret.items; continue; default: @throw [OFGetWindowsRegistryValueFailedException exceptionWithRegistryKey: self value: value subkeyPath: subkeyPath flags: flags status: status]; } } } - (void)setData: (OFData *)data forValue: (OFString *)value type: (DWORD)type { size_t length = data.count * data.itemSize; LSTATUS status; if (length > UINT32_MAX) @throw [OFOutOfRangeException exception]; if ((status = RegSetValueExW(_hKey, value.UTF16String, 0, type, data.items, (DWORD)length)) != ERROR_SUCCESS) @throw [OFSetWindowsRegistryValueFailedException exceptionWithRegistryKey: self value: value data: data type: type status: status]; } |
︙ | ︙ | |||
264 265 266 267 268 269 270 | const of_char16_t *UTF16String; size_t length; OFString *ret; if (data == nil) return nil; | | | | | 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 | const of_char16_t *UTF16String; size_t length; OFString *ret; if (data == nil) return nil; UTF16String = data.items; length = data.count; if (data.itemSize != 1 || length % 2 == 1) @throw [OFInvalidFormatException exception]; length /= 2; /* * REG_SZ and REG_EXPAND_SZ contain a \0, but can contain data after it * that should be ignored. |
︙ | ︙ | |||
306 307 308 309 310 311 312 | - (void)setString: (OFString *)string forValue: (OFString *)value type: (DWORD)type { void *pool = objc_autoreleasePoolPush(); OFData *data; | | | | | | 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 | - (void)setString: (OFString *)string forValue: (OFString *)value type: (DWORD)type { void *pool = objc_autoreleasePoolPush(); OFData *data; data = [OFData dataWithItems: string.UTF16String itemSize: sizeof(of_char16_t) count: string.UTF16StringLength + 1]; [self setData: data forValue: value type: type]; objc_autoreleasePoolPop(pool); } - (void)deleteValue: (OFString *)value { void *pool = objc_autoreleasePoolPush(); LSTATUS status; if ((status = RegDeleteValueW(_hKey, value.UTF16String)) != ERROR_SUCCESS) @throw [OFDeleteWindowsRegistryValueFailedException exceptionWithRegistryKey: self value: value status: status]; objc_autoreleasePoolPop(pool); } - (void)deleteSubkeyAtPath: (OFString *)subkeyPath { void *pool = objc_autoreleasePoolPush(); LSTATUS status; if ((status = RegDeleteKeyW(_hKey, subkeyPath.UTF16String)) != ERROR_SUCCESS) @throw [OFDeleteWindowsRegistryKeyFailedException exceptionWithRegistryKey: self subkeyPath: subkeyPath status: status]; objc_autoreleasePoolPop(pool); } @end |
Modified src/OFXMLAttribute.m from [bc86f5c2b5] to [87a544a7c5].
︙ | ︙ | |||
73 74 75 76 77 78 79 | - (instancetype)initWithSerialization: (OFXMLElement *)element { self = [super of_init]; @try { void *pool = objc_autoreleasePoolPush(); | | | | < | | | | | 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 | - (instancetype)initWithSerialization: (OFXMLElement *)element { self = [super of_init]; @try { void *pool = objc_autoreleasePoolPush(); if (![element.name isEqual: self.className] || ![element.namespace isEqual: OF_SERIALIZATION_NS]) @throw [OFInvalidArgumentException exception]; _name = [[element attributeForName: @"name"].stringValue copy]; _namespace = [[element attributeForName: @"namespace"] .stringValue copy]; _stringValue = [[element attributeForName: @"stringValue"] .stringValue copy]; objc_autoreleasePoolPop(pool); } @catch (id e) { [self release]; @throw e; } |
︙ | ︙ | |||
143 144 145 146 147 148 149 | - (uint32_t)hash { uint32_t hash; OF_HASH_INIT(hash); | | | | | | 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 | - (uint32_t)hash { uint32_t hash; OF_HASH_INIT(hash); OF_HASH_ADD_HASH(hash, _name.hash); OF_HASH_ADD_HASH(hash, _namespace.hash); OF_HASH_ADD_HASH(hash, _stringValue.hash); OF_HASH_FINALIZE(hash); return hash; } - (OFXMLElement *)XMLElementBySerializing { void *pool = objc_autoreleasePoolPush(); OFXMLElement *element; element = [OFXMLElement elementWithName: self.className namespace: OF_SERIALIZATION_NS]; [element addAttributeWithName: @"name" stringValue: _name]; if (_namespace != nil) [element addAttributeWithName: @"namespace" |
︙ | ︙ |
Modified src/OFXMLCDATA.m from [daf8eb8593] to [37fee43ed7].
︙ | ︙ | |||
47 48 49 50 51 52 53 | - (instancetype)initWithSerialization: (OFXMLElement *)element { self = [super of_init]; @try { void *pool = objc_autoreleasePoolPush(); | | | | | 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 | - (instancetype)initWithSerialization: (OFXMLElement *)element { self = [super of_init]; @try { void *pool = objc_autoreleasePoolPush(); if (![element.name isEqual: self.className] || ![element.namespace isEqual: OF_SERIALIZATION_NS]) @throw [OFInvalidArgumentException exception]; _CDATA = [element.stringValue copy]; objc_autoreleasePoolPop(pool); } @catch (id e) { [self release]; @throw e; } |
︙ | ︙ | |||
86 87 88 89 90 91 92 | CDATA = object; return ([CDATA->_CDATA isEqual: _CDATA]); } - (uint32_t)hash { | | | 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 | CDATA = object; return ([CDATA->_CDATA isEqual: _CDATA]); } - (uint32_t)hash { return _CDATA.hash; } - (OFString *)stringValue { return [[_CDATA copy] autorelease]; } |
︙ | ︙ | |||
116 117 118 119 120 121 122 | [ret retain]; objc_autoreleasePoolPop(pool); return [ret autorelease]; } - (OFString *)XMLStringWithIndentation: (unsigned int)indentation { | | | | | | 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 | [ret retain]; objc_autoreleasePoolPop(pool); return [ret autorelease]; } - (OFString *)XMLStringWithIndentation: (unsigned int)indentation { return self.XMLString; } - (OFString *)XMLStringWithIndentation: (unsigned int)indentation level: (unsigned int)level { return self.XMLString; } - (OFString *)description { return self.XMLString; } - (OFXMLElement *)XMLElementBySerializing { OFXMLElement *element = [OFXMLElement elementWithName: self.className namespace: OF_SERIALIZATION_NS]; [element addChild: self]; return element; } @end |
Modified src/OFXMLCharacters.m from [7f78add46a] to [0b6f50536f].
︙ | ︙ | |||
47 48 49 50 51 52 53 | - (instancetype)initWithSerialization: (OFXMLElement *)element { self = [super of_init]; @try { void *pool = objc_autoreleasePoolPush(); | | | | | 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 | - (instancetype)initWithSerialization: (OFXMLElement *)element { self = [super of_init]; @try { void *pool = objc_autoreleasePoolPush(); if (![element.name isEqual: self.className] || ![element.namespace isEqual: OF_SERIALIZATION_NS]) @throw [OFInvalidArgumentException exception]; _characters = [element.stringValue copy]; objc_autoreleasePoolPop(pool); } @catch (id e) { [self release]; @throw e; } |
︙ | ︙ | |||
86 87 88 89 90 91 92 | characters = object; return ([characters->_characters isEqual: _characters]); } - (uint32_t)hash { | | | | | | | | 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 | characters = object; return ([characters->_characters isEqual: _characters]); } - (uint32_t)hash { return _characters.hash; } - (OFString *)stringValue { return [[_characters copy] autorelease]; } - (void)setStringValue: (OFString *)stringValue { OFString *old = _characters; _characters = [stringValue copy]; [old release]; } - (OFString *)XMLString { return _characters.stringByXMLEscaping; } - (OFString *)XMLStringWithIndentation: (unsigned int)indentation { return _characters.stringByXMLEscaping; } - (OFString *)XMLStringWithIndentation: (unsigned int)indentation level: (unsigned int)level { return _characters.stringByXMLEscaping; } - (OFString *)description { return _characters.stringByXMLEscaping; } - (OFXMLElement *)XMLElementBySerializing { return [OFXMLElement elementWithName: self.className namespace: OF_SERIALIZATION_NS stringValue: _characters]; } @end |
Modified src/OFXMLComment.m from [cfcfb31543] to [7cb96fc45d].
︙ | ︙ | |||
49 50 51 52 53 54 55 | - (instancetype)initWithSerialization: (OFXMLElement *)element { self = [super of_init]; @try { void *pool = objc_autoreleasePoolPush(); | | | | | 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 | - (instancetype)initWithSerialization: (OFXMLElement *)element { self = [super of_init]; @try { void *pool = objc_autoreleasePoolPush(); if (![element.name isEqual: self.className] || ![element.namespace isEqual: OF_SERIALIZATION_NS]) @throw [OFInvalidArgumentException exception]; _comment = [element.stringValue copy]; objc_autoreleasePoolPop(pool); } @catch (id e) { [self release]; @throw e; } |
︙ | ︙ | |||
88 89 90 91 92 93 94 | comment = object; return ([comment->_comment isEqual: _comment]); } - (uint32_t)hash { | | | 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 | comment = object; return ([comment->_comment isEqual: _comment]); } - (uint32_t)hash { return _comment.hash; } - (OFString *)stringValue { return @""; } |
︙ | ︙ | |||
137 138 139 140 141 142 143 | - (OFString *)description { return [OFString stringWithFormat: @"<!--%@-->", _comment]; } - (OFXMLElement *)XMLElementBySerializing { | | | 137 138 139 140 141 142 143 144 145 146 147 148 | - (OFString *)description { return [OFString stringWithFormat: @"<!--%@-->", _comment]; } - (OFXMLElement *)XMLElementBySerializing { return [OFXMLElement elementWithName: self.className namespace: OF_SERIALIZATION_NS stringValue: _comment]; } @end |
Modified src/OFXMLElement.m from [7faef87abe] to [5fc577399d].
︙ | ︙ | |||
96 97 98 99 100 101 102 | stringValue: (OFString *)stringValue { return [[[self alloc] initWithName: name stringValue: stringValue] autorelease]; } + (instancetype)elementWithName: (OFString *)name | | | | | | 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 | stringValue: (OFString *)stringValue { return [[[self alloc] initWithName: name stringValue: stringValue] autorelease]; } + (instancetype)elementWithName: (OFString *)name namespace: (OFString *)namespace { return [[[self alloc] initWithName: name namespace: namespace] autorelease]; } + (instancetype)elementWithName: (OFString *)name namespace: (OFString *)namespace stringValue: (OFString *)stringValue { return [[[self alloc] initWithName: name namespace: namespace stringValue: stringValue] autorelease]; } + (instancetype)elementWithElement: (OFXMLElement *)element { return [[[self alloc] initWithElement: element] autorelease]; } |
︙ | ︙ | |||
175 176 177 178 179 180 181 | _namespaces = [[OFMutableDictionary alloc] initWithKeysAndObjects: @"http://www.w3.org/XML/1998/namespace", @"xml", @"http://www.w3.org/2000/xmlns/", @"xmlns", nil]; if (stringValue != nil) | | | 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 | _namespaces = [[OFMutableDictionary alloc] initWithKeysAndObjects: @"http://www.w3.org/XML/1998/namespace", @"xml", @"http://www.w3.org/2000/xmlns/", @"xmlns", nil]; if (stringValue != nil) self.stringValue = stringValue; } @catch (id e) { [self release]; @throw e; } return self; } |
︙ | ︙ | |||
226 227 228 229 230 231 232 | pool = objc_autoreleasePoolPush(); parser = [OFXMLParser parser]; builder = [OFXMLElementBuilder elementBuilder]; delegate = [[[OFXMLElement_OFXMLElementBuilderDelegate alloc] init] autorelease]; | | | | | 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 | pool = objc_autoreleasePoolPush(); parser = [OFXMLParser parser]; builder = [OFXMLElementBuilder elementBuilder]; delegate = [[[OFXMLElement_OFXMLElementBuilderDelegate alloc] init] autorelease]; parser.delegate = builder; builder.delegate = delegate; [parser parseString: string]; if (!parser.hasFinishedParsing) @throw [OFMalformedXMLException exceptionWithParser: parser]; self = [delegate->_element retain]; objc_autoreleasePoolPop(pool); return self; |
︙ | ︙ | |||
258 259 260 261 262 263 264 | pool = objc_autoreleasePoolPush(); parser = [OFXMLParser parser]; builder = [OFXMLElementBuilder elementBuilder]; delegate = [[[OFXMLElement_OFXMLElementBuilderDelegate alloc] init] autorelease]; | | | | | 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 | pool = objc_autoreleasePoolPush(); parser = [OFXMLParser parser]; builder = [OFXMLElementBuilder elementBuilder]; delegate = [[[OFXMLElement_OFXMLElementBuilderDelegate alloc] init] autorelease]; parser.delegate = builder; builder.delegate = delegate; [parser parseFile: path]; if (!parser.hasFinishedParsing) @throw [OFMalformedXMLException exceptionWithParser: parser]; self = [delegate->_element retain]; objc_autoreleasePoolPop(pool); return self; |
︙ | ︙ | |||
285 286 287 288 289 290 291 | @try { void *pool = objc_autoreleasePoolPush(); OFXMLElement *attributesElement, *namespacesElement; OFXMLElement *childrenElement; OFEnumerator *keyEnumerator, *objectEnumerator; OFString *key, *object; | | | | < | | | | | | | | | | | | | | 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 | @try { void *pool = objc_autoreleasePoolPush(); OFXMLElement *attributesElement, *namespacesElement; OFXMLElement *childrenElement; OFEnumerator *keyEnumerator, *objectEnumerator; OFString *key, *object; if (![element.name isEqual: self.className] || ![element.namespace isEqual: OF_SERIALIZATION_NS]) @throw [OFInvalidArgumentException exception]; _name = [[element attributeForName: @"name"].stringValue copy]; _namespace = [[element attributeForName: @"namespace"] .stringValue copy]; _defaultNamespace = [[element attributeForName: @"defaultNamespace"].stringValue copy]; attributesElement = [[element elementForName: @"attributes" namespace: OF_SERIALIZATION_NS] elementsForNamespace: OF_SERIALIZATION_NS].firstObject; namespacesElement = [[element elementForName: @"namespaces" namespace: OF_SERIALIZATION_NS] elementsForNamespace: OF_SERIALIZATION_NS].firstObject; childrenElement = [[element elementForName: @"children" namespace: OF_SERIALIZATION_NS] elementsForNamespace: OF_SERIALIZATION_NS].firstObject; _attributes = [attributesElement.objectByDeserializing mutableCopy]; _namespaces = [namespacesElement.objectByDeserializing mutableCopy]; _children = [childrenElement.objectByDeserializing mutableCopy]; /* Sanity checks */ if ((_attributes != nil && ![_attributes isKindOfClass: [OFMutableArray class]]) || (_namespaces != nil && ![_namespaces isKindOfClass: [OFMutableDictionary class]]) || (_children != nil && |
︙ | ︙ | |||
394 395 396 397 398 399 400 | return [[_children copy] autorelease]; } - (void)setStringValue: (OFString *)stringValue { void *pool = objc_autoreleasePoolPush(); | | | | | | 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 | return [[_children copy] autorelease]; } - (void)setStringValue: (OFString *)stringValue { void *pool = objc_autoreleasePoolPush(); self.children = [OFArray arrayWithObject: [OFXMLCharacters charactersWithString: stringValue]]; objc_autoreleasePoolPop(pool); } - (OFString *)stringValue { OFMutableString *ret; if (_children.count == 0) return @""; ret = [OFMutableString string]; for (OFXMLNode *child in _children) { void *pool = objc_autoreleasePoolPush(); [ret appendString: child.stringValue]; objc_autoreleasePoolPop(pool); } [ret makeImmutable]; return ret; |
︙ | ︙ | |||
469 470 471 472 473 474 475 | defaultNS = parent->_namespace; else if (parent != nil && parent->_defaultNamespace != nil) defaultNS = parent->_defaultNamespace; else defaultNS = _defaultNamespace; i = 0; | | | | | < | | | | | | | < | < | | | | | | | | | 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 | defaultNS = parent->_namespace; else if (parent != nil && parent->_defaultNamespace != nil) defaultNS = parent->_defaultNamespace; else defaultNS = _defaultNamespace; i = 0; length = _name.UTF8StringLength + 3 + (level * indentation); cString = [self allocMemoryWithSize: length]; memset(cString + i, ' ', level * indentation); i += level * indentation; /* Start of tag */ cString[i++] = '<'; if (prefix != nil && ![_namespace isEqual: defaultNS]) { length += prefix.UTF8StringLength + 1; @try { cString = [self resizeMemory: cString size: length]; } @catch (id e) { [self freeMemory: cString]; @throw e; } memcpy(cString + i, prefix.UTF8String, prefix.UTF8StringLength); i += prefix.UTF8StringLength; cString[i++] = ':'; } memcpy(cString + i, _name.UTF8String, _name.UTF8StringLength); i += _name.UTF8StringLength; /* xmlns if necessary */ if (prefix == nil && ((_namespace != nil && ![_namespace isEqual: defaultNS]) || (_namespace == nil && defaultNS != nil))) { length += _namespace.UTF8StringLength + 9; @try { cString = [self resizeMemory: cString size: length]; } @catch (id e) { [self freeMemory: cString]; @throw e; } memcpy(cString + i, " xmlns='", 8); i += 8; memcpy(cString + i, _namespace.UTF8String, _namespace.UTF8StringLength); i += _namespace.UTF8StringLength; cString[i++] = '\''; } /* Attributes */ for (OFXMLAttribute *attribute in _attributes) { void *pool2 = objc_autoreleasePoolPush(); const char *attributeNameCString = attribute->_name.UTF8String; size_t attributeNameLength = attribute->_name.UTF8StringLength; OFString *attributePrefix = nil; OFString *tmp = attribute.stringValue.stringByXMLEscaping; char delimiter = (attribute->_useDoubleQuotes ? '"' : '\''); if (attribute->_namespace != nil && (attributePrefix = [allNamespaces objectForKey: attribute->_namespace]) == nil) @throw [OFUnboundNamespaceException exceptionWithNamespace: [attribute namespace] element: self]; length += attributeNameLength + (attributePrefix != nil ? attributePrefix.UTF8StringLength + 1 : 0) + tmp.UTF8StringLength + 4; @try { cString = [self resizeMemory: cString size: length]; } @catch (id e) { [self freeMemory: cString]; @throw e; } cString[i++] = ' '; if (attributePrefix != nil) { memcpy(cString + i, attributePrefix.UTF8String, attributePrefix.UTF8StringLength); i += attributePrefix.UTF8StringLength; cString[i++] = ':'; } memcpy(cString + i, attributeNameCString, attributeNameLength); i += attributeNameLength; cString[i++] = '='; cString[i++] = delimiter; memcpy(cString + i, tmp.UTF8String, tmp.UTF8StringLength); i += tmp.UTF8StringLength; cString[i++] = delimiter; objc_autoreleasePoolPop(pool2); } /* Children */ if (_children != nil) { |
︙ | ︙ | |||
603 604 605 606 607 608 609 | indentation: ind level: level + 1]; else childString = [child XMLStringWithIndentation: ind level: level + 1]; | | | | | | | | | | | | < | 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 | indentation: ind level: level + 1]; else childString = [child XMLStringWithIndentation: ind level: level + 1]; [tmp addItems: childString.UTF8String count: childString.UTF8StringLength]; } if (indent) [tmp addItem: "\n"]; length += tmp.count + _name.UTF8StringLength + 2 + (indent ? level * indentation : 0); @try { cString = [self resizeMemory: cString size: length]; } @catch (id e) { [self freeMemory: cString]; @throw e; } cString[i++] = '>'; memcpy(cString + i, tmp.items, tmp.count); i += tmp.count; if (indent) { memset(cString + i, ' ', level * indentation); i += level * indentation; } cString[i++] = '<'; cString[i++] = '/'; if (prefix != nil) { length += prefix.UTF8StringLength + 1; @try { cString = [self resizeMemory: cString size: length]; } @catch (id e) { [self freeMemory: cString]; @throw e; } memcpy(cString + i, prefix.UTF8String, prefix.UTF8StringLength); i += prefix.UTF8StringLength; cString[i++] = ':'; } memcpy(cString + i, _name.UTF8String, _name.UTF8StringLength); i += _name.UTF8StringLength; } else cString[i++] = '/'; cString[i++] = '>'; assert(i == length); objc_autoreleasePoolPop(pool); |
︙ | ︙ | |||
697 698 699 700 701 702 703 | } - (OFXMLElement *)XMLElementBySerializing { void *pool = objc_autoreleasePoolPush(); OFXMLElement *element; | | | 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 | } - (OFXMLElement *)XMLElementBySerializing { void *pool = objc_autoreleasePoolPush(); OFXMLElement *element; element = [OFXMLElement elementWithName: self.className namespace: OF_SERIALIZATION_NS]; if (_name != nil) [element addAttributeWithName: @"name" stringValue: _name]; if (_namespace != nil) |
︙ | ︙ | |||
719 720 721 722 723 724 725 | if (_attributes != nil) { OFXMLElement *attributesElement; attributesElement = [OFXMLElement elementWithName: @"attributes" namespace: OF_SERIALIZATION_NS]; [attributesElement addChild: | | | | | | 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 | if (_attributes != nil) { OFXMLElement *attributesElement; attributesElement = [OFXMLElement elementWithName: @"attributes" namespace: OF_SERIALIZATION_NS]; [attributesElement addChild: _attributes.XMLElementBySerializing]; [element addChild: attributesElement]; } if (_namespaces != nil) { OFXMLElement *namespacesElement; OFMutableDictionary *namespacesCopy = [[_namespaces mutableCopy] autorelease]; [namespacesCopy removeObjectForKey: @"http://www.w3.org/XML/1998/namespace"]; [namespacesCopy removeObjectForKey: @"http://www.w3.org/2000/xmlns/"]; if (namespacesCopy.count > 0) { namespacesElement = [OFXMLElement elementWithName: @"namespaces" namespace: OF_SERIALIZATION_NS]; [namespacesElement addChild: namespacesCopy.XMLElementBySerializing]; [element addChild: namespacesElement]; } } if (_children != nil) { OFXMLElement *childrenElement; childrenElement = [OFXMLElement elementWithName: @"children" namespace: OF_SERIALIZATION_NS]; [childrenElement addChild: _children.XMLElementBySerializing]; [element addChild: childrenElement]; } [element retain]; objc_autoreleasePoolPop(pool); |
︙ | ︙ | |||
820 821 822 823 824 825 826 | return attribute; return nil; } - (void)removeAttributeForName: (OFString *)attributeName { | | | | 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 | return attribute; return nil; } - (void)removeAttributeForName: (OFString *)attributeName { OFXMLAttribute *const *objects = _attributes.objects; size_t count = _attributes.count; for (size_t i = 0; i < count; i++) { if (objects[i]->_namespace == nil && [objects[i]->_name isEqual: attributeName]) { [_attributes removeObjectAtIndex: i]; return; |
︙ | ︙ | |||
844 845 846 847 848 849 850 | size_t count; if (attributeNS == nil) { [self removeAttributeForName: attributeName]; return; } | | | | | 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 | size_t count; if (attributeNS == nil) { [self removeAttributeForName: attributeName]; return; } objects = _attributes.objects; count = _attributes.count; for (size_t i = 0; i < count; i++) { if ([objects[i]->_namespace isEqual: attributeNS] && [objects[i]->_name isEqual: attributeName]) { [_attributes removeObjectAtIndex: i]; return; } } } - (void)setPrefix: (OFString *)prefix forNamespace: (OFString *)namespace { if (prefix.length == 0) @throw [OFInvalidArgumentException exception]; if (namespace == nil) namespace = @""; [_namespaces setObject: prefix forKey: namespace]; } |
︙ | ︙ | |||
949 950 951 952 953 954 955 | [_children replaceObjectAtIndex: idx withObject: node]; } - (OFXMLElement *)elementForName: (OFString *)elementName { | | | | | 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 | [_children replaceObjectAtIndex: idx withObject: node]; } - (OFXMLElement *)elementForName: (OFString *)elementName { return [self elementsForName: elementName].firstObject; } - (OFXMLElement *)elementForName: (OFString *)elementName namespace: (OFString *)elementNS { return [self elementsForName: elementName namespace: elementNS].firstObject; } - (OFArray *)elements { OFMutableArray OF_GENERIC(OFXMLElement *) *ret = [OFMutableArray array]; for (OFXMLNode *child in _children) |
︙ | ︙ | |||
1074 1075 1076 1077 1078 1079 1080 | - (uint32_t)hash { uint32_t hash; OF_HASH_INIT(hash); | | | | | | | | 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 | - (uint32_t)hash { uint32_t hash; OF_HASH_INIT(hash); OF_HASH_ADD_HASH(hash, _name.hash); OF_HASH_ADD_HASH(hash, _namespace.hash); OF_HASH_ADD_HASH(hash, _defaultNamespace.hash); OF_HASH_ADD_HASH(hash, _attributes.hash); OF_HASH_ADD_HASH(hash, _namespaces.hash); OF_HASH_ADD_HASH(hash, _children.hash); OF_HASH_FINALIZE(hash); return hash; } - (id)copy { return [[[self class] alloc] initWithElement: self]; } @end |
Modified src/OFXMLElementBuilder.m from [525456c691] to [40db47b479].
︙ | ︙ | |||
59 60 61 62 63 64 65 | } - (void)parser: (OFXMLParser *)parser foundProcessingInstructions: (OFString *)pi { OFXMLProcessingInstructions *node = [OFXMLProcessingInstructions processingInstructionsWithString: pi]; | | | | | | | | | | | | | | | 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 | } - (void)parser: (OFXMLParser *)parser foundProcessingInstructions: (OFString *)pi { OFXMLProcessingInstructions *node = [OFXMLProcessingInstructions processingInstructionsWithString: pi]; OFXMLElement *parent = _stack.lastObject; if (parent != nil) [parent addChild: node]; else if ([_delegate respondsToSelector: @selector(elementBuilder:didBuildParentlessNode:)]) [_delegate elementBuilder: self didBuildParentlessNode: node]; } - (void)parser: (OFXMLParser *)parser didStartElement: (OFString *)name prefix: (OFString *)prefix namespace: (OFString *)namespace attributes: (OFArray *)attributes { OFXMLElement *element = [OFXMLElement elementWithName: name namespace: namespace]; for (OFXMLAttribute *attribute in attributes) { if (attribute.namespace == nil && [attribute.name isEqual: @"xmlns"]) continue; if ([attribute.namespace isEqual: @"http://www.w3.org/2000/xmlns/"]) [element setPrefix: attribute.name forNamespace: attribute.stringValue]; [element addAttribute: attribute]; } [_stack.lastObject addChild: element]; [_stack addObject: element]; } - (void)parser: (OFXMLParser *)parser didEndElement: (OFString *)name prefix: (OFString *)prefix namespace: (OFString *)namespace { switch (_stack.count) { case 0: if ([_delegate respondsToSelector: @selector(elementBuilder: didNotExpectCloseTag:prefix:namespace:)]) [_delegate elementBuilder: self didNotExpectCloseTag: name prefix: prefix namespace: namespace]; else @throw [OFMalformedXMLException exception]; return; case 1: [_delegate elementBuilder: self didBuildElement: _stack.firstObject]; break; } [_stack removeLastObject]; } - (void)parser: (OFXMLParser *)parser foundCharacters: (OFString *)characters { OFXMLCharacters *node; OFXMLElement *parent; node = [OFXMLCharacters charactersWithString: characters]; parent = _stack.lastObject; if (parent != nil) [parent addChild: node]; else if ([_delegate respondsToSelector: @selector(elementBuilder:didBuildParentlessNode:)]) [_delegate elementBuilder: self didBuildParentlessNode: node]; } - (void)parser: (OFXMLParser *)parser foundCDATA: (OFString *)CDATA { OFXMLCDATA *node = [OFXMLCDATA CDATAWithString: CDATA]; OFXMLElement *parent = _stack.lastObject; if (parent != nil) [parent addChild: node]; else if ([_delegate respondsToSelector: @selector(elementBuilder:didBuildParentlessNode:)]) [_delegate elementBuilder: self didBuildParentlessNode: node]; } - (void)parser: (OFXMLParser *)parser foundComment: (OFString *)comment { OFXMLComment *node = [OFXMLComment commentWithString: comment]; OFXMLElement *parent = _stack.lastObject; if (parent != nil) [parent addChild: node]; else if ([_delegate respondsToSelector: @selector(elementBuilder:didBuildParentlessNode:)]) [_delegate elementBuilder: self didBuildParentlessNode: node]; |
︙ | ︙ |
Modified src/OFXMLNode.m from [badc6f5c55] to [ed42a019d1].
︙ | ︙ | |||
44 45 46 47 48 49 50 | - (void)setStringValue: (OFString *)stringValue { OF_UNRECOGNIZED_SELECTOR } - (intmax_t)decimalValue { | | | | | | 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 | - (void)setStringValue: (OFString *)stringValue { OF_UNRECOGNIZED_SELECTOR } - (intmax_t)decimalValue { return self.stringValue.decimalValue; } - (uintmax_t)hexadecimalValue { return self.stringValue.hexadecimalValue; } - (float)floatValue { return self.stringValue.floatValue; } - (double)doubleValue { return self.stringValue.doubleValue; } - (OFString *)XMLString { return [self XMLStringWithIndentation: 0 level: 0]; } |
︙ | ︙ |
Modified src/OFXMLParser.m from [f6e5cef596] to [e97aaf5fcc].
︙ | ︙ | |||
74 75 76 77 78 79 80 | [buffer addItems: string count: length]; else { void *pool = objc_autoreleasePoolPush(); OFString *tmp = [OFString stringWithCString: string encoding: encoding length: length]; | | | | | | | 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 | [buffer addItems: string count: length]; else { void *pool = objc_autoreleasePoolPush(); OFString *tmp = [OFString stringWithCString: string encoding: encoding length: length]; [buffer addItems: tmp.UTF8String count: tmp.UTF8StringLength]; objc_autoreleasePoolPop(pool); } } static OFString * transformString(OFXMLParser *parser, OFMutableData *buffer, size_t cut, bool unescape) { char *items = buffer.mutableItems; size_t length = buffer.count - cut; bool hasEntities = false; OFString *ret; for (size_t i = 0; i < length; i++) { if (items[i] == '\r') { if (i + 1 < length && items[i + 1] == '\n') { [buffer removeItemAtIndex: i]; items = buffer.mutableItems; i--; length--; } else items[i] = '\n'; } else if (items[i] == '&') hasEntities = true; |
︙ | ︙ | |||
121 122 123 124 125 126 127 | return ret; } static OFString * namespaceForPrefix(OFString *prefix, OFArray *namespaces) { | | | | 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 | return ret; } static OFString * namespaceForPrefix(OFString *prefix, OFArray *namespaces) { OFDictionary *const *objects = namespaces.objects; size_t count = namespaces.count; if (prefix == nil) prefix = @""; while (count > 0) { OFString *tmp; |
︙ | ︙ | |||
278 279 280 281 282 283 284 | if (length - _last > 0 && _state != OF_XMLPARSER_IN_TAG) appendToBuffer(_buffer, _data + _last, _encoding, length - _last); } - (void)parseString: (OFString *)string { | | | | | 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 | if (length - _last > 0 && _state != OF_XMLPARSER_IN_TAG) appendToBuffer(_buffer, _data + _last, _encoding, length - _last); } - (void)parseString: (OFString *)string { [self parseBuffer: string.UTF8String length: string.UTF8StringLength]; } - (void)parseStream: (OFStream *)stream { size_t pageSize = [OFSystemInfo pageSize]; char *buffer = [self allocMemoryWithSize: pageSize]; @try { while (!stream.atEndOfStream) { size_t length = [stream readIntoBuffer: buffer length: pageSize]; [self parseBuffer: buffer length: length]; } } @finally { |
︙ | ︙ | |||
342 343 344 345 346 347 348 | } /* Not in a tag */ - (void)of_outsideTagState { size_t length; | | | | 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 | } /* Not in a tag */ - (void)of_outsideTagState { size_t length; if ((_finishedParsing || _previous.count < 1) && _data[_i] != ' ' && _data[_i] != '\t' && _data[_i] != '\n' && _data[_i] != '\r' && _data[_i] != '<') @throw [OFMalformedXMLException exceptionWithParser: self]; if (_data[_i] != '<') return; if ((length = _i - _last) > 0) appendToBuffer(_buffer, _data + _last, _encoding, length); if (_buffer.count > 0) { void *pool = objc_autoreleasePoolPush(); OFString *characters = transformString(self, _buffer, 0, true); if ([_delegate respondsToSelector: @selector(parser:foundCharacters:)]) [_delegate parser: self foundCharacters: characters]; |
︙ | ︙ | |||
394 395 396 397 398 399 400 | break; case '!': _last = _i + 1; _state = OF_XMLPARSER_IN_EXCLAMATIONMARK; _acceptProlog = false; break; default: | | | 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 | break; case '!': _last = _i + 1; _state = OF_XMLPARSER_IN_EXCLAMATIONMARK; _acceptProlog = false; break; default: if (_depthLimit > 0 && _previous.count >= _depthLimit) @throw [OFOutOfRangeException exception]; _state = OF_XMLPARSER_IN_TAG_NAME; _acceptProlog = false; _i--; break; } |
︙ | ︙ | |||
420 421 422 423 424 425 426 | bool hasVersion = false; if (!_acceptProlog) return false; _acceptProlog = false; | | | | | | 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 | bool hasVersion = false; if (!_acceptProlog) return false; _acceptProlog = false; pi = [pi substringWithRange: of_range(3, pi.length - 3)]; pi = pi.stringByDeletingEnclosingWhitespaces; cString = pi.UTF8String; length = pi.UTF8StringLength; last = 0; for (size_t i = 0; i < length; i++) { switch (PIState) { case 0: if (cString[i] == ' ' || cString[i] == '\t' || cString[i] == '\r' || cString[i] == '\n') |
︙ | ︙ | |||
543 544 545 546 547 548 549 | return; if ((length = _i - _last) > 0) appendToBuffer(_buffer, _data + _last, _encoding, length); pool = objc_autoreleasePoolPush(); | | | | 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 | return; if ((length = _i - _last) > 0) appendToBuffer(_buffer, _data + _last, _encoding, length); pool = objc_autoreleasePoolPush(); bufferCString = _buffer.items; bufferLength = _buffer.count; bufferString = [OFString stringWithUTF8String: bufferCString length: bufferLength]; if ((tmp = memchr(bufferCString, ':', bufferLength)) != NULL) { _name = [[OFString alloc] initWithUTF8String: tmp + 1 length: bufferLength - |
︙ | ︙ | |||
587 588 589 590 591 592 593 | if ([_delegate respondsToSelector: @selector(parser:didEndElement:prefix:namespace:)]) [_delegate parser: self didEndElement: _name prefix: _prefix namespace: namespace]; | | | 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 | if ([_delegate respondsToSelector: @selector(parser:didEndElement:prefix:namespace:)]) [_delegate parser: self didEndElement: _name prefix: _prefix namespace: namespace]; if (_previous.count == 0) _finishedParsing = true; } else [_previous addObject: bufferString]; [_name release]; [_prefix release]; _name = _prefix = nil; |
︙ | ︙ | |||
628 629 630 631 632 633 634 | return; if ((length = _i - _last) > 0) appendToBuffer(_buffer, _data + _last, _encoding, length); pool = objc_autoreleasePoolPush(); | | | | | 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 | return; if ((length = _i - _last) > 0) appendToBuffer(_buffer, _data + _last, _encoding, length); pool = objc_autoreleasePoolPush(); bufferCString = _buffer.items; bufferLength = _buffer.count; bufferString = [OFString stringWithUTF8String: bufferCString length: bufferLength]; if ((tmp = memchr(bufferCString, ':', bufferLength)) != NULL) { _name = [[OFString alloc] initWithUTF8String: tmp + 1 length: bufferLength - (tmp - bufferCString) - 1]; _prefix = [[OFString alloc] initWithUTF8String: bufferCString length: tmp - bufferCString]; } else { _name = [bufferString copy]; _prefix = nil; } if (![_previous.lastObject isEqual: bufferString]) @throw [OFMalformedXMLException exceptionWithParser: self]; [_previous removeLastObject]; [_buffer removeAllItems]; namespace = namespaceForPrefix(_prefix, _namespaces); |
︙ | ︙ | |||
677 678 679 680 681 682 683 | _name = _prefix = nil; _last = _i + 1; _state = (_data[_i] == '>' ? OF_XMLPARSER_OUTSIDE_TAG : OF_XMLPARSER_EXPECT_SPACE_OR_TAG_CLOSE); | | | 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 | _name = _prefix = nil; _last = _i + 1; _state = (_data[_i] == '>' ? OF_XMLPARSER_OUTSIDE_TAG : OF_XMLPARSER_EXPECT_SPACE_OR_TAG_CLOSE); if (_previous.count == 0) _finishedParsing = true; } /* Inside a tag, name found */ - (void)of_inTagState { void *pool; |
︙ | ︙ | |||
700 701 702 703 704 705 706 | _state = OF_XMLPARSER_IN_ATTRIBUTE_NAME; _i--; } return; } | | | | 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 | _state = OF_XMLPARSER_IN_ATTRIBUTE_NAME; _i--; } return; } attributesObjects = _attributes.objects; attributesCount = _attributes.count; namespace = namespaceForPrefix(_prefix, _namespaces); if (_prefix != nil && namespace == nil) @throw [OFUnboundPrefixException exceptionWithPrefix: _prefix parser: self]; |
︙ | ︙ | |||
731 732 733 734 735 736 737 | if ([_delegate respondsToSelector: @selector(parser:didEndElement:prefix:namespace:)]) [_delegate parser: self didEndElement: _name prefix: _prefix namespace: namespace]; | | | 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 | if ([_delegate respondsToSelector: @selector(parser:didEndElement:prefix:namespace:)]) [_delegate parser: self didEndElement: _name prefix: _prefix namespace: namespace]; if (_previous.count == 0) _finishedParsing = true; [_namespaces removeLastObject]; } else if (_prefix != nil) { OFString *str = [OFString stringWithFormat: @"%@:%@", _prefix, _name]; [_previous addObject: str]; |
︙ | ︙ | |||
772 773 774 775 776 777 778 | return; if ((length = _i - _last) > 0) appendToBuffer(_buffer, _data + _last, _encoding, length); pool = objc_autoreleasePoolPush(); | | | | | | 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 | return; if ((length = _i - _last) > 0) appendToBuffer(_buffer, _data + _last, _encoding, length); pool = objc_autoreleasePoolPush(); bufferString = [OFString stringWithUTF8String: _buffer.items length: _buffer.count]; bufferCString = bufferString.UTF8String; bufferLength = bufferString.UTF8StringLength; if ((tmp = memchr(bufferCString, ':', bufferLength)) != NULL) { _attributeName = [[OFString alloc] initWithUTF8String: tmp + 1 length: bufferLength - (tmp - bufferCString) - 1]; _attributePrefix = [[OFString alloc] |
︙ | ︙ | |||
849 850 851 852 853 854 855 | if ((length = _i - _last) > 0) appendToBuffer(_buffer, _data + _last, _encoding, length); pool = objc_autoreleasePoolPush(); attributeValue = transformString(self, _buffer, 0, true); if (_attributePrefix == nil && [_attributeName isEqual: @"xmlns"]) | | | | | | 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 | if ((length = _i - _last) > 0) appendToBuffer(_buffer, _data + _last, _encoding, length); pool = objc_autoreleasePoolPush(); attributeValue = transformString(self, _buffer, 0, true); if (_attributePrefix == nil && [_attributeName isEqual: @"xmlns"]) [_namespaces.lastObject setObject: attributeValue forKey: @""]; if ([_attributePrefix isEqual: @"xmlns"]) [_namespaces.lastObject setObject: attributeValue forKey: _attributeName]; attribute = [OFXMLAttribute attributeWithName: _attributeName namespace: _attributePrefix stringValue: attributeValue]; attribute->_useDoubleQuotes = (_delimiter == '"'); [_attributes addObject: attribute]; |
︙ | ︙ |
Modified src/OFXMLProcessingInstructions.m from [894e02c7e4] to [b4f91e54e3].
︙ | ︙ | |||
49 50 51 52 53 54 55 | - (instancetype)initWithSerialization: (OFXMLElement *)element { self = [super of_init]; @try { void *pool = objc_autoreleasePoolPush(); | | | | | 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 | - (instancetype)initWithSerialization: (OFXMLElement *)element { self = [super of_init]; @try { void *pool = objc_autoreleasePoolPush(); if (![element.name isEqual: self.className] || ![element.namespace isEqual: OF_SERIALIZATION_NS]) @throw [OFInvalidArgumentException exception]; _processingInstructions = [element.stringValue copy]; objc_autoreleasePoolPop(pool); } @catch (id e) { [self release]; @throw e; } |
︙ | ︙ | |||
89 90 91 92 93 94 95 | return ([processingInstructions->_processingInstructions isEqual: _processingInstructions]); } - (uint32_t)hash { | | | 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 | return ([processingInstructions->_processingInstructions isEqual: _processingInstructions]); } - (uint32_t)hash { return _processingInstructions.hash; } - (OFString *)stringValue { return @""; } |
︙ | ︙ | |||
138 139 140 141 142 143 144 | - (OFString *)description { return [OFString stringWithFormat: @"<?%@?>", _processingInstructions]; } - (OFXMLElement *)XMLElementBySerializing { | | | 138 139 140 141 142 143 144 145 146 147 148 149 | - (OFString *)description { return [OFString stringWithFormat: @"<?%@?>", _processingInstructions]; } - (OFXMLElement *)XMLElementBySerializing { return [OFXMLElement elementWithName: self.className namespace: OF_SERIALIZATION_NS stringValue: _processingInstructions]; } @end |
Modified src/OFZIPArchive.h from [56b243376c] to [4b0bcbe6e5].
︙ | ︙ | |||
29 30 31 32 33 34 35 | /*! * @class OFZIPArchive OFZIPArchive.h ObjFW/OFZIPArchive.h * * @brief A class for accessing and manipulating ZIP files. */ @interface OFZIPArchive: OFObject { | | | 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | /*! * @class OFZIPArchive OFZIPArchive.h ObjFW/OFZIPArchive.h * * @brief A class for accessing and manipulating ZIP files. */ @interface OFZIPArchive: OFObject { OFStream *_stream; int64_t _offset; enum { OF_ZIP_ARCHIVE_MODE_READ, OF_ZIP_ARCHIVE_MODE_WRITE, OF_ZIP_ARCHIVE_MODE_APPEND } _mode; uint32_t _diskNumber, _centralDirectoryDisk; |
︙ | ︙ | |||
73 74 75 76 77 78 79 | * @param stream A stream from which the ZIP archive will be read. * For read and append mode, this needs to be an OFSeekableStream. * @param mode The mode for the ZIP file. Valid modes are "r" for reading, * "w" for creating a new file and "a" for appending to an existing * archive. * @return A new, autoreleased OFZIPArchive */ | | | 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 | * @param stream A stream from which the ZIP archive will be read. * For read and append mode, this needs to be an OFSeekableStream. * @param mode The mode for the ZIP file. Valid modes are "r" for reading, * "w" for creating a new file and "a" for appending to an existing * archive. * @return A new, autoreleased OFZIPArchive */ + (instancetype)archiveWithStream: (OFStream *)stream mode: (OFString *)mode; #ifdef OF_HAVE_FILES /*! * @brief Creates a new OFZIPArchive object with the specified file. * * @param path The path to the ZIP file |
︙ | ︙ | |||
103 104 105 106 107 108 109 | * @param stream A stream from which the ZIP archive will be read. * For read and append mode, this needs to be an OFSeekableStream. * @param mode The mode for the ZIP file. Valid modes are "r" for reading, * "w" for creating a new file and "a" for appending to an existing * archive. * @return An initialized OFZIPArchive */ | | | 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 | * @param stream A stream from which the ZIP archive will be read. * For read and append mode, this needs to be an OFSeekableStream. * @param mode The mode for the ZIP file. Valid modes are "r" for reading, * "w" for creating a new file and "a" for appending to an existing * archive. * @return An initialized OFZIPArchive */ - (instancetype)initWithStream: (OFStream *)stream mode: (OFString *)mode OF_DESIGNATED_INITIALIZER; #ifdef OF_HAVE_FILES /*! * @brief Initializes an already allocated OFZIPArchive object with the * specified file. * |
︙ | ︙ |
Modified src/OFZIPArchive.m from [a406f55747] to [ebb48a8010].
︙ | ︙ | |||
72 73 74 75 76 77 78 | - (instancetype)initWithStream: (OFStream *)stream; - (bool)matchesEntry: (OFZIPArchiveEntry *)entry; @end @interface OFZIPArchive_FileReadStream: OFStream { | | | | 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 | - (instancetype)initWithStream: (OFStream *)stream; - (bool)matchesEntry: (OFZIPArchiveEntry *)entry; @end @interface OFZIPArchive_FileReadStream: OFStream { OFStream *_stream; OFStream *_decompressedStream; OFZIPArchiveEntry *_entry; uint64_t _toRead; uint32_t _CRC32; bool _atEndOfStream; } - (instancetype)of_initWithStream: (OFStream *)stream |
︙ | ︙ | |||
139 140 141 142 143 144 145 | seekOrThrowInvalidFormat(OFSeekableStream *stream, of_offset_t offset, int whence) { @try { [stream seekToOffset: offset whence: whence]; } @catch (OFSeekFailedException *e) { | | | | | 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 | seekOrThrowInvalidFormat(OFSeekableStream *stream, of_offset_t offset, int whence) { @try { [stream seekToOffset: offset whence: whence]; } @catch (OFSeekFailedException *e) { if (e.errNo == EINVAL) @throw [OFInvalidFormatException exception]; @throw e; } } @implementation OFZIPArchive @synthesize archiveComment = _archiveComment; + (instancetype)archiveWithStream: (OFStream *)stream mode: (OFString *)mode { return [[[self alloc] initWithStream: stream mode: mode] autorelease]; } #ifdef OF_HAVE_FILES + (instancetype)archiveWithPath: (OFString *)path mode: (OFString *)mode { return [[[self alloc] initWithPath: path mode: mode] autorelease]; } #endif - (instancetype)init { OF_INVALID_INIT_METHOD } - (instancetype)initWithStream: (OFStream *)stream mode: (OFString *)mode { self = [super init]; @try { if ([mode isEqual: @"r"]) _mode = OF_ZIP_ARCHIVE_MODE_READ; |
︙ | ︙ | |||
200 201 202 203 204 205 206 | [self of_readZIPInfo]; [self of_readEntries]; } if (_mode == OF_ZIP_ARCHIVE_MODE_APPEND) { _offset = _centralDirectoryOffset; | | | 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 | [self of_readZIPInfo]; [self of_readEntries]; } if (_mode == OF_ZIP_ARCHIVE_MODE_APPEND) { _offset = _centralDirectoryOffset; seekOrThrowInvalidFormat((OFSeekableStream *)_stream, (of_offset_t)_offset, SEEK_SET); } } @catch (id e) { /* * If we are in write or append mode, we do not want -[close] * to write anything to it on error - after all, it might not * be a ZIP file which we would destroy otherwise. |
︙ | ︙ | |||
264 265 266 267 268 269 270 | { void *pool = objc_autoreleasePoolPush(); uint16_t commentLength; of_offset_t offset = -22; bool valid = false; do { | > | | 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 | { void *pool = objc_autoreleasePoolPush(); uint16_t commentLength; of_offset_t offset = -22; bool valid = false; do { seekOrThrowInvalidFormat((OFSeekableStream *)_stream, offset, SEEK_END); if ([_stream readLittleEndianInt32] == 0x06054B50) { valid = true; break; } } while (--offset >= -65557); |
︙ | ︙ | |||
296 297 298 299 300 301 302 | _centralDirectoryEntriesInDisk == 0xFFFF || _centralDirectoryEntries == 0xFFFF || _centralDirectorySize == 0xFFFFFFFF || _centralDirectoryOffset == 0xFFFFFFFF) { int64_t offset64; uint64_t size; | > | | | 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 | _centralDirectoryEntriesInDisk == 0xFFFF || _centralDirectoryEntries == 0xFFFF || _centralDirectorySize == 0xFFFFFFFF || _centralDirectoryOffset == 0xFFFFFFFF) { int64_t offset64; uint64_t size; seekOrThrowInvalidFormat((OFSeekableStream *)_stream, offset - 20, SEEK_END); if ([_stream readLittleEndianInt32] != 0x07064B50) { objc_autoreleasePoolPop(pool); return; } /* * FIXME: Handle number of the disk containing ZIP64 end of * central directory record. */ [_stream readLittleEndianInt32]; offset64 = [_stream readLittleEndianInt64]; if (offset64 < 0 || (of_offset_t)offset64 != offset64) @throw [OFOutOfRangeException exception]; seekOrThrowInvalidFormat((OFSeekableStream *)_stream, (of_offset_t)offset64, SEEK_SET); if ([_stream readLittleEndianInt32] != 0x06064B50) @throw [OFInvalidFormatException exception]; size = [_stream readLittleEndianInt64]; if (size < 44) |
︙ | ︙ | |||
353 354 355 356 357 358 359 | { void *pool = objc_autoreleasePoolPush(); if (_centralDirectoryOffset < 0 || (of_offset_t)_centralDirectoryOffset != _centralDirectoryOffset) @throw [OFOutOfRangeException exception]; | | | | | | 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 | { void *pool = objc_autoreleasePoolPush(); if (_centralDirectoryOffset < 0 || (of_offset_t)_centralDirectoryOffset != _centralDirectoryOffset) @throw [OFOutOfRangeException exception]; seekOrThrowInvalidFormat((OFSeekableStream *)_stream, (of_offset_t)_centralDirectoryOffset, SEEK_SET); for (size_t i = 0; i < _centralDirectoryEntries; i++) { OFZIPArchiveEntry *entry = [[[OFZIPArchiveEntry alloc] of_initWithStream: _stream] autorelease]; if ([_pathToEntryMap objectForKey: entry.fileName] != nil) @throw [OFInvalidFormatException exception]; [_entries addObject: entry]; [_pathToEntryMap setObject: entry forKey: entry.fileName]; } objc_autoreleasePoolPop(pool); } - (OFArray *)entries { return [[_entries copy] autorelease]; } - (OFString *)archiveComment { return _archiveComment; } - (void)setArchiveComment: (OFString *)comment { void *pool = objc_autoreleasePoolPush(); OFString *old; if (comment.UTF8StringLength > UINT16_MAX) @throw [OFOutOfRangeException exception]; old = _archiveComment; _archiveComment = [comment copy]; [old release]; objc_autoreleasePoolPop(pool); |
︙ | ︙ | |||
440 441 442 443 444 445 446 | if ((entry = [_pathToEntryMap objectForKey: path]) == nil) @throw [OFOpenItemFailedException exceptionWithPath: path mode: @"r" errNo: ENOENT]; [self of_closeLastReturnedStream]; | | > | | 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 | 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 = [[[OFZIPArchive_LocalFileHeader alloc] initWithStream: _stream] autorelease]; if (![localFileHeader matchesEntry: entry]) @throw [OFInvalidFormatException exception]; if ((localFileHeader->_minVersionNeeded & 0xFF) > 45) { |
︙ | ︙ | |||
486 487 488 489 490 491 492 | if (_mode != OF_ZIP_ARCHIVE_MODE_WRITE && _mode != OF_ZIP_ARCHIVE_MODE_APPEND) @throw [OFInvalidArgumentException exception]; pool = objc_autoreleasePoolPush(); entry = [[entry_ mutableCopy] autorelease]; | | | | | | | | | | | | | < | | | | | | | | 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 | if (_mode != OF_ZIP_ARCHIVE_MODE_WRITE && _mode != OF_ZIP_ARCHIVE_MODE_APPEND) @throw [OFInvalidArgumentException exception]; pool = objc_autoreleasePoolPush(); entry = [[entry_ mutableCopy] autorelease]; if ([_pathToEntryMap objectForKey: entry.fileName] != nil) @throw [OFOpenItemFailedException exceptionWithPath: entry.fileName mode: @"w" errNo: EEXIST]; if (entry.compressionMethod != OF_ZIP_ARCHIVE_ENTRY_COMPRESSION_METHOD_NONE) @throw [OFNotImplementedException exceptionWithSelector: _cmd object: self]; [self of_closeLastReturnedStream]; fileName = entry.fileName; fileNameLength = fileName.UTF8StringLength; extraField = entry.extraField; extraFieldLength = extraField.count; if (UINT16_MAX - extraFieldLength < 20) @throw [OFOutOfRangeException exception]; entry.versionMadeBy = (entry.versionMadeBy & 0xFF00) | 45; entry.minVersionNeeded = (entry.minVersionNeeded & 0xFF00) | 45; entry.compressedSize = 0; entry.uncompressedSize = 0; entry.CRC32 = 0; entry.generalPurposeBitFlag |= (1 << 3) | (1 << 11); entry.of_localFileHeaderOffset = _offset; [_stream writeLittleEndianInt32: 0x04034B50]; [_stream writeLittleEndianInt16: entry.minVersionNeeded]; [_stream writeLittleEndianInt16: entry.generalPurposeBitFlag]; [_stream writeLittleEndianInt16: entry.compressionMethod]; [_stream writeLittleEndianInt16: entry.of_lastModifiedFileTime]; [_stream writeLittleEndianInt16: entry.of_lastModifiedFileDate]; /* We use the data descriptor */ [_stream writeLittleEndianInt32: 0]; /* We use ZIP64 */ [_stream writeLittleEndianInt32: 0xFFFFFFFF]; [_stream writeLittleEndianInt32: 0xFFFFFFFF]; [_stream writeLittleEndianInt16: fileNameLength]; [_stream writeLittleEndianInt16: extraFieldLength + 20]; |
︙ | ︙ | |||
602 603 604 605 606 607 608 | [_stream writeLittleEndianInt32: 0x06054B50]; [_stream writeLittleEndianInt16: 0xFFFF]; /* Disk number */ [_stream writeLittleEndianInt16: 0xFFFF]; /* CD disk */ [_stream writeLittleEndianInt16: 0xFFFF]; /* CD entries in disk */ [_stream writeLittleEndianInt16: 0xFFFF]; /* CD entries */ [_stream writeLittleEndianInt32: 0xFFFFFFFF]; /* CD size */ [_stream writeLittleEndianInt32: 0xFFFFFFFF]; /* CD offset */ | | | 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 | [_stream writeLittleEndianInt32: 0x06054B50]; [_stream writeLittleEndianInt16: 0xFFFF]; /* Disk number */ [_stream writeLittleEndianInt16: 0xFFFF]; /* CD disk */ [_stream writeLittleEndianInt16: 0xFFFF]; /* CD entries in disk */ [_stream writeLittleEndianInt16: 0xFFFF]; /* CD entries */ [_stream writeLittleEndianInt32: 0xFFFFFFFF]; /* CD size */ [_stream writeLittleEndianInt32: 0xFFFFFFFF]; /* CD offset */ [_stream writeLittleEndianInt16: _archiveComment.UTF8StringLength]; if (_archiveComment != nil) [_stream writeString: _archiveComment]; objc_autoreleasePoolPop(pool); } - (void)close |
︙ | ︙ | |||
683 684 685 686 687 688 689 | if (ZIP64Size > 0) @throw [OFInvalidFormatException exception]; [extraField removeItemsInRange: range]; } | | | 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 | if (ZIP64Size > 0) @throw [OFInvalidFormatException exception]; [extraField removeItemsInRange: range]; } if (extraField.count > 0) { [extraField makeImmutable]; _extraField = [extraField copy]; } objc_autoreleasePoolPop(pool); } @catch (id e) { [self release]; |
︙ | ︙ | |||
707 708 709 710 711 712 713 | [_extraField release]; [super dealloc]; } - (bool)matchesEntry: (OFZIPArchiveEntry *)entry { | | | | | | | | | | | 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 | [_extraField release]; [super dealloc]; } - (bool)matchesEntry: (OFZIPArchiveEntry *)entry { if (_compressionMethod != entry.compressionMethod || _lastModifiedFileTime != entry.of_lastModifiedFileTime || _lastModifiedFileDate != entry.of_lastModifiedFileDate) return false; if (!(_generalPurposeBitFlag & (1 << 3))) if (_CRC32 != entry.CRC32 || _compressedSize != entry.compressedSize || _uncompressedSize != entry.uncompressedSize) return false; if (![_fileName isEqual: entry.fileName]) return false; return true; } @end @implementation OFZIPArchive_FileReadStream - (instancetype)of_initWithStream: (OFStream *)stream entry: (OFZIPArchiveEntry *)entry { self = [super init]; @try { _stream = [stream retain]; switch (entry.compressionMethod) { case OF_ZIP_ARCHIVE_ENTRY_COMPRESSION_METHOD_NONE: _decompressedStream = [stream retain]; break; case OF_ZIP_ARCHIVE_ENTRY_COMPRESSION_METHOD_DEFLATE: _decompressedStream = [[OFInflateStream alloc] initWithStream: stream]; break; case OF_ZIP_ARCHIVE_ENTRY_COMPRESSION_METHOD_DEFLATE64: _decompressedStream = [[OFInflate64Stream alloc] initWithStream: stream]; break; default: @throw [OFNotImplementedException exceptionWithSelector: _cmd object: self]; } _entry = [entry copy]; _toRead = entry.uncompressedSize; _CRC32 = ~0; } @catch (id e) { [self release]; @throw e; } return self; |
︙ | ︙ | |||
793 794 795 796 797 798 799 | if (_stream == nil) @throw [OFNotOpenException exceptionWithObject: self]; if (_atEndOfStream) return 0; | < | | | | | > | | 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 | if (_stream == nil) @throw [OFNotOpenException exceptionWithObject: self]; if (_atEndOfStream) return 0; if (_stream.atEndOfStream && !_decompressedStream.hasDataInReadBuffer) @throw [OFTruncatedDataException exception]; #if SIZE_MAX >= UINT64_MAX if (length > UINT64_MAX) @throw [OFOutOfRangeException exception]; #endif if ((uint64_t)length > _toRead) length = (size_t)_toRead; ret = [_decompressedStream readIntoBuffer: buffer length: length]; _toRead -= ret; _CRC32 = of_crc32(_CRC32, buffer, ret); if (_toRead == 0) { _atEndOfStream = true; if (~_CRC32 != _entry.CRC32) { OFString *actualChecksum = [OFString stringWithFormat: @"%08" PRIX32, ~_CRC32]; OFString *expectedChecksum = [OFString stringWithFormat: @"%08" PRIX32, _entry.CRC32]; @throw [OFChecksumMismatchException exceptionWithActualChecksum: actualChecksum expectedChecksum: expectedChecksum]; } } return ret; } - (bool)hasDataInReadBuffer { return (super.hasDataInReadBuffer || _decompressedStream.hasDataInReadBuffer); } - (int)fileDescriptorForReading { return ((id <OFReadyForReadingObserving>)_decompressedStream) .fileDescriptorForReading; } - (void)close { [_stream release]; _stream = nil; |
︙ | ︙ | |||
910 911 912 913 914 915 916 | [_stream writeLittleEndianInt32: _CRC32]; [_stream writeLittleEndianInt64: _bytesWritten]; [_stream writeLittleEndianInt64: _bytesWritten]; [_stream release]; _stream = nil; | | | | | 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 | [_stream writeLittleEndianInt32: _CRC32]; [_stream writeLittleEndianInt64: _bytesWritten]; [_stream writeLittleEndianInt64: _bytesWritten]; [_stream release]; _stream = nil; _entry.CRC32 = ~_CRC32; _entry.compressedSize = _bytesWritten; _entry.uncompressedSize = _bytesWritten; [_entry makeImmutable]; _bytesWritten += (2 * 4 + 2 * 8); } @end |
Modified src/OFZIPArchiveEntry.m from [ef9c9a9140] to [d12805fb90].
︙ | ︙ | |||
144 145 146 147 148 149 150 | } } size_t of_zip_archive_entry_extra_field_find(OFData *extraField, uint16_t tag, uint16_t *size) { | | | | 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 | } } size_t of_zip_archive_entry_extra_field_find(OFData *extraField, uint16_t tag, uint16_t *size) { const uint8_t *bytes = extraField.items; size_t count = extraField.count; for (size_t i = 0; i < count;) { uint16_t currentTag, currentSize; if (i + 3 >= count) @throw [OFInvalidFormatException exception]; |
︙ | ︙ | |||
189 190 191 192 193 194 195 | - (instancetype)initWithFileName: (OFString *)fileName { self = [super init]; @try { void *pool = objc_autoreleasePoolPush(); | | | 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 | - (instancetype)initWithFileName: (OFString *)fileName { self = [super init]; @try { void *pool = objc_autoreleasePoolPush(); if (fileName.UTF8StringLength > UINT16_MAX) @throw [OFOutOfRangeException exception]; _fileName = [fileName copy]; objc_autoreleasePoolPop(pool); } @catch (id e) { [self release]; |
︙ | ︙ | |||
278 279 280 281 282 283 284 | if (ZIP64Size > 0 || _localFileHeaderOffset < 0) @throw [OFInvalidFormatException exception]; [extraField removeItemsInRange: range]; } | | | 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 | if (ZIP64Size > 0 || _localFileHeaderOffset < 0) @throw [OFInvalidFormatException exception]; [extraField removeItemsInRange: range]; } if (extraField.count > 0) { [extraField makeImmutable]; _extraField = [extraField copy]; } objc_autoreleasePoolPop(pool); } @catch (id e) { [self release]; |
︙ | ︙ | |||
447 448 449 450 451 452 453 | @"\tCompressed size = %" @PRIu64 "\n" @"\tUncompressed size = %" @PRIu64 "\n" @"\tCompression method = %@\n" @"\tModification date = %@\n" @"\tCRC32 = %08" @PRIX32 @"\n" @"\tExtra field = %@\n" @">", | | | | | | | | | | | 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 | @"\tCompressed size = %" @PRIu64 "\n" @"\tUncompressed size = %" @PRIu64 "\n" @"\tCompression method = %@\n" @"\tModification date = %@\n" @"\tCRC32 = %08" @PRIX32 @"\n" @"\tExtra field = %@\n" @">", self.class, _fileName, _fileComment, _generalPurposeBitFlag, _compressedSize, _uncompressedSize, compressionMethod, self.modificationDate, _CRC32, _extraField]; [ret retain]; objc_autoreleasePoolPop(pool); return [ret autorelease]; } - (uint64_t)of_writeToStream: (OFStream *)stream { void *pool = objc_autoreleasePoolPush(); uint64_t size = 0; if (UINT16_MAX - _extraField.count < 32) @throw [OFOutOfRangeException exception]; [stream writeLittleEndianInt32: 0x02014B50]; [stream writeLittleEndianInt16: _versionMadeBy]; [stream writeLittleEndianInt16: _minVersionNeeded]; [stream writeLittleEndianInt16: _generalPurposeBitFlag]; [stream writeLittleEndianInt16: _compressionMethod]; [stream writeLittleEndianInt16: _lastModifiedFileTime]; [stream writeLittleEndianInt16: _lastModifiedFileDate]; [stream writeLittleEndianInt32: _CRC32]; [stream writeLittleEndianInt32: 0xFFFFFFFF]; [stream writeLittleEndianInt32: 0xFFFFFFFF]; [stream writeLittleEndianInt16: (uint16_t)_fileName.UTF8StringLength]; [stream writeLittleEndianInt16: (uint16_t)_extraField.count + 32]; [stream writeLittleEndianInt16: (uint16_t)_fileComment.UTF8StringLength]; [stream writeLittleEndianInt16: 0xFFFF]; [stream writeLittleEndianInt16: _internalAttributes]; [stream writeLittleEndianInt32: _versionSpecificAttributes]; [stream writeLittleEndianInt32: 0xFFFFFFFF]; size += (4 + (6 * 2) + (3 * 4) + (5 * 2) + (2 * 4)); [stream writeString: _fileName]; size += (uint64_t)_fileName.UTF8StringLength; [stream writeLittleEndianInt16: OF_ZIP_ARCHIVE_ENTRY_EXTRA_FIELD_ZIP64]; [stream writeLittleEndianInt16: 28]; [stream writeLittleEndianInt64: _uncompressedSize]; [stream writeLittleEndianInt64: _compressedSize]; [stream writeLittleEndianInt64: _localFileHeaderOffset]; [stream writeLittleEndianInt32: _startDiskNumber]; size += (2 * 2) + (3 * 8) + 4; if (_extraField != nil) [stream writeData: _extraField]; size += (uint64_t)_extraField.count; if (_fileComment != nil) [stream writeString: _fileComment]; size += (uint64_t)_fileComment.UTF8StringLength; objc_autoreleasePoolPop(pool); return size; } @end |
Modified src/base64.m from [8870eb10c8] to [5c79c97e1a].
︙ | ︙ | |||
101 102 103 104 105 106 107 | { const uint8_t *buffer = (const uint8_t *)string; size_t i; if ((length & 3) != 0) return false; | | | 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 | { const uint8_t *buffer = (const uint8_t *)string; size_t i; if ((length & 3) != 0) return false; if (data.itemSize != 1) return false; for (i = 0; i < length; i += 4) { uint32_t sb = 0; uint8_t count = 3; char db[3]; int8_t tmp; |
︙ | ︙ |
Modified src/bridge/NSArray_OFArray.m from [b2b37f6565] to [48bc1264c2].
︙ | ︙ | |||
43 44 45 46 47 48 49 | return [object NSObject]; return object; } - (NSUInteger)count { | | | 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 | return [object NSObject]; return object; } - (NSUInteger)count { size_t count = _array.count; if (count > NSUIntegerMax) @throw [OFOutOfRangeException exception]; return (NSUInteger)count; } @end |
Modified src/bridge/NSBridging.h from [da42c5052c] to [1b3ca80d51].
︙ | ︙ | |||
38 39 40 41 42 43 44 | * @brief Returns an instance of an ObjFW object corresponding to the receiver. * * If possible, the original object is wrapped. If this is not possible, an * autoreleased copy is created. * * @return The receiver as an ObjFW object */ | | | 38 39 40 41 42 43 44 45 46 47 48 | * @brief Returns an instance of an ObjFW object corresponding to the receiver. * * If possible, the original object is wrapped. If this is not possible, an * autoreleased copy is created. * * @return The receiver as an ObjFW object */ @property (readonly, nonatomic) id OFObject; @end OF_ASSUME_NONNULL_END |
Modified src/bridge/NSDictionary_OFDictionary.m from [a3c8b1ddd3] to [d509c1b2b1].
︙ | ︙ | |||
50 51 52 53 54 55 56 | return [object NSObject]; return object; } - (NSUInteger)count { | | | 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 | 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/NSString+OFObject.m from [8716e136d6] to [4604799e9f].
︙ | ︙ | |||
19 20 21 22 23 24 25 | #import "OFString.h" int _NSString_OFObject_reference; @implementation NSString (OFObject) - (id)OFObject { | | | 19 20 21 22 23 24 25 26 27 28 | #import "OFString.h" int _NSString_OFObject_reference; @implementation NSString (OFObject) - (id)OFObject { return [OFString stringWithUTF8String: self.UTF8String]; } @end |
Modified src/bridge/OFArray_NSArray.m from [74dc53d6fa] to [48af716058].
︙ | ︙ | |||
27 28 29 30 31 32 33 | - (instancetype)initWithNSArray: (NSArray *)array { self = [super init]; @try { if (array == nil) @throw [OFInitializationFailedException | | | 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | - (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; } |
︙ | ︙ | |||
55 56 57 58 59 60 61 | return [object OFObject]; return object; } - (size_t)count { | | | 55 56 57 58 59 60 61 62 63 64 | return [object OFObject]; return object; } - (size_t)count { return _array.count; } @end |
Modified src/bridge/OFBridging.h from [ddb7c293c6] to [441e4ae6c2].
︙ | ︙ | |||
39 40 41 42 43 44 45 | * receiver. * * If possible, the original object is wrapped. If this is not possible, an * autoreleased copy is created. * * @return The receiver as Foundation object */ | | | 39 40 41 42 43 44 45 46 47 48 49 | * receiver. * * If possible, the original object is wrapped. If this is not possible, an * autoreleased copy is created. * * @return The receiver as Foundation object */ @property (readonly, nonatomic) id NSObject; @end OF_ASSUME_NONNULL_END |
Modified src/bridge/OFDictionary_NSDictionary.m from [62f35cbb79] to [6f3ba7ec5c].
︙ | ︙ | |||
28 29 30 31 32 33 34 | - (instancetype)initWithNSDictionary: (NSDictionary *)dictionary { self = [super init]; @try { if (dictionary == nil) @throw [OFInitializationFailedException | | | 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | - (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; } |
︙ | ︙ | |||
56 57 58 59 60 61 62 | return [object OFObject]; return object; } - (size_t)count { | | | 56 57 58 59 60 61 62 63 64 65 | return [object OFObject]; return object; } - (size_t)count { return _dictionary.count; } @end |
Modified src/bridge/OFString+NSObject.m from [50b50754ec] to [b02ed78e50].
︙ | ︙ | |||
22 23 24 25 26 27 28 | #import "OFInitializationFailedException.h" int _OFString_NSObject_reference; @implementation OFString (NSObject) - (id)NSObject { | | | 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | #import "OFInitializationFailedException.h" int _OFString_NSObject_reference; @implementation OFString (NSObject) - (id)NSObject { NSString *string = [NSString stringWithUTF8String: self.UTF8String]; if (string == nil) @throw [OFInitializationFailedException exceptionWithClass: [NSString class]]; return string; } @end |
Modified src/exceptions/OFConditionBroadcastFailedException.m from [818bacfec1] to [c0d37d74d8].
︙ | ︙ | |||
51 52 53 54 55 56 57 | } - (OFString *)description { if (_condition != nil) return [OFString stringWithFormat: @"Broadcasting a condition of type %@ failed!", | | | 51 52 53 54 55 56 57 58 59 60 61 62 | } - (OFString *)description { if (_condition != nil) return [OFString stringWithFormat: @"Broadcasting a condition of type %@ failed!", _condition.class]; else return @"Broadcasting a condition failed!"; } @end |
Modified src/exceptions/OFConditionSignalFailedException.m from [7cf102178e] to [a0b8d7c91b].
︙ | ︙ | |||
51 52 53 54 55 56 57 | } - (OFString *)description { if (_condition != nil) return [OFString stringWithFormat: @"Signaling a condition of type %@ failed!", | | | 51 52 53 54 55 56 57 58 59 60 61 62 | } - (OFString *)description { if (_condition != nil) return [OFString stringWithFormat: @"Signaling a condition of type %@ failed!", _condition.class]; else return @"Signaling a condition failed!"; } @end |
Modified src/exceptions/OFConditionStillWaitingException.m from [3fa8245c6c] to [88255bff6f].
︙ | ︙ | |||
52 53 54 55 56 57 58 | - (OFString *)description { if (_condition != nil) return [OFString stringWithFormat: @"Deallocation of a condition of type %@ was tried, even " "though a thread was still waiting for it!", | | | 52 53 54 55 56 57 58 59 60 61 62 63 64 | - (OFString *)description { if (_condition != nil) return [OFString stringWithFormat: @"Deallocation of a condition of type %@ was tried, even " "though a thread was still waiting for it!", _condition.class]; else return @"Deallocation of a condition was tried, even though a " "thread was still waiting for it!"; } @end |
Modified src/exceptions/OFConditionWaitFailedException.m from [ed882483df] to [872efbe506].
︙ | ︙ | |||
51 52 53 54 55 56 57 | } - (OFString *)description { if (_condition != nil) return [OFString stringWithFormat: @"Waiting for a condition of type %@ failed!", | | | 51 52 53 54 55 56 57 58 59 60 61 62 | } - (OFString *)description { if (_condition != nil) return [OFString stringWithFormat: @"Waiting for a condition of type %@ failed!", _condition.class]; else return @"Waiting for a condition failed!"; } @end |
Modified src/exceptions/OFException.m from [168ff4f79b] to [fde76d6a75].
︙ | ︙ | |||
272 273 274 275 276 277 278 | return self; } #endif - (OFString *)description { return [OFString stringWithFormat: | | | 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 | return self; } #endif - (OFString *)description { return [OFString stringWithFormat: @"An exception of type %@ occurred!", self.class]; } - (OFArray OF_GENERIC(OFString *) *)backtrace { #ifdef HAVE__UNWIND_BACKTRACE OFMutableArray OF_GENERIC(OFString *) *backtrace = [OFMutableArray array]; |
︙ | ︙ |
Modified src/exceptions/OFGetOptionFailedException.m from [1cc76fa0b0] to [e227c18ccc].
︙ | ︙ | |||
59 60 61 62 63 64 65 | [super dealloc]; } - (OFString *)description { return [OFString stringWithFormat: @"Getting an option in a stream of type %@ failed: %@", | | | 59 60 61 62 63 64 65 66 67 68 | [super dealloc]; } - (OFString *)description { return [OFString stringWithFormat: @"Getting an option in a stream of type %@ failed: %@", _stream.class, of_strerror(_errNo)]; } @end |
Modified src/exceptions/OFHTTPRequestFailedException.m from [b33d383c3b] to [c006f7c54d].
︙ | ︙ | |||
59 60 61 62 63 64 65 | [_response release]; [super dealloc]; } - (OFString *)description { | | < | | 59 60 61 62 63 64 65 66 67 68 69 70 71 72 | [_response release]; [super dealloc]; } - (OFString *)description { const char *method = of_http_request_method_to_string(_request.method); return [OFString stringWithFormat: @"An HTTP %s request with URL %@ failed with code %d!", method, _request.URL, _response.statusCode]; } @end |
Modified src/exceptions/OFLockFailedException.m from [917c5fce63] to [5ebc5106e3].
︙ | ︙ | |||
49 50 51 52 53 54 55 | [super dealloc]; } - (OFString *)description { if (_lock != nil) return [OFString stringWithFormat: | | | 49 50 51 52 53 54 55 56 57 58 59 60 | [super dealloc]; } - (OFString *)description { if (_lock != nil) return [OFString stringWithFormat: @"A lock of type %@ could not be locked!", _lock.class]; else return @"A lock could not be locked!"; } @end |
Modified src/exceptions/OFMalformedXMLException.m from [85b84d379a] to [03c1cd11c5].
︙ | ︙ | |||
51 52 53 54 55 56 57 | } - (OFString *)description { if (_parser != nil) return [OFString stringWithFormat: @"An XML parser of type %@ encountered malformed XML in " | | | 51 52 53 54 55 56 57 58 59 60 61 62 | } - (OFString *)description { if (_parser != nil) return [OFString stringWithFormat: @"An XML parser of type %@ encountered malformed XML in " @"line %zu!", _parser.class, _parser.lineNumber]; else return @"An XML parser encountered malformed XML!"; } @end |
Modified src/exceptions/OFObserveFailedException.m from [790e9c0e69] to [6c8df61c71].
︙ | ︙ | |||
64 65 66 67 68 69 70 | [super dealloc]; } - (OFString *)description { return [OFString stringWithFormat: @"An observer of class %@ failed to observe: %@", | | | 64 65 66 67 68 69 70 71 72 73 | [super dealloc]; } - (OFString *)description { return [OFString stringWithFormat: @"An observer of class %@ failed to observe: %@", _observer.class, of_strerror(_errNo)]; } @end |
Modified src/exceptions/OFSeekFailedException.m from [58dd984cfb] to [2e85de50c3].
︙ | ︙ | |||
68 69 70 71 72 73 74 | [super dealloc]; } - (OFString *)description { return [OFString stringWithFormat: @"Seeking failed in stream of type %@: %@", | | | 68 69 70 71 72 73 74 75 76 77 | [super dealloc]; } - (OFString *)description { return [OFString stringWithFormat: @"Seeking failed in stream of type %@: %@", _stream.class, of_strerror(_errNo)]; } @end |
Modified src/exceptions/OFStillLockedException.m from [abb4e51f4a] to [bee06f8528].
︙ | ︙ | |||
50 51 52 53 54 55 56 | } - (OFString *)description { if (_lock != nil) return [OFString stringWithFormat: @"Deallocation of a lock of type %@ even though it was " | | | 50 51 52 53 54 55 56 57 58 59 60 61 62 | } - (OFString *)description { if (_lock != nil) return [OFString stringWithFormat: @"Deallocation of a lock of type %@ even though it was " @"still locked!", _lock.class]; else return @"Deallocation of a lock even though it was still " @"locked!"; } @end |
Modified src/exceptions/OFThreadJoinFailedException.m from [7b4e9d8e39] to [8453050bf7].
︙ | ︙ | |||
52 53 54 55 56 57 58 | - (OFString *)description { if (_thread != nil) return [OFString stringWithFormat: @"Joining a thread of type %@ failed! Most likely, another " @"thread already waits for the thread to join.", | | | 52 53 54 55 56 57 58 59 60 61 62 63 64 | - (OFString *)description { if (_thread != nil) return [OFString stringWithFormat: @"Joining a thread of type %@ failed! Most likely, another " @"thread already waits for the thread to join.", _thread.class]; else return @"Joining a thread failed! Most likely, another thread " @"already waits for the thread to join."; } @end |
Modified src/exceptions/OFThreadStartFailedException.m from [c9a1338f9d] to [0346f15b9f].
︙ | ︙ | |||
50 51 52 53 54 55 56 | [super dealloc]; } - (OFString *)description { if (_thread != nil) return [OFString stringWithFormat: | | | 50 51 52 53 54 55 56 57 58 59 60 61 | [super dealloc]; } - (OFString *)description { if (_thread != nil) return [OFString stringWithFormat: @"Starting a thread of type %@ failed!", _thread.class]; else return @"Starting a thread failed!"; } @end |
Modified src/exceptions/OFThreadStillRunningException.m from [6701777632] to [0f17a0cae3].
︙ | ︙ | |||
52 53 54 55 56 57 58 | - (OFString *)description { if (_thread) return [OFString stringWithFormat: @"Deallocation of a thread of type %@ was tried, even " @"though it was still running!", | | | 52 53 54 55 56 57 58 59 60 61 62 63 64 | - (OFString *)description { if (_thread) return [OFString stringWithFormat: @"Deallocation of a thread of type %@ was tried, even " @"though it was still running!", _thread.class]; else return @"Deallocation of a thread was tried, even though it " @"was still running!"; } @end |
Modified src/exceptions/OFUnboundNamespaceException.m from [c9f5da877a] to [010c318107].
︙ | ︙ | |||
65 66 67 68 69 70 71 | [super dealloc]; } - (OFString *)description { return [OFString stringWithFormat: @"The namespace %@ is not bound in an element of type %@!", | | | 65 66 67 68 69 70 71 72 73 74 | [super dealloc]; } - (OFString *)description { return [OFString stringWithFormat: @"The namespace %@ is not bound in an element of type %@!", _namespace, _element.class]; } @end |
Modified src/exceptions/OFUnboundPrefixException.m from [3f6fe5c924] to [c97c6c3e6a].
︙ | ︙ | |||
65 66 67 68 69 70 71 | [super dealloc]; } - (OFString *)description { return [OFString stringWithFormat: @"An XML parser of type %@ encountered the unbound prefix %@ in " | | | 65 66 67 68 69 70 71 72 73 74 | [super dealloc]; } - (OFString *)description { return [OFString stringWithFormat: @"An XML parser of type %@ encountered the unbound prefix %@ in " @"line %zu!", _parser.class, _prefix, _parser.lineNumber]; } @end |
Modified src/exceptions/OFUnlockFailedException.m from [f5eb2bdfd8] to [cdcb8469af].
︙ | ︙ | |||
49 50 51 52 53 54 55 | [super dealloc]; } - (OFString *)description { if (_lock != nil) return [OFString stringWithFormat: | | | 49 50 51 52 53 54 55 56 57 58 59 60 | [super dealloc]; } - (OFString *)description { if (_lock != nil) return [OFString stringWithFormat: @"A lock of type %@ could not be unlocked!", _lock.class]; else return @"A lock could not be unlocked!"; } @end |
Modified src/invocation/invoke-x86_64.m from [47d3793287] to [5df8286fd6].
︙ | ︙ | |||
189 190 191 192 193 194 195 | *context = newContext; } #endif void of_invocation_invoke(OFInvocation *invocation) { | | | | 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 | *context = newContext; } #endif void of_invocation_invoke(OFInvocation *invocation) { OFMethodSignature *methodSignature = invocation.methodSignature; size_t numberOfArguments = methodSignature.numberOfArguments; struct call_context *context; const char *typeEncoding; uint_fast8_t currentGPR = 0, currentSSE = 0; if ((context = calloc(sizeof(*context), 1)) == NULL) @throw [OFOutOfMemoryException exception]; |
︙ | ︙ | |||
306 307 308 309 310 311 312 | /* TODO: '(' */ default: free(context); @throw [OFInvalidFormatException exception]; } } | | | 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 | /* TODO: '(' */ default: free(context); @throw [OFInvalidFormatException exception]; } } typeEncoding = methodSignature.methodReturnType; if (*typeEncoding == 'r') typeEncoding++; switch (*typeEncoding) { case 'v': case 'c': |
︙ | ︙ |
Modified src/of_asprintf.m from [3f7a200743] to [53badc787e].
︙ | ︙ | |||
368 369 370 371 372 373 374 | @try { id object; if ((object = va_arg(ctx->arguments, id)) != nil) { void *pool = objc_autoreleasePoolPush(); tmpLen = asprintf(&tmp, ctx->subformat, | | | 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 | @try { id object; if ((object = va_arg(ctx->arguments, id)) != nil) { void *pool = objc_autoreleasePoolPush(); tmpLen = asprintf(&tmp, ctx->subformat, [object description].UTF8String); objc_autoreleasePoolPop(pool); } else tmpLen = asprintf(&tmp, ctx->subformat, "(nil)"); } @catch (id e) { free(ctx->buffer); |
︙ | ︙ | |||
562 563 564 565 566 567 568 | stringWithUTF8String: tmp length: tmpLen]; OFString *point = [OFLocale decimalPoint]; if (point != nil) [tmpStr replaceOccurrencesOfString: point withString: @"."]; | | | | | 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 | stringWithUTF8String: tmp length: tmpLen]; OFString *point = [OFLocale decimalPoint]; if (point != nil) [tmpStr replaceOccurrencesOfString: point withString: @"."]; if (tmpStr.UTF8StringLength > INT_MAX) return false; tmpLen = (int)tmpStr.UTF8StringLength; tmp2 = malloc(tmpLen); memcpy(tmp2, tmpStr.UTF8String, tmpLen); } @finally { free(tmp); objc_autoreleasePoolPop(pool); } tmp = tmp2; } |
︙ | ︙ |
Modified src/pbkdf2.m from [ba13c01e7e] to [8a2fd39e02].
︙ | ︙ | |||
30 31 32 33 34 35 36 | void of_pbkdf2(OFHMAC *HMAC, size_t iterations, const unsigned char *salt, size_t saltLength, const char *password, size_t passwordLength, unsigned char *key, size_t keyLength) { void *pool = objc_autoreleasePoolPush(); | | | | | | | | | 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 | void of_pbkdf2(OFHMAC *HMAC, size_t iterations, const unsigned char *salt, size_t saltLength, const char *password, size_t passwordLength, unsigned char *key, size_t keyLength) { void *pool = objc_autoreleasePoolPush(); size_t blocks, digestSize = HMAC.digestSize; OFSecureData *buffer = [OFSecureData dataWithCount: digestSize]; OFSecureData *digest = [OFSecureData dataWithCount: digestSize]; unsigned char *bufferItems = buffer.mutableItems; unsigned char *digestItems = digest.mutableItems; OFSecureData *extendedSalt; unsigned char *extendedSaltItems; if (HMAC == nil || iterations == 0 || salt == NULL || password == NULL || key == NULL || keyLength == 0) @throw [OFInvalidArgumentException exception]; blocks = keyLength / digestSize; if (keyLength % digestSize != 0) blocks++; if (saltLength > SIZE_MAX - 4 || blocks > UINT32_MAX) @throw [OFOutOfRangeException exception]; extendedSalt = [OFSecureData dataWithCount: saltLength + 4]; extendedSaltItems = extendedSalt.mutableItems; @try { uint32_t i = OF_BSWAP32_IF_LE(1); [HMAC setKey: password length: passwordLength]; memcpy(extendedSaltItems, salt, saltLength); while (keyLength > 0) { size_t length; memcpy(extendedSaltItems + saltLength, &i, 4); [HMAC reset]; [HMAC updateWithBuffer: extendedSaltItems length: saltLength + 4]; memcpy(bufferItems, HMAC.digest, digestSize); memcpy(digestItems, HMAC.digest, digestSize); for (size_t j = 1; j < iterations; j++) { [HMAC reset]; [HMAC updateWithBuffer: digestItems length: digestSize]; memcpy(digestItems, HMAC.digest, digestSize); for (size_t k = 0; k < digestSize; k++) bufferItems[k] ^= digestItems[k]; } length = digestSize; if (length > keyLength) |
︙ | ︙ |
Modified src/socket.m from [e7074a55dd] to [b2488d7024].
︙ | ︙ | |||
251 252 253 254 255 256 257 | addrIn->sin_port = OF_BSWAP16_IF_LE(port); #ifdef OF_WII addrIn->sin_len = ret.length; #endif components = [IPv4 componentsSeparatedByString: @"."]; | | | | | 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 | addrIn->sin_port = OF_BSWAP16_IF_LE(port); #ifdef OF_WII addrIn->sin_len = ret.length; #endif components = [IPv4 componentsSeparatedByString: @"."]; if (components.count != 4) @throw [OFInvalidFormatException exception]; addr = 0; for (OFString *component in components) { intmax_t number; if (component.length == 0) @throw [OFInvalidFormatException exception]; if ([component indexOfCharacterFromSet: whitespaceCharacterSet] != OF_NOT_FOUND) @throw [OFInvalidFormatException exception]; number = component.decimalValue; if (number < 0 || number > UINT8_MAX) @throw [OFInvalidFormatException exception]; addr = (addr << 8) | (number & 0xFF); } |
︙ | ︙ | |||
290 291 292 293 294 295 296 | { uintmax_t number; if ([component indexOfCharacterFromSet: [OFCharacterSet whitespaceCharacterSet]] != OF_NOT_FOUND) @throw [OFInvalidFormatException exception]; | | | 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 | { uintmax_t number; if ([component indexOfCharacterFromSet: [OFCharacterSet whitespaceCharacterSet]] != OF_NOT_FOUND) @throw [OFInvalidFormatException exception]; number = component.hexadecimalValue; if (number > UINT16_MAX) @throw [OFInvalidFormatException exception]; return (uint16_t)number; } |
︙ | ︙ | |||
323 324 325 326 327 328 329 | doubleColon = [IPv6 rangeOfString: @"::"].location; if (doubleColon != OF_NOT_FOUND) { OFString *left = [IPv6 substringWithRange: of_range(0, doubleColon)]; OFString *right = [IPv6 substringWithRange: | | | | | | | 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 | doubleColon = [IPv6 rangeOfString: @"::"].location; if (doubleColon != OF_NOT_FOUND) { OFString *left = [IPv6 substringWithRange: of_range(0, doubleColon)]; OFString *right = [IPv6 substringWithRange: of_range(doubleColon + 2, IPv6.length - doubleColon - 2)]; OFArray OF_GENERIC(OFString *) *leftComponents; OFArray OF_GENERIC(OFString *) *rightComponents; size_t i; if ([right hasPrefix: @":"] || [right containsString: @"::"]) @throw [OFInvalidFormatException exception]; leftComponents = [left componentsSeparatedByString: @":"]; rightComponents = [right componentsSeparatedByString: @":"]; if (leftComponents.count + rightComponents.count > 7) @throw [OFInvalidFormatException exception]; i = 0; for (OFString *component in leftComponents) { uint16_t number = parseIPv6Component(component); addrIn6->sin6_addr.s6_addr[i++] = number >> 8; addrIn6->sin6_addr.s6_addr[i++] = number; } i = 16; for (OFString *component in rightComponents.reversedArray) { uint16_t number = parseIPv6Component(component); addrIn6->sin6_addr.s6_addr[--i] = number >> 8; addrIn6->sin6_addr.s6_addr[--i] = number; } } else { OFArray OF_GENERIC(OFString *) *components = [IPv6 componentsSeparatedByString: @":"]; size_t i; if (components.count != 8) @throw [OFInvalidFormatException exception]; i = 0; for (OFString *component in components) { uint16_t number; if (component.length == 0) @throw [OFInvalidFormatException exception]; number = parseIPv6Component(component); addrIn6->sin6_addr.s6_addr[i++] = number >> 8; addrIn6->sin6_addr.s6_addr[i++] = number; } |
︙ | ︙ |
Modified src/threading_winapi.m from [eef2483c77] to [5c88d5e359].
︙ | ︙ | |||
29 30 31 32 33 34 35 | } bool of_thread_new(of_thread_t *thread, void (*function)(id), id object, const of_thread_attr_t *attr) { *thread = CreateThread(NULL, (attr != NULL ? attr->stackSize : 0), | | | 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | } bool of_thread_new(of_thread_t *thread, void (*function)(id), id object, const of_thread_attr_t *attr) { *thread = CreateThread(NULL, (attr != NULL ? attr->stackSize : 0), (LPTHREAD_START_ROUTINE)function, (void *)object, 0, NULL); if (thread == NULL) return false; if (attr != NULL && attr->priority != 0) { DWORD priority; |
︙ | ︙ |
Modified utils/ofhttp/OFHTTP.m from [fe54fd9353] to [1da76a65b7].
︙ | ︙ | |||
512 513 514 515 516 517 518 | [_HTTPClient setInsecureRedirectsAllowed: true]; [self performSelector: @selector(downloadNextURL) afterDelay: 0]; } - (void)client: (OFHTTPClient *)client | | | | 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 | [_HTTPClient setInsecureRedirectsAllowed: true]; [self performSelector: @selector(downloadNextURL) afterDelay: 0]; } - (void)client: (OFHTTPClient *)client didCreateSocket: (OFTCPSocket *)sock request: (OFHTTPRequest *)request { if (_insecure && [sock respondsToSelector: @selector(setCertificateVerificationEnabled:)]) ((id <OFTLSSocket>)sock).certificateVerificationEnabled = false; } - (void)client: (OFHTTPClient *)client wantsRequestBody: (OFStream *)body request: (OFHTTPRequest *)request { /* TODO: Do asynchronously and print status */ |
︙ | ︙ | |||
648 649 650 651 652 653 654 | } else @throw e; [self performSelector: @selector(downloadNextURL) afterDelay: 0]; } | | | 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 | } else @throw e; [self performSelector: @selector(downloadNextURL) afterDelay: 0]; } - (bool)stream: (OFStream *)response didReadIntoBuffer: (void *)buffer length: (size_t)length exception: (id)exception { if (exception != nil) { OFString *URL; |
︙ | ︙ |