-
Notifications
You must be signed in to change notification settings - Fork 2
/
NSString+DictLineParsing.m
99 lines (73 loc) · 2.9 KB
/
NSString+DictLineParsing.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
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
/* -*-objc-*-
*
* Dictionary Reader - A Dict client for GNUstep
* Copyright (C) 2006 Guenther Noack
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the MIT license. See COPYING.
*/
#import "NSString+DictLineParsing.h"
@implementation NSString (DictLineParsing)
/**
* Splits a Dict-protocol-style string into its components and returns
* an array with those components. A string like this consists of one
* or more strings that are separated by a whitespace. A string that
* contains whitespaces itself can be put into quotation marks.
*
* Example:
* The string
* '151 "Awful" gcide "The Collaborative International Dict..."'
*
* would decode to:
* ['151', 'Awful', 'gcide', 'The Collaborative Internation...']
*/
-(NSArray*) parseDictLine
{
NSScanner* scanner = [NSScanner scannerWithString: self];
NSCharacterSet* space =
[NSCharacterSet characterSetWithCharactersInString: @" "];
NSCharacterSet* quotationMarks =
[NSCharacterSet characterSetWithCharactersInString: @"\""];
NSMutableArray* result = [NSMutableArray arrayWithCapacity: 4];
while ([scanner isAtEnd] == NO) {
// Location: At the beginning of a word, possible quotation
// marks not yet eaten.
BOOL isQuoted = [scanner scanCharactersFromSet: quotationMarks
intoString: (NSString**) nil];
if (isQuoted) {
// Location: At the beginning of a word, right after the quotation
// mark. (FIXME: This is assuming there is no empty string!)
NSString* word;
[scanner scanUpToCharactersFromSet: quotationMarks
intoString: &word];
[result addObject: [word retain]];
// Location: At the end of a word, with the pointer pointing to
// the closing quotation marks
// eat closing quotation marks
[scanner scanCharactersFromSet: quotationMarks
intoString: (NSString**) nil];
// Location: At the end of a word, after the quotation mark
} else {
// Case 2: The word is not quoted, parse to the next whitespace!
// Location: At the beginning of a word without quotation marks
NSString* word;
[scanner scanUpToCharactersFromSet: space intoString: &word];
[result addObject: [word retain]];
// Location: At the end of a non-quoted word.
}
// Location: At the end of a word, we still need to eat some white
// spaces to reach the next word.
[scanner scanCharactersFromSet: space
intoString: (NSString**) nil];
} //end of while loop
return result;
}
-(NSString*) dictLineComponent: (int)index
{
NSArray* array = [self parseDictLine];
if (array == nil)
return nil;
NSString* component = (NSString*) [array objectAtIndex: index];
return component; // implicitely: returns nil if component was nil
}
@end