ObjFW  Check-in [0f260e0fd5]

Overview
Comment: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).

Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 0f260e0fd556a6e53c9a175e573ce59b3f8f9bcd5a06cb90e68488f4fbe8a84c
User & Date: js on 2020-11-06 02:37:02
Other Links: manifest | tags
Context
2020-11-07
10:38
Make GCC happy again check-in: 7aa23887d0 user: js tags: trunk
2020-11-06
02:37
OFString: Make freeWhenDone behave like in OFData check-in: 0f260e0fd5 user: js tags: trunk
02:24
Future-proof some code using freeWhenDone check-in: a2b4238850 user: js tags: trunk
Changes

Modified src/OFString.m from [ab9d9164f8] to [7044157852].

832
833
834
835
836
837
838
839

840
841
842
843
844
845


846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862





863
864
865
866
867
868
869
870
832
833
834
835
836
837
838

839
840





841
842

843
844
845
846
847
848
849
850








851
852
853
854
855

856
857
858
859
860
861
862







-
+

-
-
-
-
-
+
+
-








-
-
-
-
-
-
-
-
+
+
+
+
+
-







			    encoding: OF_STRING_ENCODING_UTF_8
			      length: UTF8StringLength];
}

- (instancetype)initWithUTF8StringNoCopy: (char *)UTF8String
			    freeWhenDone: (bool)freeWhenDone
{
	id ret;
	id ret = [self initWithUTF8String: UTF8String];

	@try {
		ret = [self initWithUTF8String: UTF8String];
	} @finally {
		if (freeWhenDone)
			free(UTF8String);
	if (freeWhenDone)
		free(UTF8String);
	}

	return ret;
}

- (instancetype)initWithUTF8StringNoCopy: (char *)UTF8String
				  length: (size_t)UTF8StringLength
			    freeWhenDone: (bool)freeWhenDone
{
	id ret;

	@try {
		ret = [self initWithUTF8String: UTF8String
					length: UTF8StringLength];
	} @finally {
		if (freeWhenDone)
			free(UTF8String);
	id ret = [self initWithUTF8String: UTF8String
				   length: UTF8StringLength];

	if (freeWhenDone)
		free(UTF8String);
	}

	return ret;
}

- (instancetype)initWithCString: (const char *)cString
		       encoding: (of_string_encoding_t)encoding
{

Modified src/OFUTF8String.m from [d8b3a6972a] to [e04f7e1202].

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
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







-
-
+
-
-
-
-
-




-
-
-






-
-
-








+
+
+
+
+
+








}

- (instancetype)initWithUTF8StringNoCopy: (char *)UTF8String
				  length: (size_t)UTF8StringLength
			    freeWhenDone: (bool)freeWhenDone
{
	@try {
		self = [super init];
	self = [super init];
	} @catch (id e) {
		if (freeWhenDone)
			free(UTF8String);
		@throw e;
	}

	@try {
		_s = &_storage;

		if (freeWhenDone)
			_s->freeWhenDone = UTF8String;

		if (UTF8StringLength >= 3 &&
		    memcmp(UTF8String, "\xEF\xBB\xBF", 3) == 0) {
			UTF8String += 3;
			UTF8StringLength -= 3;
		}

		_s->cString = (char *)UTF8String;
		_s->cStringLength = UTF8StringLength;

		switch (of_string_utf8_check(UTF8String, UTF8StringLength,
		    &_s->length)) {
		case 1:
			_s->isUTF8 = true;
			break;
		case -1:
			@throw [OFInvalidEncodingException exception];
		}

		_s->cString = (char *)UTF8String;
		_s->cStringLength = UTF8StringLength;

		if (freeWhenDone)
			_s->freeWhenDone = UTF8String;
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}