ObjFW  Diff

Differences From Artifact [900a1099e7]:

To Artifact [8e99773efd]:

  • File src/OFINICategory.m — part of check-in [12c5b7ee91] at 2014-06-12 13:43:41 on branch trunk — OFINIFile: Add support for quoted keys / values

    This is a much more logical way to handle leading and trailing
    whitespaces and also seems to be used by a few other INI
    implementations.

    Additionally, this imports OFINICategory.h in OFINIFile.h so that
    importing OFINIFile.h is enough - this should be less confusing - and
    allows opening non-existant files, treating them like an empty file. (user: js, size: 9255) [annotate] [blame] [check-ins using]


35
36
37
38
39
40
41




























































42
43
44
45
46
47
48

@interface OFINICategory_Comment: OFObject
{
@public
	OFString *_comment;
}
@end





























































@implementation OFINICategory_Pair
- (void)dealloc
{
	[_key release];
	[_value release];








>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







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

@interface OFINICategory_Comment: OFObject
{
@public
	OFString *_comment;
}
@end

static OFString*
escapeString(OFString *string)
{
	OFMutableString *mutableString;

	/* FIXME: Optimize */
	if (![string hasPrefix: @" "] && ![string hasPrefix: @"\t"] &&
	    ![string hasPrefix: @"\f"] && ![string hasSuffix: @" "] &&
	    ![string hasSuffix: @"\t"] && ![string hasSuffix: @"\f"] &&
	    ![string containsString: @"\""])
		return string;

	mutableString = [[string mutableCopy] autorelease];

	[mutableString replaceOccurrencesOfString: @"\\"
				       withString: @"\\\\"];
	[mutableString replaceOccurrencesOfString: @"\f"
				       withString: @"\\f"];
	[mutableString replaceOccurrencesOfString: @"\r"
				       withString: @"\\r"];
	[mutableString replaceOccurrencesOfString: @"\n"
				       withString: @"\\n"];
	[mutableString replaceOccurrencesOfString: @"\""
				       withString: @"\\\""];

	[mutableString prependString: @"\""];
	[mutableString appendString: @"\""];

	[mutableString makeImmutable];

	return mutableString;
}

static OFString*
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"
				       withString: @"\n"];
	[mutableString replaceOccurrencesOfString: @"\\\""
				       withString: @"\""];
	[mutableString replaceOccurrencesOfString: @"\\\\"
				       withString: @"\\"];

	[mutableString makeImmutable];

	return mutableString;
}

@implementation OFINICategory_Pair
- (void)dealloc
{
	[_key release];
	[_value release];

108
109
110
111
112
113
114
115
116
117
118


119
120
121
122
123
124
125
		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)];

		if ([key hasSuffix: @" "]) {
			key = [key stringByDeletingEnclosingWhitespaces];
			value = [value stringByDeletingEnclosingWhitespaces];
		}



		pair->_key = [key copy];
		pair->_value = [value copy];

		[_lines addObject: pair];
	} else {
		OFINICategory_Comment *comment =







<
|
|
|
>
>







168
169
170
171
172
173
174

175
176
177
178
179
180
181
182
183
184
185
186
		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];

		[_lines addObject: pair];
	} else {
		OFINICategory_Comment *comment =
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308

	objc_autoreleasePoolPop(pool);
}

- (void)setBool: (bool)bool_
	 forKey: (OFString*)key
{
	if (bool_)
		[self setString: @"true"
			 forKey: key];
	else
		[self setString: @"false"
			 forKey: key];
}

- (void)setFloat: (float)float_
	  forKey: (OFString*)key
{
	void *pool = objc_autoreleasePoolPush();








<
|
|
<
<
<







350
351
352
353
354
355
356

357
358



359
360
361
362
363
364
365

	objc_autoreleasePoolPop(pool);
}

- (void)setBool: (bool)bool_
	 forKey: (OFString*)key
{

	[self setString: (bool_ ? @"true" : @"false")
		 forKey: key];



}

- (void)setFloat: (float)float_
	  forKey: (OFString*)key
{
	void *pool = objc_autoreleasePoolPush();

369
370
371
372
373
374
375



376
377
378
379
380
381
382
383
384
	enumerator = [_lines objectEnumerator];
	while ((line = [enumerator nextObject]) != nil) {
		if ([line isKindOfClass: [OFINICategory_Comment class]]) {
			OFINICategory_Comment *comment = line;
			[stream writeLine: comment->_comment];
		} else if ([line isKindOfClass: [OFINICategory_Pair class]]) {
			OFINICategory_Pair *pair = line;



			[stream writeFormat: @"%@=%@\n",
					     pair->_key, pair->_value];
		} else
			@throw [OFInvalidArgumentException exception];
	}

	return true;
}
@end







>
>
>
|
<







426
427
428
429
430
431
432
433
434
435
436

437
438
439
440
441
442
443
	enumerator = [_lines objectEnumerator];
	while ((line = [enumerator nextObject]) != nil) {
		if ([line isKindOfClass: [OFINICategory_Comment class]]) {
			OFINICategory_Comment *comment = line;
			[stream writeLine: comment->_comment];
		} else if ([line isKindOfClass: [OFINICategory_Pair class]]) {
			OFINICategory_Pair *pair = line;
			OFString *key = escapeString(pair->_key);
			OFString *value = escapeString(pair->_value);

			[stream writeFormat: @"%@=%@\n", key, value];

		} else
			@throw [OFInvalidArgumentException exception];
	}

	return true;
}
@end