Differences From Artifact [e04f7e1202]:
- File
src/OFUTF8String.m
— part of check-in
[0f260e0fd5]
at
2020-11-06 02:37:02
on branch trunk
— OFString: Make freeWhenDone behave like in OFData
In particular, this means that if initialization fails, the buffer is
NOT free'd. While freeing it on error in convenient when not handling
the error, it makes handling the error and retrying impossible (e.g.
retrying with a different encoding). (user: js, size: 28345) [annotate] [blame] [check-ins using]
To Artifact [4cdd46e0d2]:
- File src/OFUTF8String.m — part of check-in [4fbdca698c] at 2020-11-07 20:23:04 on branch trunk — OFObject: Remove -[allocMemoryWithSize:] (user: js, size: 28423) [annotate] [blame] [check-ins using] [more...]
︙ | ︙ | |||
24 25 26 27 28 29 30 31 32 33 34 35 36 37 | #ifdef OF_HAVE_SYS_TYPES_H # include <sys/types.h> #endif #import "OFUTF8String.h" #import "OFUTF8String+Private.h" #import "OFArray.h" #import "OFMutableUTF8String.h" #import "OFInitializationFailedException.h" #import "OFInvalidArgumentException.h" #import "OFInvalidEncodingException.h" #import "OFInvalidFormatException.h" #import "OFOutOfMemoryException.h" | > | 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | #ifdef OF_HAVE_SYS_TYPES_H # include <sys/types.h> #endif #import "OFUTF8String.h" #import "OFUTF8String+Private.h" #import "OFArray.h" #import "OFData.h" #import "OFMutableUTF8String.h" #import "OFInitializationFailedException.h" #import "OFInvalidArgumentException.h" #import "OFInvalidEncodingException.h" #import "OFInvalidFormatException.h" #import "OFOutOfMemoryException.h" |
︙ | ︙ | |||
176 177 178 179 180 181 182 | - (instancetype)init { self = [super init]; @try { _s = &_storage; | | | | 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 | - (instancetype)init { self = [super init]; @try { _s = &_storage; _s->cString = of_calloc(1, 1); _s->freeWhenDone = true; } @catch (id e) { [self release]; @throw e; } return self; } |
︙ | ︙ | |||
242 243 244 245 246 247 248 | memcmp(cString, "\xEF\xBB\xBF", 3) == 0) { cString += 3; cStringLength -= 3; } _s = &_storage; | | > | 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 | memcmp(cString, "\xEF\xBB\xBF", 3) == 0) { cString += 3; cStringLength -= 3; } _s = &_storage; _s->cString = of_malloc(cStringLength + 1, 1); _s->cStringLength = cStringLength; _s->freeWhenDone = true; if (encoding == OF_STRING_ENCODING_UTF_8 || encoding == OF_STRING_ENCODING_ASCII) { switch (of_string_utf8_check(cString, cStringLength, &_s->length)) { case 1: if (encoding == OF_STRING_ENCODING_ASCII) |
︙ | ︙ | |||
289 290 291 292 293 294 295 | (uint8_t)cString[i], buffer); if (bytes == 0) @throw [OFInvalidEncodingException exception]; _s->cStringLength += bytes - 1; | | < | | | | | | | 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 | (uint8_t)cString[i], buffer); if (bytes == 0) @throw [OFInvalidEncodingException exception]; _s->cStringLength += bytes - 1; _s->cString = of_realloc(_s->cString, _s->cStringLength + 1, 1); memcpy(_s->cString + j, buffer, bytes); j += bytes; } _s->cString[_s->cStringLength] = 0; return self; } switch (encoding) { #define CASE(encoding, var) \ case encoding: \ table = var; \ tableOffset = var##_offset; \ break; #ifdef HAVE_ISO_8859_2 CASE(OF_STRING_ENCODING_ISO_8859_2, of_iso_8859_2_table) #endif #ifdef HAVE_ISO_8859_3 CASE(OF_STRING_ENCODING_ISO_8859_3, of_iso_8859_3_table) #endif #ifdef HAVE_ISO_8859_15 |
︙ | ︙ | |||
370 371 372 373 374 375 376 | _s->isUTF8 = true; byteLength = of_string_utf8_encode(unichar, buffer); if (byteLength == 0) @throw [OFInvalidEncodingException exception]; _s->cStringLength += byteLength - 1; | | < | | 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 | _s->isUTF8 = true; byteLength = of_string_utf8_encode(unichar, buffer); if (byteLength == 0) @throw [OFInvalidEncodingException exception]; _s->cStringLength += byteLength - 1; _s->cString = of_realloc(_s->cString, _s->cStringLength + 1, 1); memcpy(_s->cString + j, buffer, byteLength); j += byteLength; } _s->cString[_s->cStringLength] = 0; } @catch (id e) { |
︙ | ︙ | |||
422 423 424 425 426 427 428 | break; case -1: @throw [OFInvalidEncodingException exception]; } _s->cString = (char *)UTF8String; _s->cStringLength = UTF8StringLength; | < < | | 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 | break; case -1: @throw [OFInvalidEncodingException exception]; } _s->cString = (char *)UTF8String; _s->cStringLength = UTF8StringLength; _s->freeWhenDone = freeWhenDone; } @catch (id e) { [self release]; @throw e; } return self; } |
︙ | ︙ | |||
450 451 452 453 454 455 456 | [string isKindOfClass: [OFMutableUTF8String class]]) _s->isUTF8 = ((OFUTF8String *)string)->_s->isUTF8; else _s->isUTF8 = true; _s->length = string.length; | | > | > | < | 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 | [string isKindOfClass: [OFMutableUTF8String class]]) _s->isUTF8 = ((OFUTF8String *)string)->_s->isUTF8; else _s->isUTF8 = true; _s->length = string.length; _s->cString = of_malloc(_s->cStringLength + 1, 1); memcpy(_s->cString, string.UTF8String, _s->cStringLength + 1); _s->freeWhenDone = true; } @catch (id e) { [self release]; @throw e; } return self; } - (instancetype)initWithCharacters: (const of_unichar_t *)characters length: (size_t)length { self = [super init]; @try { size_t j; _s = &_storage; _s->cString = of_malloc((length * 4) + 1, 1); _s->length = length; _s->freeWhenDone = true; j = 0; for (size_t i = 0; i < length; i++) { size_t len = of_string_utf8_encode(characters[i], _s->cString + j); if (len == 0) @throw [OFInvalidEncodingException exception]; if (len > 1) _s->isUTF8 = true; j += len; } _s->cString[j] = '\0'; _s->cStringLength = j; @try { _s->cString = of_realloc(_s->cString, j + 1, 1); } @catch (OFOutOfMemoryException *e) { /* We don't care, as we only tried to make it smaller */ } } @catch (id e) { [self release]; @throw e; } |
︙ | ︙ | |||
526 527 528 529 530 531 532 | string++; length--; } else if (byteOrder != OF_BYTE_ORDER_NATIVE) swap = true; _s = &_storage; | | > | 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 | string++; length--; } else if (byteOrder != OF_BYTE_ORDER_NATIVE) swap = true; _s = &_storage; _s->cString = of_malloc((length * 4) + 1, 1); _s->length = length; _s->freeWhenDone = true; j = 0; for (size_t i = 0; i < length; i++) { of_unichar_t character = (swap ? OF_BSWAP16(string[i]) : string[i]); size_t len; |
︙ | ︙ | |||
576 577 578 579 580 581 582 | j += len; } _s->cString[j] = '\0'; _s->cStringLength = j; @try { | | < | 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 | j += len; } _s->cString[j] = '\0'; _s->cStringLength = j; @try { _s->cString = of_realloc(_s->cString, j + 1, 1); } @catch (OFOutOfMemoryException *e) { /* We don't care, as we only tried to make it smaller */ } } @catch (id e) { [self release]; @throw e; } |
︙ | ︙ | |||
611 612 613 614 615 616 617 | characters++; length--; } else if (byteOrder != OF_BYTE_ORDER_NATIVE) swap = true; _s = &_storage; | | > | 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 | characters++; length--; } else if (byteOrder != OF_BYTE_ORDER_NATIVE) swap = true; _s = &_storage; _s->cString = of_malloc((length * 4) + 1, 1); _s->length = length; _s->freeWhenDone = true; j = 0; for (size_t i = 0; i < length; i++) { char buffer[4]; size_t len = of_string_utf8_encode( (swap ? OF_BSWAP32(characters[i]) : characters[i]), buffer); |
︙ | ︙ | |||
643 644 645 646 647 648 649 | } } _s->cString[j] = '\0'; _s->cStringLength = j; @try { | | < | 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 | } } _s->cString[j] = '\0'; _s->cStringLength = j; @try { _s->cString = of_realloc(_s->cString, j + 1, 1); } @catch (OFOutOfMemoryException *e) { /* We don't care, as we only tried to make it smaller */ } } @catch (id e) { [self release]; @throw e; } |
︙ | ︙ | |||
686 687 688 689 690 691 692 | case 1: _s->isUTF8 = true; break; case -1: @throw [OFInvalidEncodingException exception]; } | | < > | | | 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 | case 1: _s->isUTF8 = true; break; case -1: @throw [OFInvalidEncodingException exception]; } _s->cString = of_malloc(cStringLength + 1, 1); memcpy(_s->cString, tmp, cStringLength + 1); _s->freeWhenDone = true; } @finally { free(tmp); } } @catch (id e) { [self release]; @throw e; } return self; } - (void)dealloc { if (_s != NULL && _s->freeWhenDone) free(_s->cString); [super dealloc]; } - (size_t)getCString: (char *)cString maxLength: (size_t)maxLength encoding: (of_string_encoding_t)encoding |
︙ | ︙ | |||
1152 1153 1154 1155 1156 1157 1158 | objc_autoreleasePoolPop(pool); return array; } - (const of_unichar_t *)characters { | < | | < < < < < | > | > | | > > > < | | < < < < < | | > | > | | | | > > > | 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 | objc_autoreleasePoolPop(pool); return array; } - (const of_unichar_t *)characters { of_unichar_t *buffer = of_malloc(_s->length, sizeof(of_unichar_t)); size_t i = 0, j = 0; while (i < _s->cStringLength) { of_unichar_t c; ssize_t cLen; cLen = of_string_utf8_decode(_s->cString + i, _s->cStringLength - i, &c); if (cLen <= 0 || c > 0x10FFFF) { free(buffer); @throw [OFInvalidEncodingException exception]; } buffer[j++] = c; i += cLen; } return [[OFData dataWithItemsNoCopy: buffer count: _s->length itemSize: sizeof(of_unichar_t) freeWhenDone: true] items]; } - (const of_char32_t *)UTF32StringWithByteOrder: (of_byte_order_t)byteOrder { of_char32_t *buffer = of_malloc(_s->length + 1, sizeof(of_char32_t)); size_t i = 0, j = 0; while (i < _s->cStringLength) { of_char32_t c; ssize_t cLen; cLen = of_string_utf8_decode(_s->cString + i, _s->cStringLength - i, &c); if (cLen <= 0 || c > 0x10FFFF) { free(buffer); @throw [OFInvalidEncodingException exception]; } if (byteOrder != OF_BYTE_ORDER_NATIVE) buffer[j++] = OF_BSWAP32(c); else buffer[j++] = c; i += cLen; } buffer[j] = 0; return [[OFData dataWithItemsNoCopy: buffer count: _s->length + 1 itemSize: sizeof(of_char32_t) freeWhenDone: true] items]; } #ifdef OF_HAVE_BLOCKS - (void)enumerateLinesUsingBlock: (of_string_line_enumeration_block_t)block { void *pool; const char *cString = _s->cString; |
︙ | ︙ |