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
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
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)];

		if ([key hasSuffix: @" "]) {
			key = [key stringByDeletingEnclosingWhitespaces];
			value = [value stringByDeletingEnclosingWhitespaces];
		}
		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
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
{
	if (bool_)
		[self setString: @"true"
			 forKey: key];
	[self setString: (bool_ ? @"true" : @"false")
		 forKey: key];
	else
		[self setString: @"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
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",
			[stream writeFormat: @"%@=%@\n", key, value];
					     pair->_key, pair->_value];
		} else
			@throw [OFInvalidArgumentException exception];
	}

	return true;
}
@end