4 // Copyright (C) 2006 Novell, Inc.
8 // Permission is hereby granted, free of charge, to any person obtaining a copy
9 // of this software and associated documentation files (the "Software"), to deal
10 // in the Software without restriction, including without limitation the rights
11 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 // copies of the Software, and to permit persons to whom the Software is
13 // furnished to do so, subject to the following conditions:
15 // The above copyright notice and this permission notice shall be included in all
16 // copies or substantial portions of the Software.
18 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30 using System
.Collections
;
34 public class ICalParser
: IEnumerator
36 public static string KabcMimeType
= "text/x-kabc-directory";
37 public static string KnotesMimeType
= "text/x-knotes-calendar";
39 private ParserState state
= ParserState
.ParsingProperty
;
40 private StringBuilder buffer
= new StringBuilder ();
42 private Token current
;
43 private TextReader reader
;
45 public ICalParser (TextReader reader
)
47 this.reader
= new UnfoldingTextReader (reader
);
52 get { return current; }
55 public bool MoveNext ()
61 case ParserState
.ParsingProperty
:
62 data
= Read (new char [] { ':', ';' }
, out stop
);
69 state
= ParserState
.ParsingPropertyValue
;
72 state
= ParserState
.ParsingPropertyParameter
;
76 current
= new Token (TokenType
.Property
, data
.Trim ());
78 case ParserState
.ParsingPropertyValue
:
79 data
= Read (new char[] { '\n'}
, out stop
);
86 state
= ParserState
.ParsingProperty
;
89 state
= ParserState
.ParsingPropertyValue
;
93 current
= new Token (TokenType
.PropertyValue
, data
.Trim ());
95 case ParserState
.ParsingPropertyParameter
:
96 data
= Read (new char[] { '\n', '=', ';', ','}
, out stop
);
103 state
= ParserState
.ParsingPropertyParameterValue
;
106 state
= ParserState
.ParsingProperty
;
113 current
= new Token (TokenType
.PropertyParameter
, data
.Trim ());
115 case ParserState
.ParsingPropertyParameterValue
:
116 data
= Read (new char[] { ',', ':', ';' }
, out stop
);
120 state
= ParserState
.ParsingPropertyParameter
;
123 state
= ParserState
.ParsingPropertyValue
;
129 current
= new Token (TokenType
.PropertyParameterValue
, data
.Trim ());
138 throw new NotImplementedException ();
141 public void Dispose()
146 private string Read (char[] stops
, out char stop
)
154 while ((i
= reader
.Read ()) != -1) {
155 if (Array
.IndexOf (stops
, (char) i
) != -1) {
160 buffer
.Append((char)i
);
163 return (buffer
.Length
== 0) ? null : buffer
.ToString ();
169 private TokenType type
;
170 private string value;
172 public TokenType Type
179 get { return value; }
182 public Token (TokenType type
, string value)
188 public override string ToString ()
190 return String
.Format ("{0} ({1})", type
, value);
194 public enum TokenType
199 PropertyParameterValue
,
202 private enum ParserState
205 ParsingPropertyValue
,
206 ParsingPropertyParameter
,
207 ParsingPropertyParameterValue
210 private class UnfoldingTextReader
: TextReader
212 private TextReader reader
;
214 public UnfoldingTextReader(TextReader reader
)
216 this.reader
= reader
;
219 public override int Read ()
221 int i
= reader
.Read ();
226 if ((char) i
== '\n' && (char) reader
.Peek() == ' ') {
230 if ((char) i
== '\r')
232 } while ((char) i
== ' ' || (char) i
== '\n');
242 static void Main (string [] args
)
244 ICalParser parser
= new ICalParser (File
.OpenText ("test.ical"));
246 while (parser
.MoveNext()) {
247 ICalParser
.Token token
= (ICalParser
.Token
) parser
.Current
;
249 if (token
.Type
!= ICalParser
.TokenType
.Property
)
250 Console
.Write ("\t");
252 if (token
.Type
== ICalParser
.TokenType
.PropertyParameterValue
)
253 Console
.Write ("\t");
255 Console
.WriteLine (token
);