Skip to content

Commit be59cc3

Browse files
refs pmengal#8 - VCalendar bug resolution.
1 parent 8b0e62b commit be59cc3

3 files changed

Lines changed: 96 additions & 58 deletions

File tree

Class Library/ActiveUp.Net.Groupware/vCalendar/Parser.cs

Lines changed: 72 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -31,28 +31,28 @@ public static vCalendar Parse(string data)
3131
data = vCard.Parser.Unfold(data);
3232
cal.Events = GetEvents(data);
3333
cal.Todos = GetTodos(data);
34-
if ((cal.Events.Count+cal.Todos.Count) > 0)
35-
data = data.Substring(data.IndexOf("\r\n"),data.IndexOf("BEGIN:",data.IndexOf("\r\n"))-data.IndexOf("\r\n"));
36-
foreach(string line in System.Text.RegularExpressions.Regex.Split(data,"\r\n"))
34+
if ((cal.Events.Count + cal.Todos.Count) > 0)
35+
data = data.Substring(data.IndexOf("\r\n"), data.IndexOf("BEGIN:", data.IndexOf("\r\n")) - data.IndexOf("\r\n"));
36+
foreach (string line in System.Text.RegularExpressions.Regex.Split(data, "\r\n"))
3737
{
3838
string fulltype = line.Split(':')[0];
3939
string type = fulltype.Split(';')[0].ToUpper();
40-
switch(type)
40+
switch (type)
4141
{
4242
case "VERSION":
43-
SetVersion(cal,line);
43+
SetVersion(cal, line);
4444
break;
4545
case "DAYLIGHT":
46-
SetDayLight(cal,line);
46+
SetDayLight(cal, line);
4747
break;
4848
case "GEO":
49-
SetGeo(cal,line);
49+
SetGeo(cal, line);
5050
break;
5151
case "TZ":
52-
SetTimeZone(cal,line);
52+
SetTimeZone(cal, line);
5353
break;
5454
case "PRODID":
55-
SetGeneratorId(cal,line);
55+
SetGeneratorId(cal, line);
5656
break;
5757
}
5858
}
@@ -66,7 +66,7 @@ private static void SetDayLight(vCalendar cal, string line)
6666
{
6767
DayLightSavings savings = new DayLightSavings();
6868
string[] compounds = line.Split(':')[1].Split(';');
69-
if(compounds[0].ToUpper()=="TRUE")
69+
if (compounds[0].ToUpper() == "TRUE")
7070
{
7171
savings.IsObserved = true;
7272
savings.Offset = int.Parse(compounds[1]);
@@ -89,44 +89,58 @@ private static void SetGeo(vCalendar cal, string line)
8989
}
9090
private static void SetTimeZone(vCalendar cal, string line)
9191
{
92-
cal.TimeZone = line.Replace(line.Split(':')[0]+":","");
92+
cal.TimeZone = line.Replace(line.Split(':')[0] + ":", "");
9393
}
9494
private static void SetGeneratorId(vCalendar cal, string line)
9595
{
96-
cal.GeneratorId = line.Replace(line.Split(':')[0]+":","");
96+
cal.GeneratorId = line.Replace(line.Split(':')[0] + ":", "");
9797
}
9898
private static vEventCollection GetEvents(string data)
9999
{
100100
int lastPosition = 0;
101101
vEventCollection events = new vEventCollection();
102+
103+
if (data.ToUpper().IndexOf("BEGIN:VEVENT") == -1) return events;
104+
if (data.ToUpper().IndexOf("END:VEVENT") == -1) return events;
105+
102106
LookForFurtherEvents:
103-
string eventData = data.Substring(data.ToUpper().IndexOf("BEGIN:VEVENT",lastPosition),data.ToUpper().IndexOf("END:VEVENT",lastPosition)+10-data.ToUpper().IndexOf("BEGIN:VEVENT",lastPosition));
104-
lastPosition = data.ToUpper().IndexOf("END:VEVENT",lastPosition)+10;
107+
108+
var eventData = data.Substring(data.ToUpper().IndexOf("BEGIN:VEVENT", lastPosition), data.ToUpper().IndexOf("END:VEVENT", lastPosition) + 10 - data.ToUpper().IndexOf("BEGIN:VEVENT", lastPosition));
109+
lastPosition = data.ToUpper().IndexOf("END:VEVENT", lastPosition) + 10;
105110
events.Add(ParseEvent(eventData));
106-
if(data.ToUpper().IndexOf("BEGIN:VEVENT",lastPosition)!=-1)
111+
112+
if (data.ToUpper().IndexOf("BEGIN:VEVENT", lastPosition) != -1)
113+
{
107114
goto LookForFurtherEvents;
115+
}
116+
108117
return events;
109118
}
110119
private static vTodoCollection GetTodos(string data)
111120
{
112121
int lastPosition = 0;
113122
vTodoCollection todos = new vTodoCollection();
114123

124+
if (data.IndexOf("BEGIN:VTODO") == -1) return todos;
125+
if (data.IndexOf("END:VTODO") == -1) return todos;
126+
115127
LookForFurtherTodos:
116-
if (data.IndexOf("BEGIN:VTODO") > -1)
128+
129+
var todoData = data.Substring(data.ToUpper().IndexOf("BEGIN:VTODO", lastPosition), data.ToUpper().IndexOf("END:VTODO", lastPosition) + 10 - data.ToUpper().IndexOf("BEGIN:VTODO", lastPosition));
130+
lastPosition = data.ToUpper().IndexOf("END:VTODO", lastPosition) + 10;
131+
todos.Add(ParseTodo(todoData));
132+
133+
if (data.ToUpper().IndexOf("BEGIN:VTODO", lastPosition) != -1)
117134
{
118-
string todoData = data.Substring(data.ToUpper().IndexOf("BEGIN:VTODO", lastPosition), data.ToUpper().IndexOf("END:VTODO", lastPosition) + 10 - data.ToUpper().IndexOf("BEGIN:VTODO", lastPosition));
119-
lastPosition = data.ToUpper().IndexOf("END:VTODO", lastPosition) + 10;
120-
todos.Add(ParseTodo(todoData));
121-
if (data.ToUpper().IndexOf("BEGIN:VTODO", lastPosition) != -1)
122-
goto LookForFurtherTodos;
135+
goto LookForFurtherTodos;
123136
}
124-
137+
125138
return todos;
126139
}
127140
public static DateTime ParseDate(string input)
128141
{
129-
try {
142+
try
143+
{
130144
return DateTime.Parse(input);
131145
}
132146
catch
@@ -149,18 +163,18 @@ public static DateTime ParseDate(string input)
149163
public static vEvent ParseEvent(string data)
150164
{
151165
vEvent even = new vEvent();
152-
153-
foreach(string line in System.Text.RegularExpressions.Regex.Split(data,"\r\n"))
166+
167+
foreach (string line in System.Text.RegularExpressions.Regex.Split(data, "\r\n"))
154168
{
155169
string fulltype = line.Split(':')[0];
156170
string type = fulltype.Split(';')[0].ToUpper();
157-
switch(type)
171+
switch (type)
158172
{
159173
case "ATTACH":
160-
AddAttachment(even,line);
174+
AddAttachment(even, line);
161175
break;
162176
case "ATTENDEE":
163-
AddAttendee(even,line);
177+
AddAttendee(even, line);
164178
break;
165179
//case "LOCATION":
166180
case "DTSTART":
@@ -182,74 +196,74 @@ public static vEvent ParseEvent(string data)
182196
case "PRIORITY":
183197
even.Priority = Convert.ToInt32(line.Split(':')[1]);
184198
break;
185-
//case "GEO": ActiveUp.Net.Groupware.vCalendar.Parser.SetGeo(even,line);
186-
// break;
187-
//case "TZ": ActiveUp.Net.Groupware.vCalendar.Parser.SetTimeZone(even,line);
188-
// break;
189-
//case "PRODID": ActiveUp.Net.Groupware.vCalendar.Parser.SetGeneratorId(even,line);
190-
// break;
199+
//case "GEO": ActiveUp.Net.Groupware.vCalendar.Parser.SetGeo(even,line);
200+
// break;
201+
//case "TZ": ActiveUp.Net.Groupware.vCalendar.Parser.SetTimeZone(even,line);
202+
// break;
203+
//case "PRODID": ActiveUp.Net.Groupware.vCalendar.Parser.SetGeneratorId(even,line);
204+
// break;
191205
}
192206
}
193207
return even;
194208
}
195209
private static void SetValueAndType(Property property, string line)
196210
{
197211
string uppercase = line.Split(':')[0].ToUpper();
198-
if(uppercase.IndexOf("CID")!=-1 || uppercase.IndexOf("CONTENT-ID")!=-1)
212+
if (uppercase.IndexOf("CID") != -1 || uppercase.IndexOf("CONTENT-ID") != -1)
199213
property.ValueType = ValueType.ContentId;
200-
else if(uppercase.IndexOf("URL")!=-1)
214+
else if (uppercase.IndexOf("URL") != -1)
201215
property.ValueType = ValueType.Url;
202216
string charset = "utf-8";
203-
if(uppercase.IndexOf("CHARSET")!=-1)
204-
charset = uppercase.Substring(uppercase.IndexOf("CHARSET="),uppercase.IndexOf(";",uppercase.IndexOf("CHARSET="))-uppercase.IndexOf("CHARSET="));
205-
if(uppercase.IndexOf("ENCODING=QUOTED-PRINTABLE")!=-1)
206-
property.Value = FromQuotedPrintable(line.Replace(line.Split(':')[0]+":",""),charset);
217+
if (uppercase.IndexOf("CHARSET") != -1)
218+
charset = uppercase.Substring(uppercase.IndexOf("CHARSET="), uppercase.IndexOf(";", uppercase.IndexOf("CHARSET=")) - uppercase.IndexOf("CHARSET="));
219+
if (uppercase.IndexOf("ENCODING=QUOTED-PRINTABLE") != -1)
220+
property.Value = FromQuotedPrintable(line.Replace(line.Split(':')[0] + ":", ""), charset);
207221
else if (uppercase.IndexOf("ENCODING=BASE64") != -1)
208222
{
209223
byte[] data = Convert.FromBase64String(line.Replace(line.Split(':')[0] + ":", ""));
210-
property.Value = System.Text.Encoding.GetEncoding(charset).GetString(data,0,data.Length);
224+
property.Value = System.Text.Encoding.GetEncoding(charset).GetString(data, 0, data.Length);
211225
}
212226
else property.Value = line.Replace(line.Split(':')[0] + ":", "");
213227
}
214228
private static void AddAttachment(AbstractEntity entity, string line)
215229
{
216230
Attachment attach = new Attachment();
217-
SetValueAndType(attach,line);
231+
SetValueAndType(attach, line);
218232
entity.Attachments.Add(attach);
219233
}
220234
private static void AddAttendee(AbstractEntity entity, string line)
221235
{
222236
Attendee attendee = new Attendee();
223-
SetValueAndType(attendee,line);
237+
SetValueAndType(attendee, line);
224238
attendee.Contact = new Address(attendee.Value);
225239
string uppercase = line.Split(':')[0].ToUpper();
226-
if(uppercase.IndexOf("EXPECT=REQUIRE")!=-1)
240+
if (uppercase.IndexOf("EXPECT=REQUIRE") != -1)
227241
attendee.Expectation = Expectation.Required;
228-
else if(uppercase.IndexOf("EXPECT=REQUEST")!=-1)
242+
else if (uppercase.IndexOf("EXPECT=REQUEST") != -1)
229243
attendee.Expectation = Expectation.Requested;
230-
else if(uppercase.IndexOf("EXPECT=IMMEDIATE")!=-1)
244+
else if (uppercase.IndexOf("EXPECT=IMMEDIATE") != -1)
231245
attendee.Expectation = Expectation.ImmediateResponse;
232-
if(uppercase.IndexOf("ROLE=OWNER")!=-1)
246+
if (uppercase.IndexOf("ROLE=OWNER") != -1)
233247
attendee.Role = Role.Owner;
234-
else if(uppercase.IndexOf("ROLE=ORGANIZER")!=-1)
248+
else if (uppercase.IndexOf("ROLE=ORGANIZER") != -1)
235249
attendee.Role = Role.Organizer;
236-
else if(uppercase.IndexOf("ROLE=DELEGATE")!=-1)
250+
else if (uppercase.IndexOf("ROLE=DELEGATE") != -1)
237251
attendee.Role = Role.Delegate;
238-
if(uppercase.IndexOf("STATUS=ACCEPTED")!=-1)
252+
if (uppercase.IndexOf("STATUS=ACCEPTED") != -1)
239253
attendee.Status = Status.Accepted;
240-
else if(uppercase.IndexOf("STATUS=SENT")!=-1)
254+
else if (uppercase.IndexOf("STATUS=SENT") != -1)
241255
attendee.Status = Status.Sent;
242-
else if(uppercase.IndexOf("STATUS=TENTATIVE")!=-1)
256+
else if (uppercase.IndexOf("STATUS=TENTATIVE") != -1)
243257
attendee.Status = Status.Tentative;
244-
else if(uppercase.IndexOf("STATUS=CONFIRMED")!=-1)
258+
else if (uppercase.IndexOf("STATUS=CONFIRMED") != -1)
245259
attendee.Status = Status.Confirmed;
246-
else if(uppercase.IndexOf("STATUS=DECLINED")!=-1)
260+
else if (uppercase.IndexOf("STATUS=DECLINED") != -1)
247261
attendee.Status = Status.Declined;
248-
else if(uppercase.IndexOf("STATUS=COMPLETED")!=-1)
262+
else if (uppercase.IndexOf("STATUS=COMPLETED") != -1)
249263
attendee.Status = Status.Completed;
250-
else if(uppercase.IndexOf("STATUS=DELEGATED")!=-1)
264+
else if (uppercase.IndexOf("STATUS=DELEGATED") != -1)
251265
attendee.Status = Status.Delegated;
252-
if(uppercase.IndexOf("RVSP=YES")!=-1)
266+
if (uppercase.IndexOf("RVSP=YES") != -1)
253267
attendee.ReplyRequested = true;
254268
entity.Attendees.Add(attendee);
255269
}
@@ -287,7 +301,7 @@ public static string FromQuotedPrintable(string input, string toCharset)
287301
decoded = new byte[arr.Count];
288302
for (int j = 0; j < arr.Count; j++)
289303
decoded[j] = (byte)arr[j];
290-
return System.Text.Encoding.GetEncoding(toCharset).GetString(decoded,0,decoded.Length).TrimEnd('=');
304+
return System.Text.Encoding.GetEncoding(toCharset).GetString(decoded, 0, decoded.Length).TrimEnd('=');
291305
}
292306
catch { return input; }
293307
}

Class Library/ActiveUp.Net.Tests/ActiveUp.Net.Tests.csproj

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@
8383
<Compile Include="Common\RFC2047\Rfc2047DecoderTests.cs" />
8484
<Compile Include="Common\RFC2047\Rfc2047DecoderTests.Splitter.cs" />
8585
<Compile Include="FluentTests.cs" />
86+
<Compile Include="Groupware\ParserTests.cs" />
8687
<Compile Include="ImapTests.cs" />
8788
<Compile Include="SmtpTests.cs" />
8889
<Compile Include="Properties\AssemblyInfo.cs" />
@@ -157,6 +158,10 @@
157158
<Project>{3A83AE95-C23F-48B4-9F1A-AD4B32C37B93}</Project>
158159
<Name>ActiveUp.Net.Common</Name>
159160
</ProjectReference>
161+
<ProjectReference Include="..\ActiveUp.Net.Groupware\ActiveUp.Net.Groupware.csproj">
162+
<Project>{C646ED2B-50B7-4178-BEFA-657F1259251F}</Project>
163+
<Name>ActiveUp.Net.Groupware</Name>
164+
</ProjectReference>
160165
<ProjectReference Include="..\ActiveUp.Net.Imap4\ActiveUp.Net.Imap4.csproj">
161166
<Project>{6BEE77DF-2DD2-41C3-BA16-60E20B1EDDCC}</Project>
162167
<Name>ActiveUp.Net.Imap4</Name>
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
using ActiveUp.Net.Groupware.vCalendar;
2+
using NUnit.Framework;
3+
4+
namespace ActiveUp.Net.Tests.Groupware
5+
{
6+
[TestFixture]
7+
public class ParserTests
8+
{
9+
[Test]
10+
public void should_parse_simple_date()
11+
{
12+
var vcal = Parser.Parse("TODO:");
13+
14+
Assert.AreEqual(0, vcal.Todos.Count);
15+
Assert.AreEqual(0, vcal.Events.Count);
16+
}
17+
18+
}
19+
}

0 commit comments

Comments
 (0)