ObjFW  Diff

Differences From Artifact [38c671870e]:

  • File src/OFINIFile.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: 3681) [annotate] [blame] [check-ins using]

To Artifact [7cf0535b70]:


24
25
26
27
28
29
30
31

32
33
34
35
36
37
38
#import "OFInvalidFormatException.h"
#import "OFOpenFileFailedException.h"

#import "autorelease.h"
#import "macros.h"

@interface OFINIFile (OF_PRIVATE_CATEGORY)
- (void)OF_parseFile: (OFString*)path;

@end

static bool
isWhitespaceLine(OFString *line)
{
	const char *cString = [line UTF8String];
	size_t i, length = [line UTF8StringLength];







|
>







24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#import "OFInvalidFormatException.h"
#import "OFOpenFileFailedException.h"

#import "autorelease.h"
#import "macros.h"

@interface OFINIFile (OF_PRIVATE_CATEGORY)
- (void)OF_parseFile: (OFString*)path
	    encoding: (of_string_encoding_t)encoding;
@end

static bool
isWhitespaceLine(OFString *line)
{
	const char *cString = [line UTF8String];
	size_t i, length = [line UTF8StringLength];
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
}

@implementation OFINIFile
+ (instancetype)fileWithPath: (OFString*)path
{
	return [[[self alloc] initWithPath: path] autorelease];
}








- init
{
	OF_INVALID_INIT_METHOD
}

- initWithPath: (OFString*)path
{







	self = [super init];

	@try {
		_categories = [[OFMutableArray alloc] init];

		[self OF_parseFile: path];

	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}







>
>
>
>
>
>
>








>
>
>
>
>
>
>





|
>







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
}

@implementation OFINIFile
+ (instancetype)fileWithPath: (OFString*)path
{
	return [[[self alloc] initWithPath: path] autorelease];
}

+ (instancetype)fileWithPath: (OFString*)path
		    encoding: (of_string_encoding_t)encoding
{
	return [[[self alloc] initWithPath: path
				  encoding: encoding] autorelease];
}

- init
{
	OF_INVALID_INIT_METHOD
}

- initWithPath: (OFString*)path
{
	return [self initWithPath: path
			 encoding: OF_STRING_ENCODING_UTF_8];
}

- initWithPath: (OFString*)path
      encoding: (of_string_encoding_t)encoding
{
	self = [super init];

	@try {
		_categories = [[OFMutableArray alloc] init];

		[self OF_parseFile: path
			  encoding: encoding];
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}
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

	objc_autoreleasePoolPop(pool);

	return [category autorelease];
}

- (void)OF_parseFile: (OFString*)path

{
	void *pool = objc_autoreleasePoolPush();
	OFFile *file;
	OFINICategory *category = nil;
	OFString *line;

	@try {
		file = [OFFile fileWithPath: path
				       mode: @"r"];
	} @catch (OFOpenFileFailedException *e) {
		/* Handle missing file like an empty file */
		if ([e errNo] == ENOENT)
			return;

		@throw e;
	}

	while ((line = [file readLine]) != nil) {
		if (isWhitespaceLine(line))
			continue;

		if ([line hasPrefix: @"["]) {
			OFString *categoryName;

			if (![line hasSuffix: @"]"])







>

















|







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

	objc_autoreleasePoolPop(pool);

	return [category autorelease];
}

- (void)OF_parseFile: (OFString*)path
	    encoding: (of_string_encoding_t)encoding
{
	void *pool = objc_autoreleasePoolPush();
	OFFile *file;
	OFINICategory *category = nil;
	OFString *line;

	@try {
		file = [OFFile fileWithPath: path
				       mode: @"r"];
	} @catch (OFOpenFileFailedException *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: @"]"])
157
158
159
160
161
162
163







164
165
166
167
168
169
170
171
172

173
174
175
176
177
178
	}

	objc_autoreleasePoolPop(pool);
}

- (void)writeToFile: (OFString*)path
{







	void *pool = objc_autoreleasePoolPush();
	OFFile *file = [OFFile fileWithPath: path
				       mode: @"w"];
	OFEnumerator *enumerator = [_categories objectEnumerator];
	OFINICategory *category;
	bool first = true;

	while ((category = [enumerator nextObject]) != nil)
		if ([category OF_writeToStream: file

					 first: first])
			first = false;

	objc_autoreleasePoolPop(pool);
}
@end







>
>
>
>
>
>
>









>






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
	}

	objc_autoreleasePoolPop(pool);
}

- (void)writeToFile: (OFString*)path
{
	[self writeToFile: path
		 encoding: OF_STRING_ENCODING_UTF_8];
}

- (void)writeToFile: (OFString*)path
	   encoding: (of_string_encoding_t)encoding
{
	void *pool = objc_autoreleasePoolPush();
	OFFile *file = [OFFile fileWithPath: path
				       mode: @"w"];
	OFEnumerator *enumerator = [_categories objectEnumerator];
	OFINICategory *category;
	bool first = true;

	while ((category = [enumerator nextObject]) != nil)
		if ([category OF_writeToStream: file
				      encoding: encoding
					 first: first])
			first = false;

	objc_autoreleasePoolPop(pool);
}
@end