ics - sections.go
1 package ics
2
3 // File automatically generated with ./genSections.sh
4
5 import (
6 "errors"
7 "fmt"
8 "io"
9 "strings"
10
11 "vimagination.zapto.org/parser"
12 )
13
14 // Calendar represents a iCalendar object.
15 type Calendar struct {
16 Version PropVersion
17 ProductID PropProductID
18 Event []Event
19 Todo []Todo
20 Journal []Journal
21 FreeBusy []FreeBusy
22 Timezone []Timezone
23 }
24
25 func (s *Calendar) decode(t tokeniser) error {
26 var requiredVersion, requiredProductID bool
27
28 Loop:
29 for {
30 p, err := t.GetPhrase()
31 if err != nil {
32 return fmt.Errorf(errDecodingType, cCalendar, err)
33 } else if p.Type == parser.PhraseDone {
34 return fmt.Errorf(errDecodingType, cCalendar, io.ErrUnexpectedEOF)
35 }
36
37 params := p.Data[1 : len(p.Data)-1]
38 value := p.Data[len(p.Data)-1].Data
39
40 switch strings.ToUpper(p.Data[0].Data) {
41 case "BEGIN":
42 switch n := strings.ToUpper(value); n {
43 case "VEVENT":
44 var e Event
45
46 if err := e.decode(t); err != nil {
47 return fmt.Errorf(errDecodingProp, cCalendar, cEvent, err)
48 }
49
50 s.Event = append(s.Event, e)
51 case "VTODO":
52 var e Todo
53
54 if err := e.decode(t); err != nil {
55 return fmt.Errorf(errDecodingProp, cCalendar, cTodo, err)
56 }
57
58 s.Todo = append(s.Todo, e)
59 case "VJOURNAL":
60 var e Journal
61
62 if err := e.decode(t); err != nil {
63 return fmt.Errorf(errDecodingProp, cCalendar, cJournal, err)
64 }
65
66 s.Journal = append(s.Journal, e)
67 case "VFREEBUSY":
68 var e FreeBusy
69
70 if err := e.decode(t); err != nil {
71 return fmt.Errorf(errDecodingProp, cCalendar, cFreeBusy, err)
72 }
73
74 s.FreeBusy = append(s.FreeBusy, e)
75 case "VTIMEZONE":
76 var e Timezone
77
78 if err := e.decode(t); err != nil {
79 return fmt.Errorf(errDecodingProp, cCalendar, cTimezone, err)
80 }
81
82 s.Timezone = append(s.Timezone, e)
83 default:
84 if err := decodeDummy(t, n); err != nil {
85 return fmt.Errorf(errDecodingType, cCalendar, err)
86 }
87 }
88 case "VERSION":
89 if requiredVersion {
90 return fmt.Errorf(errMultiple, cCalendar, cVersion)
91 }
92
93 requiredVersion = true
94
95 if err := s.Version.decode(params, value); err != nil {
96 return fmt.Errorf(errDecodingProp, cCalendar, cVersion, err)
97 }
98 case "PRODID":
99 if requiredProductID {
100 return fmt.Errorf(errMultiple, cCalendar, cProductID)
101 }
102
103 requiredProductID = true
104
105 if err := s.ProductID.decode(params, value); err != nil {
106 return fmt.Errorf(errDecodingProp, cCalendar, cProductID, err)
107 }
108 case "END":
109 if value != "VCALENDAR" {
110 return fmt.Errorf(errDecodingType, cCalendar, ErrInvalidEnd)
111 }
112
113 break Loop
114 }
115 }
116
117 if !requiredVersion || !requiredProductID {
118 return fmt.Errorf(errDecodingType, cCalendar, ErrMissingRequired)
119 }
120
121 return nil
122 }
123
124 func (s *Calendar) encode(w writer) {
125 w.WriteString("BEGIN:VCALENDAR\r\n")
126 s.Version.encode(w)
127 s.ProductID.encode(w)
128
129 for n := range s.Event {
130 s.Event[n].encode(w)
131 }
132
133 for n := range s.Todo {
134 s.Todo[n].encode(w)
135 }
136
137 for n := range s.Journal {
138 s.Journal[n].encode(w)
139 }
140
141 for n := range s.FreeBusy {
142 s.FreeBusy[n].encode(w)
143 }
144
145 for n := range s.Timezone {
146 s.Timezone[n].encode(w)
147 }
148
149 w.WriteString("END:VCALENDAR\r\n")
150 }
151
152 func (s *Calendar) valid() error {
153 if err := s.Version.valid(); err != nil {
154 return fmt.Errorf(errValidatingProp, cCalendar, cVersion, err)
155 }
156
157 if err := s.ProductID.valid(); err != nil {
158 return fmt.Errorf(errValidatingProp, cCalendar, cProductID, err)
159 }
160
161 for n := range s.Event {
162 if err := s.Event[n].valid(); err != nil {
163 return fmt.Errorf(errValidatingProp, cCalendar, cEvent, err)
164 }
165 }
166
167 for n := range s.Todo {
168 if err := s.Todo[n].valid(); err != nil {
169 return fmt.Errorf(errValidatingProp, cCalendar, cTodo, err)
170 }
171 }
172
173 for n := range s.Journal {
174 if err := s.Journal[n].valid(); err != nil {
175 return fmt.Errorf(errValidatingProp, cCalendar, cJournal, err)
176 }
177 }
178
179 for n := range s.FreeBusy {
180 if err := s.FreeBusy[n].valid(); err != nil {
181 return fmt.Errorf(errValidatingProp, cCalendar, cFreeBusy, err)
182 }
183 }
184
185 for n := range s.Timezone {
186 if err := s.Timezone[n].valid(); err != nil {
187 return fmt.Errorf(errValidatingProp, cCalendar, cTimezone, err)
188 }
189 }
190
191 return nil
192 }
193
194 // Event provides a group of components that describe an event.
195 type Event struct {
196 DateTimeStamp PropDateTimeStamp
197 UID PropUID
198 DateTimeStart *PropDateTimeStart
199 Class *PropClass
200 Created *PropCreated
201 Description *PropDescription
202 Geo *PropGeo
203 LastModified *PropLastModified
204 Location *PropLocation
205 Organizer *PropOrganizer
206 Priority *PropPriority
207 Sequence *PropSequence
208 Status *PropStatus
209 Summary *PropSummary
210 TimeTransparency *PropTimeTransparency
211 URL *PropURL
212 RecurrenceID *PropRecurrenceID
213 RecurrenceRule *PropRecurrenceRule
214 DateTimeEnd *PropDateTimeEnd
215 Duration *PropDuration
216 Attachment []PropAttachment
217 Attendee []PropAttendee
218 Categories []PropCategories
219 Comment []PropComment
220 Contact []PropContact
221 ExceptionDateTime []PropExceptionDateTime
222 RequestStatus []PropRequestStatus
223 RelatedTo []PropRelatedTo
224 Resources []PropResources
225 RecurrenceDateTimes []PropRecurrenceDateTimes
226 Alarm []Alarm
227 }
228
229 func (s *Event) decode(t tokeniser) error {
230 var requiredDateTimeStamp, requiredUID bool
231
232 Loop:
233 for {
234 p, err := t.GetPhrase()
235 if err != nil {
236 return fmt.Errorf(errDecodingType, cEvent, err)
237 } else if p.Type == parser.PhraseDone {
238 return fmt.Errorf(errDecodingType, cEvent, io.ErrUnexpectedEOF)
239 }
240
241 params := p.Data[1 : len(p.Data)-1]
242 value := p.Data[len(p.Data)-1].Data
243
244 switch strings.ToUpper(p.Data[0].Data) {
245 case "BEGIN":
246 switch n := strings.ToUpper(value); n {
247 case "VALARM":
248 var e Alarm
249
250 if err := e.decode(t); err != nil {
251 return fmt.Errorf(errDecodingProp, cEvent, cAlarm, err)
252 }
253
254 s.Alarm = append(s.Alarm, e)
255 default:
256 if err := decodeDummy(t, n); err != nil {
257 return fmt.Errorf(errDecodingType, cEvent, err)
258 }
259 }
260 case "DTSTAMP":
261 if requiredDateTimeStamp {
262 return fmt.Errorf(errMultiple, cEvent, cDateTimeStamp)
263 }
264
265 requiredDateTimeStamp = true
266
267 if err := s.DateTimeStamp.decode(params, value); err != nil {
268 return fmt.Errorf(errDecodingProp, cEvent, cDateTimeStamp, err)
269 }
270 case "UID":
271 if requiredUID {
272 return fmt.Errorf(errMultiple, cEvent, cUID)
273 }
274
275 requiredUID = true
276
277 if err := s.UID.decode(params, value); err != nil {
278 return fmt.Errorf(errDecodingProp, cEvent, cUID, err)
279 }
280 case "DTSTART":
281 if s.DateTimeStart != nil {
282 return fmt.Errorf(errMultiple, cEvent, cDateTimeStart)
283 }
284
285 s.DateTimeStart = new(PropDateTimeStart)
286
287 if err := s.DateTimeStart.decode(params, value); err != nil {
288 return fmt.Errorf(errDecodingProp, cEvent, cDateTimeStart, err)
289 }
290 case "CLASS":
291 if s.Class != nil {
292 return fmt.Errorf(errMultiple, cEvent, cClass)
293 }
294
295 s.Class = new(PropClass)
296
297 if err := s.Class.decode(params, value); err != nil {
298 return fmt.Errorf(errDecodingProp, cEvent, cClass, err)
299 }
300 case "CREATED":
301 if s.Created != nil {
302 return fmt.Errorf(errMultiple, cEvent, cCreated)
303 }
304
305 s.Created = new(PropCreated)
306
307 if err := s.Created.decode(params, value); err != nil {
308 return fmt.Errorf(errDecodingProp, cEvent, cCreated, err)
309 }
310 case "DESCRIPTION":
311 if s.Description != nil {
312 return fmt.Errorf(errMultiple, cEvent, cDescription)
313 }
314
315 s.Description = new(PropDescription)
316
317 if err := s.Description.decode(params, value); err != nil {
318 return fmt.Errorf(errDecodingProp, cEvent, cDescription, err)
319 }
320 case "GEO":
321 if s.Geo != nil {
322 return fmt.Errorf(errMultiple, cEvent, cGeo)
323 }
324
325 s.Geo = new(PropGeo)
326
327 if err := s.Geo.decode(params, value); err != nil {
328 return fmt.Errorf(errDecodingProp, cEvent, cGeo, err)
329 }
330 case "LAST-MOD":
331 if s.LastModified != nil {
332 return fmt.Errorf(errMultiple, cEvent, cLastModified)
333 }
334
335 s.LastModified = new(PropLastModified)
336
337 if err := s.LastModified.decode(params, value); err != nil {
338 return fmt.Errorf(errDecodingProp, cEvent, cLastModified, err)
339 }
340 case "LOCATION":
341 if s.Location != nil {
342 return fmt.Errorf(errMultiple, cEvent, cLocation)
343 }
344
345 s.Location = new(PropLocation)
346
347 if err := s.Location.decode(params, value); err != nil {
348 return fmt.Errorf(errDecodingProp, cEvent, cLocation, err)
349 }
350 case "ORGANIZER":
351 if s.Organizer != nil {
352 return fmt.Errorf(errMultiple, cEvent, cOrganizer)
353 }
354
355 s.Organizer = new(PropOrganizer)
356
357 if err := s.Organizer.decode(params, value); err != nil {
358 return fmt.Errorf(errDecodingProp, cEvent, cOrganizer, err)
359 }
360 case "PRIORITY":
361 if s.Priority != nil {
362 return fmt.Errorf(errMultiple, cEvent, cPriority)
363 }
364
365 s.Priority = new(PropPriority)
366
367 if err := s.Priority.decode(params, value); err != nil {
368 return fmt.Errorf(errDecodingProp, cEvent, cPriority, err)
369 }
370 case "SEQUENCE":
371 if s.Sequence != nil {
372 return fmt.Errorf(errMultiple, cEvent, cSequence)
373 }
374
375 s.Sequence = new(PropSequence)
376
377 if err := s.Sequence.decode(params, value); err != nil {
378 return fmt.Errorf(errDecodingProp, cEvent, cSequence, err)
379 }
380 case "STATUS":
381 if s.Status != nil {
382 return fmt.Errorf(errMultiple, cEvent, cStatus)
383 }
384
385 s.Status = new(PropStatus)
386
387 if err := s.Status.decode(params, value); err != nil {
388 return fmt.Errorf(errDecodingProp, cEvent, cStatus, err)
389 }
390 case "SUMMARY":
391 if s.Summary != nil {
392 return fmt.Errorf(errMultiple, cEvent, cSummary)
393 }
394
395 s.Summary = new(PropSummary)
396
397 if err := s.Summary.decode(params, value); err != nil {
398 return fmt.Errorf(errDecodingProp, cEvent, cSummary, err)
399 }
400 case "TRANSP":
401 if s.TimeTransparency != nil {
402 return fmt.Errorf(errMultiple, cEvent, cTimeTransparency)
403 }
404
405 s.TimeTransparency = new(PropTimeTransparency)
406
407 if err := s.TimeTransparency.decode(params, value); err != nil {
408 return fmt.Errorf(errDecodingProp, cEvent, cTimeTransparency, err)
409 }
410 case "URL":
411 if s.URL != nil {
412 return fmt.Errorf(errMultiple, cEvent, cURL)
413 }
414
415 s.URL = new(PropURL)
416
417 if err := s.URL.decode(params, value); err != nil {
418 return fmt.Errorf(errDecodingProp, cEvent, cURL, err)
419 }
420 case "RECURRENCE-ID":
421 if s.RecurrenceID != nil {
422 return fmt.Errorf(errMultiple, cEvent, cRecurrenceID)
423 }
424
425 s.RecurrenceID = new(PropRecurrenceID)
426
427 if err := s.RecurrenceID.decode(params, value); err != nil {
428 return fmt.Errorf(errDecodingProp, cEvent, cRecurrenceID, err)
429 }
430 case "RRULE":
431 if s.RecurrenceRule != nil {
432 return fmt.Errorf(errMultiple, cEvent, cRecurrenceRule)
433 }
434
435 s.RecurrenceRule = new(PropRecurrenceRule)
436
437 if err := s.RecurrenceRule.decode(params, value); err != nil {
438 return fmt.Errorf(errDecodingProp, cEvent, cRecurrenceRule, err)
439 }
440 case "DTEND":
441 if s.DateTimeEnd != nil {
442 return fmt.Errorf(errMultiple, cEvent, cDateTimeEnd)
443 }
444
445 s.DateTimeEnd = new(PropDateTimeEnd)
446
447 if err := s.DateTimeEnd.decode(params, value); err != nil {
448 return fmt.Errorf(errDecodingProp, cEvent, cDateTimeEnd, err)
449 }
450 case "DURATION":
451 if s.Duration != nil {
452 return fmt.Errorf(errMultiple, cEvent, cDuration)
453 }
454
455 s.Duration = new(PropDuration)
456
457 if err := s.Duration.decode(params, value); err != nil {
458 return fmt.Errorf(errDecodingProp, cEvent, cDuration, err)
459 }
460 case "ATTACH":
461 var e PropAttachment
462
463 if err := e.decode(params, value); err != nil {
464 return fmt.Errorf(errDecodingProp, cEvent, cAttachment, err)
465 }
466
467 s.Attachment = append(s.Attachment, e)
468 case "ATTENDEE":
469 var e PropAttendee
470
471 if err := e.decode(params, value); err != nil {
472 return fmt.Errorf(errDecodingProp, cEvent, cAttendee, err)
473 }
474
475 s.Attendee = append(s.Attendee, e)
476 case "CATEGORIES":
477 var e PropCategories
478
479 if err := e.decode(params, value); err != nil {
480 return fmt.Errorf(errDecodingProp, cEvent, cCategories, err)
481 }
482
483 s.Categories = append(s.Categories, e)
484 case "COMMENT":
485 var e PropComment
486
487 if err := e.decode(params, value); err != nil {
488 return fmt.Errorf(errDecodingProp, cEvent, cComment, err)
489 }
490
491 s.Comment = append(s.Comment, e)
492 case "CONTACT":
493 var e PropContact
494
495 if err := e.decode(params, value); err != nil {
496 return fmt.Errorf(errDecodingProp, cEvent, cContact, err)
497 }
498
499 s.Contact = append(s.Contact, e)
500 case "EXDATE":
501 var e PropExceptionDateTime
502
503 if err := e.decode(params, value); err != nil {
504 return fmt.Errorf(errDecodingProp, cEvent, cExceptionDateTime, err)
505 }
506
507 s.ExceptionDateTime = append(s.ExceptionDateTime, e)
508 case "REQUEST-STATUS":
509 var e PropRequestStatus
510
511 if err := e.decode(params, value); err != nil {
512 return fmt.Errorf(errDecodingProp, cEvent, cRequestStatus, err)
513 }
514
515 s.RequestStatus = append(s.RequestStatus, e)
516 case "RELATED-TO":
517 var e PropRelatedTo
518
519 if err := e.decode(params, value); err != nil {
520 return fmt.Errorf(errDecodingProp, cEvent, cRelatedTo, err)
521 }
522
523 s.RelatedTo = append(s.RelatedTo, e)
524 case "RESOURCES":
525 var e PropResources
526
527 if err := e.decode(params, value); err != nil {
528 return fmt.Errorf(errDecodingProp, cEvent, cResources, err)
529 }
530
531 s.Resources = append(s.Resources, e)
532 case "RDATE":
533 var e PropRecurrenceDateTimes
534
535 if err := e.decode(params, value); err != nil {
536 return fmt.Errorf(errDecodingProp, cEvent, cRecurrenceDateTimes, err)
537 }
538
539 s.RecurrenceDateTimes = append(s.RecurrenceDateTimes, e)
540 case "END":
541 if value != "VEVENT" {
542 return fmt.Errorf(errDecodingType, cEvent, ErrInvalidEnd)
543 }
544
545 break Loop
546 }
547 }
548
549 if !requiredDateTimeStamp || !requiredUID {
550 return fmt.Errorf(errDecodingType, cEvent, ErrMissingRequired)
551 }
552
553 if s.DateTimeEnd != nil && s.Duration != nil {
554 return fmt.Errorf(errDecodingType, cEvent, ErrRequirementNotMet)
555 }
556
557 return nil
558 }
559
560 func (s *Event) encode(w writer) {
561 w.WriteString("BEGIN:VEVENT\r\n")
562 s.DateTimeStamp.encode(w)
563 s.UID.encode(w)
564
565 if s.DateTimeStart != nil {
566 s.DateTimeStart.encode(w)
567 }
568
569 if s.Class != nil {
570 s.Class.encode(w)
571 }
572
573 if s.Created != nil {
574 s.Created.encode(w)
575 }
576
577 if s.Description != nil {
578 s.Description.encode(w)
579 }
580
581 if s.Geo != nil {
582 s.Geo.encode(w)
583 }
584
585 if s.LastModified != nil {
586 s.LastModified.encode(w)
587 }
588
589 if s.Location != nil {
590 s.Location.encode(w)
591 }
592
593 if s.Organizer != nil {
594 s.Organizer.encode(w)
595 }
596
597 if s.Priority != nil {
598 s.Priority.encode(w)
599 }
600
601 if s.Sequence != nil {
602 s.Sequence.encode(w)
603 }
604
605 if s.Status != nil {
606 s.Status.encode(w)
607 }
608
609 if s.Summary != nil {
610 s.Summary.encode(w)
611 }
612
613 if s.TimeTransparency != nil {
614 s.TimeTransparency.encode(w)
615 }
616
617 if s.URL != nil {
618 s.URL.encode(w)
619 }
620
621 if s.RecurrenceID != nil {
622 s.RecurrenceID.encode(w)
623 }
624
625 if s.RecurrenceRule != nil {
626 s.RecurrenceRule.encode(w)
627 }
628
629 if s.DateTimeEnd != nil {
630 s.DateTimeEnd.encode(w)
631 }
632
633 if s.Duration != nil {
634 s.Duration.encode(w)
635 }
636
637 for n := range s.Attachment {
638 s.Attachment[n].encode(w)
639 }
640
641 for n := range s.Attendee {
642 s.Attendee[n].encode(w)
643 }
644
645 for n := range s.Categories {
646 s.Categories[n].encode(w)
647 }
648
649 for n := range s.Comment {
650 s.Comment[n].encode(w)
651 }
652
653 for n := range s.Contact {
654 s.Contact[n].encode(w)
655 }
656
657 for n := range s.ExceptionDateTime {
658 s.ExceptionDateTime[n].encode(w)
659 }
660
661 for n := range s.RequestStatus {
662 s.RequestStatus[n].encode(w)
663 }
664
665 for n := range s.RelatedTo {
666 s.RelatedTo[n].encode(w)
667 }
668
669 for n := range s.Resources {
670 s.Resources[n].encode(w)
671 }
672
673 for n := range s.RecurrenceDateTimes {
674 s.RecurrenceDateTimes[n].encode(w)
675 }
676
677 for n := range s.Alarm {
678 s.Alarm[n].encode(w)
679 }
680
681 w.WriteString("END:VEVENT\r\n")
682 }
683
684 func (s *Event) valid() error {
685 if err := s.DateTimeStamp.valid(); err != nil {
686 return fmt.Errorf(errValidatingProp, cEvent, cDateTimeStamp, err)
687 }
688
689 if err := s.UID.valid(); err != nil {
690 return fmt.Errorf(errValidatingProp, cEvent, cUID, err)
691 }
692
693 if s.DateTimeStart != nil {
694 if err := s.DateTimeStart.valid(); err != nil {
695 return fmt.Errorf(errValidatingProp, cEvent, cDateTimeStart, err)
696 }
697 }
698
699 if s.Class != nil {
700 if err := s.Class.valid(); err != nil {
701 return fmt.Errorf(errValidatingProp, cEvent, cClass, err)
702 }
703 }
704
705 if s.Created != nil {
706 if err := s.Created.valid(); err != nil {
707 return fmt.Errorf(errValidatingProp, cEvent, cCreated, err)
708 }
709 }
710
711 if s.Description != nil {
712 if err := s.Description.valid(); err != nil {
713 return fmt.Errorf(errValidatingProp, cEvent, cDescription, err)
714 }
715 }
716
717 if s.Geo != nil {
718 if err := s.Geo.valid(); err != nil {
719 return fmt.Errorf(errValidatingProp, cEvent, cGeo, err)
720 }
721 }
722
723 if s.LastModified != nil {
724 if err := s.LastModified.valid(); err != nil {
725 return fmt.Errorf(errValidatingProp, cEvent, cLastModified, err)
726 }
727 }
728
729 if s.Location != nil {
730 if err := s.Location.valid(); err != nil {
731 return fmt.Errorf(errValidatingProp, cEvent, cLocation, err)
732 }
733 }
734
735 if s.Organizer != nil {
736 if err := s.Organizer.valid(); err != nil {
737 return fmt.Errorf(errValidatingProp, cEvent, cOrganizer, err)
738 }
739 }
740
741 if s.Priority != nil {
742 if err := s.Priority.valid(); err != nil {
743 return fmt.Errorf(errValidatingProp, cEvent, cPriority, err)
744 }
745 }
746
747 if s.Sequence != nil {
748 if err := s.Sequence.valid(); err != nil {
749 return fmt.Errorf(errValidatingProp, cEvent, cSequence, err)
750 }
751 }
752
753 if s.Status != nil {
754 if err := s.Status.valid(); err != nil {
755 return fmt.Errorf(errValidatingProp, cEvent, cStatus, err)
756 }
757 }
758
759 if s.Summary != nil {
760 if err := s.Summary.valid(); err != nil {
761 return fmt.Errorf(errValidatingProp, cEvent, cSummary, err)
762 }
763 }
764
765 if s.TimeTransparency != nil {
766 if err := s.TimeTransparency.valid(); err != nil {
767 return fmt.Errorf(errValidatingProp, cEvent, cTimeTransparency, err)
768 }
769 }
770
771 if s.URL != nil {
772 if err := s.URL.valid(); err != nil {
773 return fmt.Errorf(errValidatingProp, cEvent, cURL, err)
774 }
775 }
776
777 if s.RecurrenceID != nil {
778 if err := s.RecurrenceID.valid(); err != nil {
779 return fmt.Errorf(errValidatingProp, cEvent, cRecurrenceID, err)
780 }
781 }
782
783 if s.RecurrenceRule != nil {
784 if err := s.RecurrenceRule.valid(); err != nil {
785 return fmt.Errorf(errValidatingProp, cEvent, cRecurrenceRule, err)
786 }
787 }
788
789 if s.DateTimeEnd != nil {
790 if err := s.DateTimeEnd.valid(); err != nil {
791 return fmt.Errorf(errValidatingProp, cEvent, cDateTimeEnd, err)
792 }
793 }
794
795 if s.Duration != nil {
796 if err := s.Duration.valid(); err != nil {
797 return fmt.Errorf(errValidatingProp, cEvent, cDuration, err)
798 }
799 }
800
801 for n := range s.Attachment {
802 if err := s.Attachment[n].valid(); err != nil {
803 return fmt.Errorf(errValidatingProp, cEvent, cAttachment, err)
804 }
805 }
806
807 for n := range s.Attendee {
808 if err := s.Attendee[n].valid(); err != nil {
809 return fmt.Errorf(errValidatingProp, cEvent, cAttendee, err)
810 }
811 }
812
813 for n := range s.Categories {
814 if err := s.Categories[n].valid(); err != nil {
815 return fmt.Errorf(errValidatingProp, cEvent, cCategories, err)
816 }
817 }
818
819 for n := range s.Comment {
820 if err := s.Comment[n].valid(); err != nil {
821 return fmt.Errorf(errValidatingProp, cEvent, cComment, err)
822 }
823 }
824
825 for n := range s.Contact {
826 if err := s.Contact[n].valid(); err != nil {
827 return fmt.Errorf(errValidatingProp, cEvent, cContact, err)
828 }
829 }
830
831 for n := range s.ExceptionDateTime {
832 if err := s.ExceptionDateTime[n].valid(); err != nil {
833 return fmt.Errorf(errValidatingProp, cEvent, cExceptionDateTime, err)
834 }
835 }
836
837 for n := range s.RequestStatus {
838 if err := s.RequestStatus[n].valid(); err != nil {
839 return fmt.Errorf(errValidatingProp, cEvent, cRequestStatus, err)
840 }
841 }
842
843 for n := range s.RelatedTo {
844 if err := s.RelatedTo[n].valid(); err != nil {
845 return fmt.Errorf(errValidatingProp, cEvent, cRelatedTo, err)
846 }
847 }
848
849 for n := range s.Resources {
850 if err := s.Resources[n].valid(); err != nil {
851 return fmt.Errorf(errValidatingProp, cEvent, cResources, err)
852 }
853 }
854
855 for n := range s.RecurrenceDateTimes {
856 if err := s.RecurrenceDateTimes[n].valid(); err != nil {
857 return fmt.Errorf(errValidatingProp, cEvent, cRecurrenceDateTimes, err)
858 }
859 }
860
861 for n := range s.Alarm {
862 if err := s.Alarm[n].valid(); err != nil {
863 return fmt.Errorf(errValidatingProp, cEvent, cAlarm, err)
864 }
865 }
866
867 return nil
868 }
869
870 // Todo provides a group of components that describe a to-do.
871 type Todo struct {
872 DateTimeStamp PropDateTimeStamp
873 UID PropUID
874 Class *PropClass
875 Completed *PropCompleted
876 Created *PropCreated
877 Description *PropDescription
878 DateTimeStart *PropDateTimeStart
879 Geo *PropGeo
880 LastModified *PropLastModified
881 Location *PropLocation
882 Organizer *PropOrganizer
883 PercentComplete *PropPercentComplete
884 Priority *PropPriority
885 RecurrenceID *PropRecurrenceID
886 Sequence *PropSequence
887 Status *PropStatus
888 Summary *PropSummary
889 URL *PropURL
890 Due *PropDue
891 Duration *PropDuration
892 Attachment []PropAttachment
893 Attendee []PropAttendee
894 Categories []PropCategories
895 Comment []PropComment
896 Contact []PropContact
897 ExceptionDateTime []PropExceptionDateTime
898 RequestStatus []PropRequestStatus
899 RelatedTo []PropRelatedTo
900 Resources []PropResources
901 RecurrenceDateTimes []PropRecurrenceDateTimes
902 Alarm []Alarm
903 }
904
905 func (s *Todo) decode(t tokeniser) error {
906 var requiredDateTimeStamp, requiredUID bool
907
908 Loop:
909 for {
910 p, err := t.GetPhrase()
911 if err != nil {
912 return fmt.Errorf(errDecodingType, cTodo, err)
913 } else if p.Type == parser.PhraseDone {
914 return fmt.Errorf(errDecodingType, cTodo, io.ErrUnexpectedEOF)
915 }
916
917 params := p.Data[1 : len(p.Data)-1]
918 value := p.Data[len(p.Data)-1].Data
919
920 switch strings.ToUpper(p.Data[0].Data) {
921 case "BEGIN":
922 switch n := strings.ToUpper(value); n {
923 case "VALARM":
924 var e Alarm
925
926 if err := e.decode(t); err != nil {
927 return fmt.Errorf(errDecodingProp, cTodo, cAlarm, err)
928 }
929
930 s.Alarm = append(s.Alarm, e)
931 default:
932 if err := decodeDummy(t, n); err != nil {
933 return fmt.Errorf(errDecodingType, cTodo, err)
934 }
935 }
936 case "DTSTAMP":
937 if requiredDateTimeStamp {
938 return fmt.Errorf(errMultiple, cTodo, cDateTimeStamp)
939 }
940
941 requiredDateTimeStamp = true
942
943 if err := s.DateTimeStamp.decode(params, value); err != nil {
944 return fmt.Errorf(errDecodingProp, cTodo, cDateTimeStamp, err)
945 }
946 case "UID":
947 if requiredUID {
948 return fmt.Errorf(errMultiple, cTodo, cUID)
949 }
950
951 requiredUID = true
952
953 if err := s.UID.decode(params, value); err != nil {
954 return fmt.Errorf(errDecodingProp, cTodo, cUID, err)
955 }
956 case "CLASS":
957 if s.Class != nil {
958 return fmt.Errorf(errMultiple, cTodo, cClass)
959 }
960
961 s.Class = new(PropClass)
962
963 if err := s.Class.decode(params, value); err != nil {
964 return fmt.Errorf(errDecodingProp, cTodo, cClass, err)
965 }
966 case "COMPLETED":
967 if s.Completed != nil {
968 return fmt.Errorf(errMultiple, cTodo, cCompleted)
969 }
970
971 s.Completed = new(PropCompleted)
972
973 if err := s.Completed.decode(params, value); err != nil {
974 return fmt.Errorf(errDecodingProp, cTodo, cCompleted, err)
975 }
976 case "CREATED":
977 if s.Created != nil {
978 return fmt.Errorf(errMultiple, cTodo, cCreated)
979 }
980
981 s.Created = new(PropCreated)
982
983 if err := s.Created.decode(params, value); err != nil {
984 return fmt.Errorf(errDecodingProp, cTodo, cCreated, err)
985 }
986 case "DESCRIPTION":
987 if s.Description != nil {
988 return fmt.Errorf(errMultiple, cTodo, cDescription)
989 }
990
991 s.Description = new(PropDescription)
992
993 if err := s.Description.decode(params, value); err != nil {
994 return fmt.Errorf(errDecodingProp, cTodo, cDescription, err)
995 }
996 case "DTSTART":
997 if s.DateTimeStart != nil {
998 return fmt.Errorf(errMultiple, cTodo, cDateTimeStart)
999 }
1000
1001 s.DateTimeStart = new(PropDateTimeStart)
1002
1003 if err := s.DateTimeStart.decode(params, value); err != nil {
1004 return fmt.Errorf(errDecodingProp, cTodo, cDateTimeStart, err)
1005 }
1006 case "GEO":
1007 if s.Geo != nil {
1008 return fmt.Errorf(errMultiple, cTodo, cGeo)
1009 }
1010
1011 s.Geo = new(PropGeo)
1012
1013 if err := s.Geo.decode(params, value); err != nil {
1014 return fmt.Errorf(errDecodingProp, cTodo, cGeo, err)
1015 }
1016 case "LAST-MOD":
1017 if s.LastModified != nil {
1018 return fmt.Errorf(errMultiple, cTodo, cLastModified)
1019 }
1020
1021 s.LastModified = new(PropLastModified)
1022
1023 if err := s.LastModified.decode(params, value); err != nil {
1024 return fmt.Errorf(errDecodingProp, cTodo, cLastModified, err)
1025 }
1026 case "LOCATION":
1027 if s.Location != nil {
1028 return fmt.Errorf(errMultiple, cTodo, cLocation)
1029 }
1030
1031 s.Location = new(PropLocation)
1032
1033 if err := s.Location.decode(params, value); err != nil {
1034 return fmt.Errorf(errDecodingProp, cTodo, cLocation, err)
1035 }
1036 case "ORGANIZER":
1037 if s.Organizer != nil {
1038 return fmt.Errorf(errMultiple, cTodo, cOrganizer)
1039 }
1040
1041 s.Organizer = new(PropOrganizer)
1042
1043 if err := s.Organizer.decode(params, value); err != nil {
1044 return fmt.Errorf(errDecodingProp, cTodo, cOrganizer, err)
1045 }
1046 case "PERCENT-COMPLETE":
1047 if s.PercentComplete != nil {
1048 return fmt.Errorf(errMultiple, cTodo, cPercentComplete)
1049 }
1050
1051 s.PercentComplete = new(PropPercentComplete)
1052
1053 if err := s.PercentComplete.decode(params, value); err != nil {
1054 return fmt.Errorf(errDecodingProp, cTodo, cPercentComplete, err)
1055 }
1056 case "PRIORITY":
1057 if s.Priority != nil {
1058 return fmt.Errorf(errMultiple, cTodo, cPriority)
1059 }
1060
1061 s.Priority = new(PropPriority)
1062
1063 if err := s.Priority.decode(params, value); err != nil {
1064 return fmt.Errorf(errDecodingProp, cTodo, cPriority, err)
1065 }
1066 case "RECURRENCE-ID":
1067 if s.RecurrenceID != nil {
1068 return fmt.Errorf(errMultiple, cTodo, cRecurrenceID)
1069 }
1070
1071 s.RecurrenceID = new(PropRecurrenceID)
1072
1073 if err := s.RecurrenceID.decode(params, value); err != nil {
1074 return fmt.Errorf(errDecodingProp, cTodo, cRecurrenceID, err)
1075 }
1076 case "SEQUENCE":
1077 if s.Sequence != nil {
1078 return fmt.Errorf(errMultiple, cTodo, cSequence)
1079 }
1080
1081 s.Sequence = new(PropSequence)
1082
1083 if err := s.Sequence.decode(params, value); err != nil {
1084 return fmt.Errorf(errDecodingProp, cTodo, cSequence, err)
1085 }
1086 case "STATUS":
1087 if s.Status != nil {
1088 return fmt.Errorf(errMultiple, cTodo, cStatus)
1089 }
1090
1091 s.Status = new(PropStatus)
1092
1093 if err := s.Status.decode(params, value); err != nil {
1094 return fmt.Errorf(errDecodingProp, cTodo, cStatus, err)
1095 }
1096 case "SUMMARY":
1097 if s.Summary != nil {
1098 return fmt.Errorf(errMultiple, cTodo, cSummary)
1099 }
1100
1101 s.Summary = new(PropSummary)
1102
1103 if err := s.Summary.decode(params, value); err != nil {
1104 return fmt.Errorf(errDecodingProp, cTodo, cSummary, err)
1105 }
1106 case "URL":
1107 if s.URL != nil {
1108 return fmt.Errorf(errMultiple, cTodo, cURL)
1109 }
1110
1111 s.URL = new(PropURL)
1112
1113 if err := s.URL.decode(params, value); err != nil {
1114 return fmt.Errorf(errDecodingProp, cTodo, cURL, err)
1115 }
1116 case "DUE":
1117 if s.Due != nil {
1118 return fmt.Errorf(errMultiple, cTodo, cDue)
1119 }
1120
1121 s.Due = new(PropDue)
1122
1123 if err := s.Due.decode(params, value); err != nil {
1124 return fmt.Errorf(errDecodingProp, cTodo, cDue, err)
1125 }
1126 case "DURATION":
1127 if s.Duration != nil {
1128 return fmt.Errorf(errMultiple, cTodo, cDuration)
1129 }
1130
1131 s.Duration = new(PropDuration)
1132
1133 if err := s.Duration.decode(params, value); err != nil {
1134 return fmt.Errorf(errDecodingProp, cTodo, cDuration, err)
1135 }
1136 case "ATTACH":
1137 var e PropAttachment
1138
1139 if err := e.decode(params, value); err != nil {
1140 return fmt.Errorf(errDecodingProp, cTodo, cAttachment, err)
1141 }
1142
1143 s.Attachment = append(s.Attachment, e)
1144 case "ATTENDEE":
1145 var e PropAttendee
1146
1147 if err := e.decode(params, value); err != nil {
1148 return fmt.Errorf(errDecodingProp, cTodo, cAttendee, err)
1149 }
1150
1151 s.Attendee = append(s.Attendee, e)
1152 case "CATEGORIES":
1153 var e PropCategories
1154
1155 if err := e.decode(params, value); err != nil {
1156 return fmt.Errorf(errDecodingProp, cTodo, cCategories, err)
1157 }
1158
1159 s.Categories = append(s.Categories, e)
1160 case "COMMENT":
1161 var e PropComment
1162
1163 if err := e.decode(params, value); err != nil {
1164 return fmt.Errorf(errDecodingProp, cTodo, cComment, err)
1165 }
1166
1167 s.Comment = append(s.Comment, e)
1168 case "CONTACT":
1169 var e PropContact
1170
1171 if err := e.decode(params, value); err != nil {
1172 return fmt.Errorf(errDecodingProp, cTodo, cContact, err)
1173 }
1174
1175 s.Contact = append(s.Contact, e)
1176 case "EXDATE":
1177 var e PropExceptionDateTime
1178
1179 if err := e.decode(params, value); err != nil {
1180 return fmt.Errorf(errDecodingProp, cTodo, cExceptionDateTime, err)
1181 }
1182
1183 s.ExceptionDateTime = append(s.ExceptionDateTime, e)
1184 case "REQUEST-STATUS":
1185 var e PropRequestStatus
1186
1187 if err := e.decode(params, value); err != nil {
1188 return fmt.Errorf(errDecodingProp, cTodo, cRequestStatus, err)
1189 }
1190
1191 s.RequestStatus = append(s.RequestStatus, e)
1192 case "RELATED-TO":
1193 var e PropRelatedTo
1194
1195 if err := e.decode(params, value); err != nil {
1196 return fmt.Errorf(errDecodingProp, cTodo, cRelatedTo, err)
1197 }
1198
1199 s.RelatedTo = append(s.RelatedTo, e)
1200 case "RESOURCES":
1201 var e PropResources
1202
1203 if err := e.decode(params, value); err != nil {
1204 return fmt.Errorf(errDecodingProp, cTodo, cResources, err)
1205 }
1206
1207 s.Resources = append(s.Resources, e)
1208 case "RDATE":
1209 var e PropRecurrenceDateTimes
1210
1211 if err := e.decode(params, value); err != nil {
1212 return fmt.Errorf(errDecodingProp, cTodo, cRecurrenceDateTimes, err)
1213 }
1214
1215 s.RecurrenceDateTimes = append(s.RecurrenceDateTimes, e)
1216 case "END":
1217 if value != "VTODO" {
1218 return fmt.Errorf(errDecodingType, cTodo, ErrInvalidEnd)
1219 }
1220
1221 break Loop
1222 }
1223 }
1224
1225 if !requiredDateTimeStamp || !requiredUID {
1226 return fmt.Errorf(errDecodingType, cTodo, ErrMissingRequired)
1227 }
1228
1229 if s.Duration != nil && (s.DateTimeStart == nil) {
1230 return fmt.Errorf(errDecodingType, cTodo, ErrRequirementNotMet)
1231 }
1232
1233 if s.Due != nil && s.Duration != nil {
1234 return fmt.Errorf(errDecodingType, cTodo, ErrRequirementNotMet)
1235 }
1236
1237 return nil
1238 }
1239
1240 func (s *Todo) encode(w writer) {
1241 w.WriteString("BEGIN:VTODO\r\n")
1242 s.DateTimeStamp.encode(w)
1243 s.UID.encode(w)
1244
1245 if s.Class != nil {
1246 s.Class.encode(w)
1247 }
1248
1249 if s.Completed != nil {
1250 s.Completed.encode(w)
1251 }
1252
1253 if s.Created != nil {
1254 s.Created.encode(w)
1255 }
1256
1257 if s.Description != nil {
1258 s.Description.encode(w)
1259 }
1260
1261 if s.DateTimeStart != nil {
1262 s.DateTimeStart.encode(w)
1263 }
1264
1265 if s.Geo != nil {
1266 s.Geo.encode(w)
1267 }
1268
1269 if s.LastModified != nil {
1270 s.LastModified.encode(w)
1271 }
1272
1273 if s.Location != nil {
1274 s.Location.encode(w)
1275 }
1276
1277 if s.Organizer != nil {
1278 s.Organizer.encode(w)
1279 }
1280
1281 if s.PercentComplete != nil {
1282 s.PercentComplete.encode(w)
1283 }
1284
1285 if s.Priority != nil {
1286 s.Priority.encode(w)
1287 }
1288
1289 if s.RecurrenceID != nil {
1290 s.RecurrenceID.encode(w)
1291 }
1292
1293 if s.Sequence != nil {
1294 s.Sequence.encode(w)
1295 }
1296
1297 if s.Status != nil {
1298 s.Status.encode(w)
1299 }
1300
1301 if s.Summary != nil {
1302 s.Summary.encode(w)
1303 }
1304
1305 if s.URL != nil {
1306 s.URL.encode(w)
1307 }
1308
1309 if s.Due != nil {
1310 s.Due.encode(w)
1311 }
1312
1313 if s.Duration != nil {
1314 s.Duration.encode(w)
1315 }
1316
1317 for n := range s.Attachment {
1318 s.Attachment[n].encode(w)
1319 }
1320
1321 for n := range s.Attendee {
1322 s.Attendee[n].encode(w)
1323 }
1324
1325 for n := range s.Categories {
1326 s.Categories[n].encode(w)
1327 }
1328
1329 for n := range s.Comment {
1330 s.Comment[n].encode(w)
1331 }
1332
1333 for n := range s.Contact {
1334 s.Contact[n].encode(w)
1335 }
1336
1337 for n := range s.ExceptionDateTime {
1338 s.ExceptionDateTime[n].encode(w)
1339 }
1340
1341 for n := range s.RequestStatus {
1342 s.RequestStatus[n].encode(w)
1343 }
1344
1345 for n := range s.RelatedTo {
1346 s.RelatedTo[n].encode(w)
1347 }
1348
1349 for n := range s.Resources {
1350 s.Resources[n].encode(w)
1351 }
1352
1353 for n := range s.RecurrenceDateTimes {
1354 s.RecurrenceDateTimes[n].encode(w)
1355 }
1356
1357 for n := range s.Alarm {
1358 s.Alarm[n].encode(w)
1359 }
1360
1361 w.WriteString("END:VTODO\r\n")
1362 }
1363
1364 func (s *Todo) valid() error {
1365 if err := s.DateTimeStamp.valid(); err != nil {
1366 return fmt.Errorf(errValidatingProp, cTodo, cDateTimeStamp, err)
1367 }
1368
1369 if err := s.UID.valid(); err != nil {
1370 return fmt.Errorf(errValidatingProp, cTodo, cUID, err)
1371 }
1372
1373 if s.Class != nil {
1374 if err := s.Class.valid(); err != nil {
1375 return fmt.Errorf(errValidatingProp, cTodo, cClass, err)
1376 }
1377 }
1378
1379 if s.Completed != nil {
1380 if err := s.Completed.valid(); err != nil {
1381 return fmt.Errorf(errValidatingProp, cTodo, cCompleted, err)
1382 }
1383 }
1384
1385 if s.Created != nil {
1386 if err := s.Created.valid(); err != nil {
1387 return fmt.Errorf(errValidatingProp, cTodo, cCreated, err)
1388 }
1389 }
1390
1391 if s.Description != nil {
1392 if err := s.Description.valid(); err != nil {
1393 return fmt.Errorf(errValidatingProp, cTodo, cDescription, err)
1394 }
1395 }
1396
1397 if s.DateTimeStart != nil {
1398 if err := s.DateTimeStart.valid(); err != nil {
1399 return fmt.Errorf(errValidatingProp, cTodo, cDateTimeStart, err)
1400 }
1401 }
1402
1403 if s.Geo != nil {
1404 if err := s.Geo.valid(); err != nil {
1405 return fmt.Errorf(errValidatingProp, cTodo, cGeo, err)
1406 }
1407 }
1408
1409 if s.LastModified != nil {
1410 if err := s.LastModified.valid(); err != nil {
1411 return fmt.Errorf(errValidatingProp, cTodo, cLastModified, err)
1412 }
1413 }
1414
1415 if s.Location != nil {
1416 if err := s.Location.valid(); err != nil {
1417 return fmt.Errorf(errValidatingProp, cTodo, cLocation, err)
1418 }
1419 }
1420
1421 if s.Organizer != nil {
1422 if err := s.Organizer.valid(); err != nil {
1423 return fmt.Errorf(errValidatingProp, cTodo, cOrganizer, err)
1424 }
1425 }
1426
1427 if s.PercentComplete != nil {
1428 if err := s.PercentComplete.valid(); err != nil {
1429 return fmt.Errorf(errValidatingProp, cTodo, cPercentComplete, err)
1430 }
1431 }
1432
1433 if s.Priority != nil {
1434 if err := s.Priority.valid(); err != nil {
1435 return fmt.Errorf(errValidatingProp, cTodo, cPriority, err)
1436 }
1437 }
1438
1439 if s.RecurrenceID != nil {
1440 if err := s.RecurrenceID.valid(); err != nil {
1441 return fmt.Errorf(errValidatingProp, cTodo, cRecurrenceID, err)
1442 }
1443 }
1444
1445 if s.Sequence != nil {
1446 if err := s.Sequence.valid(); err != nil {
1447 return fmt.Errorf(errValidatingProp, cTodo, cSequence, err)
1448 }
1449 }
1450
1451 if s.Status != nil {
1452 if err := s.Status.valid(); err != nil {
1453 return fmt.Errorf(errValidatingProp, cTodo, cStatus, err)
1454 }
1455 }
1456
1457 if s.Summary != nil {
1458 if err := s.Summary.valid(); err != nil {
1459 return fmt.Errorf(errValidatingProp, cTodo, cSummary, err)
1460 }
1461 }
1462
1463 if s.URL != nil {
1464 if err := s.URL.valid(); err != nil {
1465 return fmt.Errorf(errValidatingProp, cTodo, cURL, err)
1466 }
1467 }
1468
1469 if s.Due != nil {
1470 if err := s.Due.valid(); err != nil {
1471 return fmt.Errorf(errValidatingProp, cTodo, cDue, err)
1472 }
1473 }
1474
1475 if s.Duration != nil {
1476 if err := s.Duration.valid(); err != nil {
1477 return fmt.Errorf(errValidatingProp, cTodo, cDuration, err)
1478 }
1479 }
1480
1481 for n := range s.Attachment {
1482 if err := s.Attachment[n].valid(); err != nil {
1483 return fmt.Errorf(errValidatingProp, cTodo, cAttachment, err)
1484 }
1485 }
1486
1487 for n := range s.Attendee {
1488 if err := s.Attendee[n].valid(); err != nil {
1489 return fmt.Errorf(errValidatingProp, cTodo, cAttendee, err)
1490 }
1491 }
1492
1493 for n := range s.Categories {
1494 if err := s.Categories[n].valid(); err != nil {
1495 return fmt.Errorf(errValidatingProp, cTodo, cCategories, err)
1496 }
1497 }
1498
1499 for n := range s.Comment {
1500 if err := s.Comment[n].valid(); err != nil {
1501 return fmt.Errorf(errValidatingProp, cTodo, cComment, err)
1502 }
1503 }
1504
1505 for n := range s.Contact {
1506 if err := s.Contact[n].valid(); err != nil {
1507 return fmt.Errorf(errValidatingProp, cTodo, cContact, err)
1508 }
1509 }
1510
1511 for n := range s.ExceptionDateTime {
1512 if err := s.ExceptionDateTime[n].valid(); err != nil {
1513 return fmt.Errorf(errValidatingProp, cTodo, cExceptionDateTime, err)
1514 }
1515 }
1516
1517 for n := range s.RequestStatus {
1518 if err := s.RequestStatus[n].valid(); err != nil {
1519 return fmt.Errorf(errValidatingProp, cTodo, cRequestStatus, err)
1520 }
1521 }
1522
1523 for n := range s.RelatedTo {
1524 if err := s.RelatedTo[n].valid(); err != nil {
1525 return fmt.Errorf(errValidatingProp, cTodo, cRelatedTo, err)
1526 }
1527 }
1528
1529 for n := range s.Resources {
1530 if err := s.Resources[n].valid(); err != nil {
1531 return fmt.Errorf(errValidatingProp, cTodo, cResources, err)
1532 }
1533 }
1534
1535 for n := range s.RecurrenceDateTimes {
1536 if err := s.RecurrenceDateTimes[n].valid(); err != nil {
1537 return fmt.Errorf(errValidatingProp, cTodo, cRecurrenceDateTimes, err)
1538 }
1539 }
1540
1541 for n := range s.Alarm {
1542 if err := s.Alarm[n].valid(); err != nil {
1543 return fmt.Errorf(errValidatingProp, cTodo, cAlarm, err)
1544 }
1545 }
1546
1547 return nil
1548 }
1549
1550 // Journal provides a group of components that describe a journal entry.
1551 type Journal struct {
1552 DateTimeStamp PropDateTimeStamp
1553 UID PropUID
1554 Class *PropClass
1555 Created *PropCreated
1556 DateTimeStart *PropDateTimeStart
1557 LastModified *PropLastModified
1558 Organizer *PropOrganizer
1559 RecurrenceID *PropRecurrenceID
1560 Sequence *PropSequence
1561 Status *PropStatus
1562 Summary *PropSummary
1563 URL *PropURL
1564 RecurrenceRule *PropRecurrenceRule
1565 Attachment []PropAttachment
1566 Attendee []PropAttendee
1567 Categories []PropCategories
1568 Comment []PropComment
1569 Contact []PropContact
1570 Description []PropDescription
1571 ExceptionDateTime []PropExceptionDateTime
1572 RequestStatus []PropRequestStatus
1573 RelatedTo []PropRelatedTo
1574 Resources []PropResources
1575 RecurrenceDateTimes []PropRecurrenceDateTimes
1576 }
1577
1578 func (s *Journal) decode(t tokeniser) error {
1579 var requiredDateTimeStamp, requiredUID bool
1580
1581 Loop:
1582 for {
1583 p, err := t.GetPhrase()
1584 if err != nil {
1585 return fmt.Errorf(errDecodingType, cJournal, err)
1586 } else if p.Type == parser.PhraseDone {
1587 return fmt.Errorf(errDecodingType, cJournal, io.ErrUnexpectedEOF)
1588 }
1589
1590 params := p.Data[1 : len(p.Data)-1]
1591 value := p.Data[len(p.Data)-1].Data
1592
1593 switch strings.ToUpper(p.Data[0].Data) {
1594 case "BEGIN":
1595 switch n := strings.ToUpper(value); n {
1596 default:
1597 if err := decodeDummy(t, n); err != nil {
1598 return fmt.Errorf(errDecodingType, cJournal, err)
1599 }
1600 }
1601 case "DTSTAMP":
1602 if requiredDateTimeStamp {
1603 return fmt.Errorf(errMultiple, cJournal, cDateTimeStamp)
1604 }
1605
1606 requiredDateTimeStamp = true
1607
1608 if err := s.DateTimeStamp.decode(params, value); err != nil {
1609 return fmt.Errorf(errDecodingProp, cJournal, cDateTimeStamp, err)
1610 }
1611 case "UID":
1612 if requiredUID {
1613 return fmt.Errorf(errMultiple, cJournal, cUID)
1614 }
1615
1616 requiredUID = true
1617
1618 if err := s.UID.decode(params, value); err != nil {
1619 return fmt.Errorf(errDecodingProp, cJournal, cUID, err)
1620 }
1621 case "CLASS":
1622 if s.Class != nil {
1623 return fmt.Errorf(errMultiple, cJournal, cClass)
1624 }
1625
1626 s.Class = new(PropClass)
1627
1628 if err := s.Class.decode(params, value); err != nil {
1629 return fmt.Errorf(errDecodingProp, cJournal, cClass, err)
1630 }
1631 case "CREATED":
1632 if s.Created != nil {
1633 return fmt.Errorf(errMultiple, cJournal, cCreated)
1634 }
1635
1636 s.Created = new(PropCreated)
1637
1638 if err := s.Created.decode(params, value); err != nil {
1639 return fmt.Errorf(errDecodingProp, cJournal, cCreated, err)
1640 }
1641 case "DTSTART":
1642 if s.DateTimeStart != nil {
1643 return fmt.Errorf(errMultiple, cJournal, cDateTimeStart)
1644 }
1645
1646 s.DateTimeStart = new(PropDateTimeStart)
1647
1648 if err := s.DateTimeStart.decode(params, value); err != nil {
1649 return fmt.Errorf(errDecodingProp, cJournal, cDateTimeStart, err)
1650 }
1651 case "LAST-MOD":
1652 if s.LastModified != nil {
1653 return fmt.Errorf(errMultiple, cJournal, cLastModified)
1654 }
1655
1656 s.LastModified = new(PropLastModified)
1657
1658 if err := s.LastModified.decode(params, value); err != nil {
1659 return fmt.Errorf(errDecodingProp, cJournal, cLastModified, err)
1660 }
1661 case "ORGANIZER":
1662 if s.Organizer != nil {
1663 return fmt.Errorf(errMultiple, cJournal, cOrganizer)
1664 }
1665
1666 s.Organizer = new(PropOrganizer)
1667
1668 if err := s.Organizer.decode(params, value); err != nil {
1669 return fmt.Errorf(errDecodingProp, cJournal, cOrganizer, err)
1670 }
1671 case "RECURRENCE-ID":
1672 if s.RecurrenceID != nil {
1673 return fmt.Errorf(errMultiple, cJournal, cRecurrenceID)
1674 }
1675
1676 s.RecurrenceID = new(PropRecurrenceID)
1677
1678 if err := s.RecurrenceID.decode(params, value); err != nil {
1679 return fmt.Errorf(errDecodingProp, cJournal, cRecurrenceID, err)
1680 }
1681 case "SEQUENCE":
1682 if s.Sequence != nil {
1683 return fmt.Errorf(errMultiple, cJournal, cSequence)
1684 }
1685
1686 s.Sequence = new(PropSequence)
1687
1688 if err := s.Sequence.decode(params, value); err != nil {
1689 return fmt.Errorf(errDecodingProp, cJournal, cSequence, err)
1690 }
1691 case "STATUS":
1692 if s.Status != nil {
1693 return fmt.Errorf(errMultiple, cJournal, cStatus)
1694 }
1695
1696 s.Status = new(PropStatus)
1697
1698 if err := s.Status.decode(params, value); err != nil {
1699 return fmt.Errorf(errDecodingProp, cJournal, cStatus, err)
1700 }
1701 case "SUMMARY":
1702 if s.Summary != nil {
1703 return fmt.Errorf(errMultiple, cJournal, cSummary)
1704 }
1705
1706 s.Summary = new(PropSummary)
1707
1708 if err := s.Summary.decode(params, value); err != nil {
1709 return fmt.Errorf(errDecodingProp, cJournal, cSummary, err)
1710 }
1711 case "URL":
1712 if s.URL != nil {
1713 return fmt.Errorf(errMultiple, cJournal, cURL)
1714 }
1715
1716 s.URL = new(PropURL)
1717
1718 if err := s.URL.decode(params, value); err != nil {
1719 return fmt.Errorf(errDecodingProp, cJournal, cURL, err)
1720 }
1721 case "RRULE":
1722 if s.RecurrenceRule != nil {
1723 return fmt.Errorf(errMultiple, cJournal, cRecurrenceRule)
1724 }
1725
1726 s.RecurrenceRule = new(PropRecurrenceRule)
1727
1728 if err := s.RecurrenceRule.decode(params, value); err != nil {
1729 return fmt.Errorf(errDecodingProp, cJournal, cRecurrenceRule, err)
1730 }
1731 case "ATTACH":
1732 var e PropAttachment
1733
1734 if err := e.decode(params, value); err != nil {
1735 return fmt.Errorf(errDecodingProp, cJournal, cAttachment, err)
1736 }
1737
1738 s.Attachment = append(s.Attachment, e)
1739 case "ATTENDEE":
1740 var e PropAttendee
1741
1742 if err := e.decode(params, value); err != nil {
1743 return fmt.Errorf(errDecodingProp, cJournal, cAttendee, err)
1744 }
1745
1746 s.Attendee = append(s.Attendee, e)
1747 case "CATEGORIES":
1748 var e PropCategories
1749
1750 if err := e.decode(params, value); err != nil {
1751 return fmt.Errorf(errDecodingProp, cJournal, cCategories, err)
1752 }
1753
1754 s.Categories = append(s.Categories, e)
1755 case "COMMENT":
1756 var e PropComment
1757
1758 if err := e.decode(params, value); err != nil {
1759 return fmt.Errorf(errDecodingProp, cJournal, cComment, err)
1760 }
1761
1762 s.Comment = append(s.Comment, e)
1763 case "CONTACT":
1764 var e PropContact
1765
1766 if err := e.decode(params, value); err != nil {
1767 return fmt.Errorf(errDecodingProp, cJournal, cContact, err)
1768 }
1769
1770 s.Contact = append(s.Contact, e)
1771 case "DESCRIPTION":
1772 var e PropDescription
1773
1774 if err := e.decode(params, value); err != nil {
1775 return fmt.Errorf(errDecodingProp, cJournal, cDescription, err)
1776 }
1777
1778 s.Description = append(s.Description, e)
1779 case "EXDATE":
1780 var e PropExceptionDateTime
1781
1782 if err := e.decode(params, value); err != nil {
1783 return fmt.Errorf(errDecodingProp, cJournal, cExceptionDateTime, err)
1784 }
1785
1786 s.ExceptionDateTime = append(s.ExceptionDateTime, e)
1787 case "REQUEST-STATUS":
1788 var e PropRequestStatus
1789
1790 if err := e.decode(params, value); err != nil {
1791 return fmt.Errorf(errDecodingProp, cJournal, cRequestStatus, err)
1792 }
1793
1794 s.RequestStatus = append(s.RequestStatus, e)
1795 case "RELATED-TO":
1796 var e PropRelatedTo
1797
1798 if err := e.decode(params, value); err != nil {
1799 return fmt.Errorf(errDecodingProp, cJournal, cRelatedTo, err)
1800 }
1801
1802 s.RelatedTo = append(s.RelatedTo, e)
1803 case "RESOURCES":
1804 var e PropResources
1805
1806 if err := e.decode(params, value); err != nil {
1807 return fmt.Errorf(errDecodingProp, cJournal, cResources, err)
1808 }
1809
1810 s.Resources = append(s.Resources, e)
1811 case "RDATE":
1812 var e PropRecurrenceDateTimes
1813
1814 if err := e.decode(params, value); err != nil {
1815 return fmt.Errorf(errDecodingProp, cJournal, cRecurrenceDateTimes, err)
1816 }
1817
1818 s.RecurrenceDateTimes = append(s.RecurrenceDateTimes, e)
1819 case "END":
1820 if value != "VJOURNAL" {
1821 return fmt.Errorf(errDecodingType, cJournal, ErrInvalidEnd)
1822 }
1823
1824 break Loop
1825 }
1826 }
1827
1828 if !requiredDateTimeStamp || !requiredUID {
1829 return fmt.Errorf(errDecodingType, cJournal, ErrMissingRequired)
1830 }
1831
1832 return nil
1833 }
1834
1835 func (s *Journal) encode(w writer) {
1836 w.WriteString("BEGIN:VJOURNAL\r\n")
1837 s.DateTimeStamp.encode(w)
1838 s.UID.encode(w)
1839
1840 if s.Class != nil {
1841 s.Class.encode(w)
1842 }
1843
1844 if s.Created != nil {
1845 s.Created.encode(w)
1846 }
1847
1848 if s.DateTimeStart != nil {
1849 s.DateTimeStart.encode(w)
1850 }
1851
1852 if s.LastModified != nil {
1853 s.LastModified.encode(w)
1854 }
1855
1856 if s.Organizer != nil {
1857 s.Organizer.encode(w)
1858 }
1859
1860 if s.RecurrenceID != nil {
1861 s.RecurrenceID.encode(w)
1862 }
1863
1864 if s.Sequence != nil {
1865 s.Sequence.encode(w)
1866 }
1867
1868 if s.Status != nil {
1869 s.Status.encode(w)
1870 }
1871
1872 if s.Summary != nil {
1873 s.Summary.encode(w)
1874 }
1875
1876 if s.URL != nil {
1877 s.URL.encode(w)
1878 }
1879
1880 if s.RecurrenceRule != nil {
1881 s.RecurrenceRule.encode(w)
1882 }
1883
1884 for n := range s.Attachment {
1885 s.Attachment[n].encode(w)
1886 }
1887
1888 for n := range s.Attendee {
1889 s.Attendee[n].encode(w)
1890 }
1891
1892 for n := range s.Categories {
1893 s.Categories[n].encode(w)
1894 }
1895
1896 for n := range s.Comment {
1897 s.Comment[n].encode(w)
1898 }
1899
1900 for n := range s.Contact {
1901 s.Contact[n].encode(w)
1902 }
1903
1904 for n := range s.Description {
1905 s.Description[n].encode(w)
1906 }
1907
1908 for n := range s.ExceptionDateTime {
1909 s.ExceptionDateTime[n].encode(w)
1910 }
1911
1912 for n := range s.RequestStatus {
1913 s.RequestStatus[n].encode(w)
1914 }
1915
1916 for n := range s.RelatedTo {
1917 s.RelatedTo[n].encode(w)
1918 }
1919
1920 for n := range s.Resources {
1921 s.Resources[n].encode(w)
1922 }
1923
1924 for n := range s.RecurrenceDateTimes {
1925 s.RecurrenceDateTimes[n].encode(w)
1926 }
1927
1928 w.WriteString("END:VJOURNAL\r\n")
1929 }
1930
1931 func (s *Journal) valid() error {
1932 if err := s.DateTimeStamp.valid(); err != nil {
1933 return fmt.Errorf(errValidatingProp, cJournal, cDateTimeStamp, err)
1934 }
1935
1936 if err := s.UID.valid(); err != nil {
1937 return fmt.Errorf(errValidatingProp, cJournal, cUID, err)
1938 }
1939
1940 if s.Class != nil {
1941 if err := s.Class.valid(); err != nil {
1942 return fmt.Errorf(errValidatingProp, cJournal, cClass, err)
1943 }
1944 }
1945
1946 if s.Created != nil {
1947 if err := s.Created.valid(); err != nil {
1948 return fmt.Errorf(errValidatingProp, cJournal, cCreated, err)
1949 }
1950 }
1951
1952 if s.DateTimeStart != nil {
1953 if err := s.DateTimeStart.valid(); err != nil {
1954 return fmt.Errorf(errValidatingProp, cJournal, cDateTimeStart, err)
1955 }
1956 }
1957
1958 if s.LastModified != nil {
1959 if err := s.LastModified.valid(); err != nil {
1960 return fmt.Errorf(errValidatingProp, cJournal, cLastModified, err)
1961 }
1962 }
1963
1964 if s.Organizer != nil {
1965 if err := s.Organizer.valid(); err != nil {
1966 return fmt.Errorf(errValidatingProp, cJournal, cOrganizer, err)
1967 }
1968 }
1969
1970 if s.RecurrenceID != nil {
1971 if err := s.RecurrenceID.valid(); err != nil {
1972 return fmt.Errorf(errValidatingProp, cJournal, cRecurrenceID, err)
1973 }
1974 }
1975
1976 if s.Sequence != nil {
1977 if err := s.Sequence.valid(); err != nil {
1978 return fmt.Errorf(errValidatingProp, cJournal, cSequence, err)
1979 }
1980 }
1981
1982 if s.Status != nil {
1983 if err := s.Status.valid(); err != nil {
1984 return fmt.Errorf(errValidatingProp, cJournal, cStatus, err)
1985 }
1986 }
1987
1988 if s.Summary != nil {
1989 if err := s.Summary.valid(); err != nil {
1990 return fmt.Errorf(errValidatingProp, cJournal, cSummary, err)
1991 }
1992 }
1993
1994 if s.URL != nil {
1995 if err := s.URL.valid(); err != nil {
1996 return fmt.Errorf(errValidatingProp, cJournal, cURL, err)
1997 }
1998 }
1999
2000 if s.RecurrenceRule != nil {
2001 if err := s.RecurrenceRule.valid(); err != nil {
2002 return fmt.Errorf(errValidatingProp, cJournal, cRecurrenceRule, err)
2003 }
2004 }
2005
2006 for n := range s.Attachment {
2007 if err := s.Attachment[n].valid(); err != nil {
2008 return fmt.Errorf(errValidatingProp, cJournal, cAttachment, err)
2009 }
2010 }
2011
2012 for n := range s.Attendee {
2013 if err := s.Attendee[n].valid(); err != nil {
2014 return fmt.Errorf(errValidatingProp, cJournal, cAttendee, err)
2015 }
2016 }
2017
2018 for n := range s.Categories {
2019 if err := s.Categories[n].valid(); err != nil {
2020 return fmt.Errorf(errValidatingProp, cJournal, cCategories, err)
2021 }
2022 }
2023
2024 for n := range s.Comment {
2025 if err := s.Comment[n].valid(); err != nil {
2026 return fmt.Errorf(errValidatingProp, cJournal, cComment, err)
2027 }
2028 }
2029
2030 for n := range s.Contact {
2031 if err := s.Contact[n].valid(); err != nil {
2032 return fmt.Errorf(errValidatingProp, cJournal, cContact, err)
2033 }
2034 }
2035
2036 for n := range s.Description {
2037 if err := s.Description[n].valid(); err != nil {
2038 return fmt.Errorf(errValidatingProp, cJournal, cDescription, err)
2039 }
2040 }
2041
2042 for n := range s.ExceptionDateTime {
2043 if err := s.ExceptionDateTime[n].valid(); err != nil {
2044 return fmt.Errorf(errValidatingProp, cJournal, cExceptionDateTime, err)
2045 }
2046 }
2047
2048 for n := range s.RequestStatus {
2049 if err := s.RequestStatus[n].valid(); err != nil {
2050 return fmt.Errorf(errValidatingProp, cJournal, cRequestStatus, err)
2051 }
2052 }
2053
2054 for n := range s.RelatedTo {
2055 if err := s.RelatedTo[n].valid(); err != nil {
2056 return fmt.Errorf(errValidatingProp, cJournal, cRelatedTo, err)
2057 }
2058 }
2059
2060 for n := range s.Resources {
2061 if err := s.Resources[n].valid(); err != nil {
2062 return fmt.Errorf(errValidatingProp, cJournal, cResources, err)
2063 }
2064 }
2065
2066 for n := range s.RecurrenceDateTimes {
2067 if err := s.RecurrenceDateTimes[n].valid(); err != nil {
2068 return fmt.Errorf(errValidatingProp, cJournal, cRecurrenceDateTimes, err)
2069 }
2070 }
2071
2072 return nil
2073 }
2074
2075 // FreeBusy provides a group of components that describe either a request for
2076 // free/busy time, describe a response to a request for free/busy time, or
2077 // describe a published set of busy time.
2078 type FreeBusy struct {
2079 DateTimeStamp PropDateTimeStamp
2080 UID PropUID
2081 Contact *PropContact
2082 DateTimeStart *PropDateTimeStart
2083 DateTimeEnd *PropDateTimeEnd
2084 Organizer *PropOrganizer
2085 URL *PropURL
2086 Attendee []PropAttendee
2087 Comment []PropComment
2088 FreeBusy []PropFreeBusy
2089 RequestStatus []PropRequestStatus
2090 }
2091
2092 func (s *FreeBusy) decode(t tokeniser) error {
2093 var requiredDateTimeStamp, requiredUID bool
2094
2095 Loop:
2096 for {
2097 p, err := t.GetPhrase()
2098 if err != nil {
2099 return fmt.Errorf(errDecodingType, cFreeBusy, err)
2100 } else if p.Type == parser.PhraseDone {
2101 return fmt.Errorf(errDecodingType, cFreeBusy, io.ErrUnexpectedEOF)
2102 }
2103
2104 params := p.Data[1 : len(p.Data)-1]
2105 value := p.Data[len(p.Data)-1].Data
2106
2107 switch strings.ToUpper(p.Data[0].Data) {
2108 case "BEGIN":
2109 switch n := strings.ToUpper(value); n {
2110 default:
2111 if err := decodeDummy(t, n); err != nil {
2112 return fmt.Errorf(errDecodingType, cFreeBusy, err)
2113 }
2114 }
2115 case "DTSTAMP":
2116 if requiredDateTimeStamp {
2117 return fmt.Errorf(errMultiple, cFreeBusy, cDateTimeStamp)
2118 }
2119
2120 requiredDateTimeStamp = true
2121
2122 if err := s.DateTimeStamp.decode(params, value); err != nil {
2123 return fmt.Errorf(errDecodingProp, cFreeBusy, cDateTimeStamp, err)
2124 }
2125 case "UID":
2126 if requiredUID {
2127 return fmt.Errorf(errMultiple, cFreeBusy, cUID)
2128 }
2129
2130 requiredUID = true
2131
2132 if err := s.UID.decode(params, value); err != nil {
2133 return fmt.Errorf(errDecodingProp, cFreeBusy, cUID, err)
2134 }
2135 case "CONTACT":
2136 if s.Contact != nil {
2137 return fmt.Errorf(errMultiple, cFreeBusy, cContact)
2138 }
2139
2140 s.Contact = new(PropContact)
2141
2142 if err := s.Contact.decode(params, value); err != nil {
2143 return fmt.Errorf(errDecodingProp, cFreeBusy, cContact, err)
2144 }
2145 case "DTSTART":
2146 if s.DateTimeStart != nil {
2147 return fmt.Errorf(errMultiple, cFreeBusy, cDateTimeStart)
2148 }
2149
2150 s.DateTimeStart = new(PropDateTimeStart)
2151
2152 if err := s.DateTimeStart.decode(params, value); err != nil {
2153 return fmt.Errorf(errDecodingProp, cFreeBusy, cDateTimeStart, err)
2154 }
2155 case "DTEND":
2156 if s.DateTimeEnd != nil {
2157 return fmt.Errorf(errMultiple, cFreeBusy, cDateTimeEnd)
2158 }
2159
2160 s.DateTimeEnd = new(PropDateTimeEnd)
2161
2162 if err := s.DateTimeEnd.decode(params, value); err != nil {
2163 return fmt.Errorf(errDecodingProp, cFreeBusy, cDateTimeEnd, err)
2164 }
2165 case "ORGANIZER":
2166 if s.Organizer != nil {
2167 return fmt.Errorf(errMultiple, cFreeBusy, cOrganizer)
2168 }
2169
2170 s.Organizer = new(PropOrganizer)
2171
2172 if err := s.Organizer.decode(params, value); err != nil {
2173 return fmt.Errorf(errDecodingProp, cFreeBusy, cOrganizer, err)
2174 }
2175 case "URL":
2176 if s.URL != nil {
2177 return fmt.Errorf(errMultiple, cFreeBusy, cURL)
2178 }
2179
2180 s.URL = new(PropURL)
2181
2182 if err := s.URL.decode(params, value); err != nil {
2183 return fmt.Errorf(errDecodingProp, cFreeBusy, cURL, err)
2184 }
2185 case "ATTENDEE":
2186 var e PropAttendee
2187
2188 if err := e.decode(params, value); err != nil {
2189 return fmt.Errorf(errDecodingProp, cFreeBusy, cAttendee, err)
2190 }
2191
2192 s.Attendee = append(s.Attendee, e)
2193 case "COMMENT":
2194 var e PropComment
2195
2196 if err := e.decode(params, value); err != nil {
2197 return fmt.Errorf(errDecodingProp, cFreeBusy, cComment, err)
2198 }
2199
2200 s.Comment = append(s.Comment, e)
2201 case "FREEBUSY":
2202 var e PropFreeBusy
2203
2204 if err := e.decode(params, value); err != nil {
2205 return fmt.Errorf(errDecodingProp, cFreeBusy, cFreeBusy, err)
2206 }
2207
2208 s.FreeBusy = append(s.FreeBusy, e)
2209 case "REQUEST-STATUS":
2210 var e PropRequestStatus
2211
2212 if err := e.decode(params, value); err != nil {
2213 return fmt.Errorf(errDecodingProp, cFreeBusy, cRequestStatus, err)
2214 }
2215
2216 s.RequestStatus = append(s.RequestStatus, e)
2217 case "END":
2218 if value != "VFREEBUSY" {
2219 return fmt.Errorf(errDecodingType, cFreeBusy, ErrInvalidEnd)
2220 }
2221
2222 break Loop
2223 }
2224 }
2225
2226 if !requiredDateTimeStamp || !requiredUID {
2227 return fmt.Errorf(errDecodingType, cFreeBusy, ErrMissingRequired)
2228 }
2229
2230 return nil
2231 }
2232
2233 func (s *FreeBusy) encode(w writer) {
2234 w.WriteString("BEGIN:VFREEBUSY\r\n")
2235 s.DateTimeStamp.encode(w)
2236 s.UID.encode(w)
2237
2238 if s.Contact != nil {
2239 s.Contact.encode(w)
2240 }
2241
2242 if s.DateTimeStart != nil {
2243 s.DateTimeStart.encode(w)
2244 }
2245
2246 if s.DateTimeEnd != nil {
2247 s.DateTimeEnd.encode(w)
2248 }
2249
2250 if s.Organizer != nil {
2251 s.Organizer.encode(w)
2252 }
2253
2254 if s.URL != nil {
2255 s.URL.encode(w)
2256 }
2257
2258 for n := range s.Attendee {
2259 s.Attendee[n].encode(w)
2260 }
2261
2262 for n := range s.Comment {
2263 s.Comment[n].encode(w)
2264 }
2265
2266 for n := range s.FreeBusy {
2267 s.FreeBusy[n].encode(w)
2268 }
2269
2270 for n := range s.RequestStatus {
2271 s.RequestStatus[n].encode(w)
2272 }
2273
2274 w.WriteString("END:VFREEBUSY\r\n")
2275 }
2276
2277 func (s *FreeBusy) valid() error {
2278 if err := s.DateTimeStamp.valid(); err != nil {
2279 return fmt.Errorf(errValidatingProp, cFreeBusy, cDateTimeStamp, err)
2280 }
2281
2282 if err := s.UID.valid(); err != nil {
2283 return fmt.Errorf(errValidatingProp, cFreeBusy, cUID, err)
2284 }
2285
2286 if s.Contact != nil {
2287 if err := s.Contact.valid(); err != nil {
2288 return fmt.Errorf(errValidatingProp, cFreeBusy, cContact, err)
2289 }
2290 }
2291
2292 if s.DateTimeStart != nil {
2293 if err := s.DateTimeStart.valid(); err != nil {
2294 return fmt.Errorf(errValidatingProp, cFreeBusy, cDateTimeStart, err)
2295 }
2296 }
2297
2298 if s.DateTimeEnd != nil {
2299 if err := s.DateTimeEnd.valid(); err != nil {
2300 return fmt.Errorf(errValidatingProp, cFreeBusy, cDateTimeEnd, err)
2301 }
2302 }
2303
2304 if s.Organizer != nil {
2305 if err := s.Organizer.valid(); err != nil {
2306 return fmt.Errorf(errValidatingProp, cFreeBusy, cOrganizer, err)
2307 }
2308 }
2309
2310 if s.URL != nil {
2311 if err := s.URL.valid(); err != nil {
2312 return fmt.Errorf(errValidatingProp, cFreeBusy, cURL, err)
2313 }
2314 }
2315
2316 for n := range s.Attendee {
2317 if err := s.Attendee[n].valid(); err != nil {
2318 return fmt.Errorf(errValidatingProp, cFreeBusy, cAttendee, err)
2319 }
2320 }
2321
2322 for n := range s.Comment {
2323 if err := s.Comment[n].valid(); err != nil {
2324 return fmt.Errorf(errValidatingProp, cFreeBusy, cComment, err)
2325 }
2326 }
2327
2328 for n := range s.FreeBusy {
2329 if err := s.FreeBusy[n].valid(); err != nil {
2330 return fmt.Errorf(errValidatingProp, cFreeBusy, cFreeBusy, err)
2331 }
2332 }
2333
2334 for n := range s.RequestStatus {
2335 if err := s.RequestStatus[n].valid(); err != nil {
2336 return fmt.Errorf(errValidatingProp, cFreeBusy, cRequestStatus, err)
2337 }
2338 }
2339
2340 return nil
2341 }
2342
2343 // Timezone provide a group of components that defines a time zone.
2344 type Timezone struct {
2345 TimezoneID PropTimezoneID
2346 LastModified *PropLastModified
2347 TimezoneURL *PropTimezoneURL
2348 Standard []Standard
2349 Daylight []Daylight
2350 }
2351
2352 func (s *Timezone) decode(t tokeniser) error {
2353 var requiredTimezoneID bool
2354
2355 Loop:
2356 for {
2357 p, err := t.GetPhrase()
2358 if err != nil {
2359 return fmt.Errorf(errDecodingType, cTimezone, err)
2360 } else if p.Type == parser.PhraseDone {
2361 return fmt.Errorf(errDecodingType, cTimezone, io.ErrUnexpectedEOF)
2362 }
2363
2364 params := p.Data[1 : len(p.Data)-1]
2365 value := p.Data[len(p.Data)-1].Data
2366
2367 switch strings.ToUpper(p.Data[0].Data) {
2368 case "BEGIN":
2369 switch n := strings.ToUpper(value); n {
2370 case "STANDARD":
2371 var e Standard
2372
2373 if err := e.decode(t); err != nil {
2374 return fmt.Errorf(errDecodingProp, cTimezone, cStandard, err)
2375 }
2376
2377 s.Standard = append(s.Standard, e)
2378 case "DAYLIGHT":
2379 var e Daylight
2380
2381 if err := e.decode(t); err != nil {
2382 return fmt.Errorf(errDecodingProp, cTimezone, cDaylight, err)
2383 }
2384
2385 s.Daylight = append(s.Daylight, e)
2386 default:
2387 if err := decodeDummy(t, n); err != nil {
2388 return fmt.Errorf(errDecodingType, cTimezone, err)
2389 }
2390 }
2391 case "TZID":
2392 if requiredTimezoneID {
2393 return fmt.Errorf(errMultiple, cTimezone, cTimezoneID)
2394 }
2395
2396 requiredTimezoneID = true
2397
2398 if err := s.TimezoneID.decode(params, value); err != nil {
2399 return fmt.Errorf(errDecodingProp, cTimezone, cTimezoneID, err)
2400 }
2401 case "LAST-MOD":
2402 if s.LastModified != nil {
2403 return fmt.Errorf(errMultiple, cTimezone, cLastModified)
2404 }
2405
2406 s.LastModified = new(PropLastModified)
2407
2408 if err := s.LastModified.decode(params, value); err != nil {
2409 return fmt.Errorf(errDecodingProp, cTimezone, cLastModified, err)
2410 }
2411 case "TZURL":
2412 if s.TimezoneURL != nil {
2413 return fmt.Errorf(errMultiple, cTimezone, cTimezoneURL)
2414 }
2415
2416 s.TimezoneURL = new(PropTimezoneURL)
2417
2418 if err := s.TimezoneURL.decode(params, value); err != nil {
2419 return fmt.Errorf(errDecodingProp, cTimezone, cTimezoneURL, err)
2420 }
2421 case "END":
2422 if value != "VTIMEZONE" {
2423 return fmt.Errorf(errDecodingType, cTimezone, ErrInvalidEnd)
2424 }
2425
2426 break Loop
2427 }
2428 }
2429
2430 if !requiredTimezoneID {
2431 return fmt.Errorf(errDecodingType, cTimezone, ErrMissingRequired)
2432 }
2433
2434 if s.Standard == nil && s.Daylight == nil {
2435 return fmt.Errorf(errDecodingType, cTimezone, ErrRequirementNotMet)
2436 }
2437
2438 return nil
2439 }
2440
2441 func (s *Timezone) encode(w writer) {
2442 w.WriteString("BEGIN:VTIMEZONE\r\n")
2443 s.TimezoneID.encode(w)
2444
2445 if s.LastModified != nil {
2446 s.LastModified.encode(w)
2447 }
2448
2449 if s.TimezoneURL != nil {
2450 s.TimezoneURL.encode(w)
2451 }
2452
2453 for n := range s.Standard {
2454 s.Standard[n].encode(w)
2455 }
2456
2457 for n := range s.Daylight {
2458 s.Daylight[n].encode(w)
2459 }
2460
2461 w.WriteString("END:VTIMEZONE\r\n")
2462 }
2463
2464 func (s *Timezone) valid() error {
2465 if err := s.TimezoneID.valid(); err != nil {
2466 return fmt.Errorf(errValidatingProp, cTimezone, cTimezoneID, err)
2467 }
2468
2469 if s.LastModified != nil {
2470 if err := s.LastModified.valid(); err != nil {
2471 return fmt.Errorf(errValidatingProp, cTimezone, cLastModified, err)
2472 }
2473 }
2474
2475 if s.TimezoneURL != nil {
2476 if err := s.TimezoneURL.valid(); err != nil {
2477 return fmt.Errorf(errValidatingProp, cTimezone, cTimezoneURL, err)
2478 }
2479 }
2480
2481 for n := range s.Standard {
2482 if err := s.Standard[n].valid(); err != nil {
2483 return fmt.Errorf(errValidatingProp, cTimezone, cStandard, err)
2484 }
2485 }
2486
2487 for n := range s.Daylight {
2488 if err := s.Daylight[n].valid(); err != nil {
2489 return fmt.Errorf(errValidatingProp, cTimezone, cDaylight, err)
2490 }
2491 }
2492
2493 return nil
2494 }
2495
2496 // Standard represents standard timezone rules.
2497 type Standard struct {
2498 DateTimeStart PropDateTimeStart
2499 TimezoneOffsetTo PropTimezoneOffsetTo
2500 TimezoneOffsetFrom PropTimezoneOffsetFrom
2501 RecurrenceRule *PropRecurrenceRule
2502 Comment []PropComment
2503 RecurrenceDateTimes []PropRecurrenceDateTimes
2504 TimezoneName []PropTimezoneName
2505 }
2506
2507 func (s *Standard) decode(t tokeniser) error {
2508 var requiredDateTimeStart, requiredTimezoneOffsetTo, requiredTimezoneOffsetFrom bool
2509
2510 Loop:
2511 for {
2512 p, err := t.GetPhrase()
2513 if err != nil {
2514 return fmt.Errorf(errDecodingType, cStandard, err)
2515 } else if p.Type == parser.PhraseDone {
2516 return fmt.Errorf(errDecodingType, cStandard, io.ErrUnexpectedEOF)
2517 }
2518
2519 params := p.Data[1 : len(p.Data)-1]
2520 value := p.Data[len(p.Data)-1].Data
2521
2522 switch strings.ToUpper(p.Data[0].Data) {
2523 case "BEGIN":
2524 switch n := strings.ToUpper(value); n {
2525 default:
2526 if err := decodeDummy(t, n); err != nil {
2527 return fmt.Errorf(errDecodingType, cStandard, err)
2528 }
2529 }
2530 case "DTSTART":
2531 if requiredDateTimeStart {
2532 return fmt.Errorf(errMultiple, cStandard, cDateTimeStart)
2533 }
2534
2535 requiredDateTimeStart = true
2536
2537 if err := s.DateTimeStart.decode(params, value); err != nil {
2538 return fmt.Errorf(errDecodingProp, cStandard, cDateTimeStart, err)
2539 }
2540 case "TZOFFSETTO":
2541 if requiredTimezoneOffsetTo {
2542 return fmt.Errorf(errMultiple, cStandard, cTimezoneOffsetTo)
2543 }
2544
2545 requiredTimezoneOffsetTo = true
2546
2547 if err := s.TimezoneOffsetTo.decode(params, value); err != nil {
2548 return fmt.Errorf(errDecodingProp, cStandard, cTimezoneOffsetTo, err)
2549 }
2550 case "TZOFFSETFROM":
2551 if requiredTimezoneOffsetFrom {
2552 return fmt.Errorf(errMultiple, cStandard, cTimezoneOffsetFrom)
2553 }
2554
2555 requiredTimezoneOffsetFrom = true
2556
2557 if err := s.TimezoneOffsetFrom.decode(params, value); err != nil {
2558 return fmt.Errorf(errDecodingProp, cStandard, cTimezoneOffsetFrom, err)
2559 }
2560 case "RRULE":
2561 if s.RecurrenceRule != nil {
2562 return fmt.Errorf(errMultiple, cStandard, cRecurrenceRule)
2563 }
2564
2565 s.RecurrenceRule = new(PropRecurrenceRule)
2566
2567 if err := s.RecurrenceRule.decode(params, value); err != nil {
2568 return fmt.Errorf(errDecodingProp, cStandard, cRecurrenceRule, err)
2569 }
2570 case "COMMENT":
2571 var e PropComment
2572
2573 if err := e.decode(params, value); err != nil {
2574 return fmt.Errorf(errDecodingProp, cStandard, cComment, err)
2575 }
2576
2577 s.Comment = append(s.Comment, e)
2578 case "RDATE":
2579 var e PropRecurrenceDateTimes
2580
2581 if err := e.decode(params, value); err != nil {
2582 return fmt.Errorf(errDecodingProp, cStandard, cRecurrenceDateTimes, err)
2583 }
2584
2585 s.RecurrenceDateTimes = append(s.RecurrenceDateTimes, e)
2586 case "TZNAME":
2587 var e PropTimezoneName
2588
2589 if err := e.decode(params, value); err != nil {
2590 return fmt.Errorf(errDecodingProp, cStandard, cTimezoneName, err)
2591 }
2592
2593 s.TimezoneName = append(s.TimezoneName, e)
2594 case "END":
2595 if value != "STANDARD" {
2596 return fmt.Errorf(errDecodingType, cStandard, ErrInvalidEnd)
2597 }
2598
2599 break Loop
2600 }
2601 }
2602
2603 if !requiredDateTimeStart || !requiredTimezoneOffsetTo || !requiredTimezoneOffsetFrom {
2604 return fmt.Errorf(errDecodingType, cStandard, ErrMissingRequired)
2605 }
2606
2607 return nil
2608 }
2609
2610 func (s *Standard) encode(w writer) {
2611 w.WriteString("BEGIN:STANDARD\r\n")
2612 s.DateTimeStart.encode(w)
2613 s.TimezoneOffsetTo.encode(w)
2614 s.TimezoneOffsetFrom.encode(w)
2615
2616 if s.RecurrenceRule != nil {
2617 s.RecurrenceRule.encode(w)
2618 }
2619
2620 for n := range s.Comment {
2621 s.Comment[n].encode(w)
2622 }
2623
2624 for n := range s.RecurrenceDateTimes {
2625 s.RecurrenceDateTimes[n].encode(w)
2626 }
2627
2628 for n := range s.TimezoneName {
2629 s.TimezoneName[n].encode(w)
2630 }
2631
2632 w.WriteString("END:STANDARD\r\n")
2633 }
2634
2635 func (s *Standard) valid() error {
2636 if err := s.DateTimeStart.valid(); err != nil {
2637 return fmt.Errorf(errValidatingProp, cStandard, cDateTimeStart, err)
2638 }
2639
2640 if err := s.TimezoneOffsetTo.valid(); err != nil {
2641 return fmt.Errorf(errValidatingProp, cStandard, cTimezoneOffsetTo, err)
2642 }
2643
2644 if err := s.TimezoneOffsetFrom.valid(); err != nil {
2645 return fmt.Errorf(errValidatingProp, cStandard, cTimezoneOffsetFrom, err)
2646 }
2647
2648 if s.RecurrenceRule != nil {
2649 if err := s.RecurrenceRule.valid(); err != nil {
2650 return fmt.Errorf(errValidatingProp, cStandard, cRecurrenceRule, err)
2651 }
2652 }
2653
2654 for n := range s.Comment {
2655 if err := s.Comment[n].valid(); err != nil {
2656 return fmt.Errorf(errValidatingProp, cStandard, cComment, err)
2657 }
2658 }
2659
2660 for n := range s.RecurrenceDateTimes {
2661 if err := s.RecurrenceDateTimes[n].valid(); err != nil {
2662 return fmt.Errorf(errValidatingProp, cStandard, cRecurrenceDateTimes, err)
2663 }
2664 }
2665
2666 for n := range s.TimezoneName {
2667 if err := s.TimezoneName[n].valid(); err != nil {
2668 return fmt.Errorf(errValidatingProp, cStandard, cTimezoneName, err)
2669 }
2670 }
2671
2672 return nil
2673 }
2674
2675 // Daylight represents daylight savings timezone rules.
2676 type Daylight struct {
2677 DateTimeStart PropDateTimeStart
2678 TimezoneOffsetTo PropTimezoneOffsetTo
2679 TimezoneOffsetFrom PropTimezoneOffsetFrom
2680 RecurrenceRule *PropRecurrenceRule
2681 Comment []PropComment
2682 RecurrenceDateTimes []PropRecurrenceDateTimes
2683 TimezoneName []PropTimezoneName
2684 }
2685
2686 func (s *Daylight) decode(t tokeniser) error {
2687 var requiredDateTimeStart, requiredTimezoneOffsetTo, requiredTimezoneOffsetFrom bool
2688
2689 Loop:
2690 for {
2691 p, err := t.GetPhrase()
2692 if err != nil {
2693 return fmt.Errorf(errDecodingType, cDaylight, err)
2694 } else if p.Type == parser.PhraseDone {
2695 return fmt.Errorf(errDecodingType, cDaylight, io.ErrUnexpectedEOF)
2696 }
2697
2698 params := p.Data[1 : len(p.Data)-1]
2699 value := p.Data[len(p.Data)-1].Data
2700
2701 switch strings.ToUpper(p.Data[0].Data) {
2702 case "BEGIN":
2703 switch n := strings.ToUpper(value); n {
2704 default:
2705 if err := decodeDummy(t, n); err != nil {
2706 return fmt.Errorf(errDecodingType, cDaylight, err)
2707 }
2708 }
2709 case "DTSTART":
2710 if requiredDateTimeStart {
2711 return fmt.Errorf(errMultiple, cDaylight, cDateTimeStart)
2712 }
2713
2714 requiredDateTimeStart = true
2715
2716 if err := s.DateTimeStart.decode(params, value); err != nil {
2717 return fmt.Errorf(errDecodingProp, cDaylight, cDateTimeStart, err)
2718 }
2719 case "TZOFFSETTO":
2720 if requiredTimezoneOffsetTo {
2721 return fmt.Errorf(errMultiple, cDaylight, cTimezoneOffsetTo)
2722 }
2723
2724 requiredTimezoneOffsetTo = true
2725
2726 if err := s.TimezoneOffsetTo.decode(params, value); err != nil {
2727 return fmt.Errorf(errDecodingProp, cDaylight, cTimezoneOffsetTo, err)
2728 }
2729 case "TZOFFSETFROM":
2730 if requiredTimezoneOffsetFrom {
2731 return fmt.Errorf(errMultiple, cDaylight, cTimezoneOffsetFrom)
2732 }
2733
2734 requiredTimezoneOffsetFrom = true
2735
2736 if err := s.TimezoneOffsetFrom.decode(params, value); err != nil {
2737 return fmt.Errorf(errDecodingProp, cDaylight, cTimezoneOffsetFrom, err)
2738 }
2739 case "RRULE":
2740 if s.RecurrenceRule != nil {
2741 return fmt.Errorf(errMultiple, cDaylight, cRecurrenceRule)
2742 }
2743
2744 s.RecurrenceRule = new(PropRecurrenceRule)
2745
2746 if err := s.RecurrenceRule.decode(params, value); err != nil {
2747 return fmt.Errorf(errDecodingProp, cDaylight, cRecurrenceRule, err)
2748 }
2749 case "COMMENT":
2750 var e PropComment
2751
2752 if err := e.decode(params, value); err != nil {
2753 return fmt.Errorf(errDecodingProp, cDaylight, cComment, err)
2754 }
2755
2756 s.Comment = append(s.Comment, e)
2757 case "RDATE":
2758 var e PropRecurrenceDateTimes
2759
2760 if err := e.decode(params, value); err != nil {
2761 return fmt.Errorf(errDecodingProp, cDaylight, cRecurrenceDateTimes, err)
2762 }
2763
2764 s.RecurrenceDateTimes = append(s.RecurrenceDateTimes, e)
2765 case "TZNAME":
2766 var e PropTimezoneName
2767
2768 if err := e.decode(params, value); err != nil {
2769 return fmt.Errorf(errDecodingProp, cDaylight, cTimezoneName, err)
2770 }
2771
2772 s.TimezoneName = append(s.TimezoneName, e)
2773 case "END":
2774 if value != "DAYLIGHT" {
2775 return fmt.Errorf(errDecodingType, cDaylight, ErrInvalidEnd)
2776 }
2777
2778 break Loop
2779 }
2780 }
2781
2782 if !requiredDateTimeStart || !requiredTimezoneOffsetTo || !requiredTimezoneOffsetFrom {
2783 return fmt.Errorf(errDecodingType, cDaylight, ErrMissingRequired)
2784 }
2785
2786 return nil
2787 }
2788
2789 func (s *Daylight) encode(w writer) {
2790 w.WriteString("BEGIN:DAYLIGHT\r\n")
2791 s.DateTimeStart.encode(w)
2792 s.TimezoneOffsetTo.encode(w)
2793 s.TimezoneOffsetFrom.encode(w)
2794
2795 if s.RecurrenceRule != nil {
2796 s.RecurrenceRule.encode(w)
2797 }
2798
2799 for n := range s.Comment {
2800 s.Comment[n].encode(w)
2801 }
2802
2803 for n := range s.RecurrenceDateTimes {
2804 s.RecurrenceDateTimes[n].encode(w)
2805 }
2806
2807 for n := range s.TimezoneName {
2808 s.TimezoneName[n].encode(w)
2809 }
2810
2811 w.WriteString("END:DAYLIGHT\r\n")
2812 }
2813
2814 func (s *Daylight) valid() error {
2815 if err := s.DateTimeStart.valid(); err != nil {
2816 return fmt.Errorf(errValidatingProp, cDaylight, cDateTimeStart, err)
2817 }
2818
2819 if err := s.TimezoneOffsetTo.valid(); err != nil {
2820 return fmt.Errorf(errValidatingProp, cDaylight, cTimezoneOffsetTo, err)
2821 }
2822
2823 if err := s.TimezoneOffsetFrom.valid(); err != nil {
2824 return fmt.Errorf(errValidatingProp, cDaylight, cTimezoneOffsetFrom, err)
2825 }
2826
2827 if s.RecurrenceRule != nil {
2828 if err := s.RecurrenceRule.valid(); err != nil {
2829 return fmt.Errorf(errValidatingProp, cDaylight, cRecurrenceRule, err)
2830 }
2831 }
2832
2833 for n := range s.Comment {
2834 if err := s.Comment[n].valid(); err != nil {
2835 return fmt.Errorf(errValidatingProp, cDaylight, cComment, err)
2836 }
2837 }
2838
2839 for n := range s.RecurrenceDateTimes {
2840 if err := s.RecurrenceDateTimes[n].valid(); err != nil {
2841 return fmt.Errorf(errValidatingProp, cDaylight, cRecurrenceDateTimes, err)
2842 }
2843 }
2844
2845 for n := range s.TimezoneName {
2846 if err := s.TimezoneName[n].valid(); err != nil {
2847 return fmt.Errorf(errValidatingProp, cDaylight, cTimezoneName, err)
2848 }
2849 }
2850
2851 return nil
2852 }
2853
2854 // AlarmAudio provides a group of components that define an Audio Alarm.
2855 type AlarmAudio struct {
2856 Trigger PropTrigger
2857 Duration *PropDuration
2858 Repeat *PropRepeat
2859 Attachment []PropAttachment
2860 UID *PropUID
2861 AlarmAgent []PropAlarmAgent
2862 AlarmStatus *PropAlarmStatus
2863 LastTriggered []PropLastTriggered
2864 Acknowledged *PropAcknowledged
2865 Proximity *PropProximity
2866 GeoLocation []PropGeoLocation
2867 RelatedTo *PropRelatedTo
2868 DefaultAlarm *PropDefaultAlarm
2869 }
2870
2871 func (s *AlarmAudio) decode(t tokeniser) error {
2872 var requiredTrigger bool
2873
2874 Loop:
2875 for {
2876 p, err := t.GetPhrase()
2877 if err != nil {
2878 return fmt.Errorf(errDecodingType, cAlarmAudio, err)
2879 } else if p.Type == parser.PhraseDone {
2880 return fmt.Errorf(errDecodingType, cAlarmAudio, io.ErrUnexpectedEOF)
2881 }
2882
2883 params := p.Data[1 : len(p.Data)-1]
2884 value := p.Data[len(p.Data)-1].Data
2885
2886 switch strings.ToUpper(p.Data[0].Data) {
2887 case "BEGIN":
2888 switch n := strings.ToUpper(value); n {
2889 default:
2890 if err := decodeDummy(t, n); err != nil {
2891 return fmt.Errorf(errDecodingType, cAlarmAudio, err)
2892 }
2893 }
2894 case "TRIGGER":
2895 if requiredTrigger {
2896 return fmt.Errorf(errMultiple, cAlarmAudio, cTrigger)
2897 }
2898
2899 requiredTrigger = true
2900
2901 if err := s.Trigger.decode(params, value); err != nil {
2902 return fmt.Errorf(errDecodingProp, cAlarmAudio, cTrigger, err)
2903 }
2904 case "DURATION":
2905 if s.Duration != nil {
2906 return fmt.Errorf(errMultiple, cAlarmAudio, cDuration)
2907 }
2908
2909 s.Duration = new(PropDuration)
2910
2911 if err := s.Duration.decode(params, value); err != nil {
2912 return fmt.Errorf(errDecodingProp, cAlarmAudio, cDuration, err)
2913 }
2914 case "REPEAT":
2915 if s.Repeat != nil {
2916 return fmt.Errorf(errMultiple, cAlarmAudio, cRepeat)
2917 }
2918
2919 s.Repeat = new(PropRepeat)
2920
2921 if err := s.Repeat.decode(params, value); err != nil {
2922 return fmt.Errorf(errDecodingProp, cAlarmAudio, cRepeat, err)
2923 }
2924 case "ATTACH":
2925 var e PropAttachment
2926
2927 if err := e.decode(params, value); err != nil {
2928 return fmt.Errorf(errDecodingProp, cAlarmAudio, cAttachment, err)
2929 }
2930
2931 s.Attachment = append(s.Attachment, e)
2932 case "UID":
2933 if s.UID != nil {
2934 return fmt.Errorf(errMultiple, cAlarmAudio, cUID)
2935 }
2936
2937 s.UID = new(PropUID)
2938
2939 if err := s.UID.decode(params, value); err != nil {
2940 return fmt.Errorf(errDecodingProp, cAlarmAudio, cUID, err)
2941 }
2942 case "ALARM-AGENT":
2943 var e PropAlarmAgent
2944
2945 if err := e.decode(params, value); err != nil {
2946 return fmt.Errorf(errDecodingProp, cAlarmAudio, cAlarmAgent, err)
2947 }
2948
2949 s.AlarmAgent = append(s.AlarmAgent, e)
2950 case "STATUS":
2951 if s.AlarmStatus != nil {
2952 return fmt.Errorf(errMultiple, cAlarmAudio, cAlarmStatus)
2953 }
2954
2955 s.AlarmStatus = new(PropAlarmStatus)
2956
2957 if err := s.AlarmStatus.decode(params, value); err != nil {
2958 return fmt.Errorf(errDecodingProp, cAlarmAudio, cAlarmStatus, err)
2959 }
2960 case "LAST-TRIGGERED":
2961 var e PropLastTriggered
2962
2963 if err := e.decode(params, value); err != nil {
2964 return fmt.Errorf(errDecodingProp, cAlarmAudio, cLastTriggered, err)
2965 }
2966
2967 s.LastTriggered = append(s.LastTriggered, e)
2968 case "ACKNOWLEDGED":
2969 if s.Acknowledged != nil {
2970 return fmt.Errorf(errMultiple, cAlarmAudio, cAcknowledged)
2971 }
2972
2973 s.Acknowledged = new(PropAcknowledged)
2974
2975 if err := s.Acknowledged.decode(params, value); err != nil {
2976 return fmt.Errorf(errDecodingProp, cAlarmAudio, cAcknowledged, err)
2977 }
2978 case "PROXIMITY":
2979 if s.Proximity != nil {
2980 return fmt.Errorf(errMultiple, cAlarmAudio, cProximity)
2981 }
2982
2983 s.Proximity = new(PropProximity)
2984
2985 if err := s.Proximity.decode(params, value); err != nil {
2986 return fmt.Errorf(errDecodingProp, cAlarmAudio, cProximity, err)
2987 }
2988 case "GEO-LOCATION":
2989 var e PropGeoLocation
2990
2991 if err := e.decode(params, value); err != nil {
2992 return fmt.Errorf(errDecodingProp, cAlarmAudio, cGeoLocation, err)
2993 }
2994
2995 s.GeoLocation = append(s.GeoLocation, e)
2996 case "RELATED-TO":
2997 if s.RelatedTo != nil {
2998 return fmt.Errorf(errMultiple, cAlarmAudio, cRelatedTo)
2999 }
3000
3001 s.RelatedTo = new(PropRelatedTo)
3002
3003 if err := s.RelatedTo.decode(params, value); err != nil {
3004 return fmt.Errorf(errDecodingProp, cAlarmAudio, cRelatedTo, err)
3005 }
3006 case "DEFAULT-ALARM":
3007 if s.DefaultAlarm != nil {
3008 return fmt.Errorf(errMultiple, cAlarmAudio, cDefaultAlarm)
3009 }
3010
3011 s.DefaultAlarm = new(PropDefaultAlarm)
3012
3013 if err := s.DefaultAlarm.decode(params, value); err != nil {
3014 return fmt.Errorf(errDecodingProp, cAlarmAudio, cDefaultAlarm, err)
3015 }
3016 case "END":
3017 if value != "VALARM" {
3018 return fmt.Errorf(errDecodingType, cAlarmAudio, ErrInvalidEnd)
3019 }
3020
3021 break Loop
3022 }
3023 }
3024
3025 if !requiredTrigger {
3026 return fmt.Errorf(errDecodingType, cAlarmAudio, ErrMissingRequired)
3027 }
3028
3029 if s.GeoLocation != nil && (s.Proximity == nil) {
3030 return fmt.Errorf(errDecodingType, cAlarmAudio, ErrRequirementNotMet)
3031 }
3032
3033 return nil
3034 }
3035
3036 func (s *AlarmAudio) encode(w writer) {
3037 s.Trigger.encode(w)
3038
3039 if s.Duration != nil {
3040 s.Duration.encode(w)
3041 }
3042
3043 if s.Repeat != nil {
3044 s.Repeat.encode(w)
3045 }
3046
3047 for n := range s.Attachment {
3048 s.Attachment[n].encode(w)
3049 }
3050
3051 if s.UID != nil {
3052 s.UID.encode(w)
3053 }
3054
3055 for n := range s.AlarmAgent {
3056 s.AlarmAgent[n].encode(w)
3057 }
3058
3059 if s.AlarmStatus != nil {
3060 s.AlarmStatus.encode(w)
3061 }
3062
3063 for n := range s.LastTriggered {
3064 s.LastTriggered[n].encode(w)
3065 }
3066
3067 if s.Acknowledged != nil {
3068 s.Acknowledged.encode(w)
3069 }
3070
3071 if s.Proximity != nil {
3072 s.Proximity.encode(w)
3073 }
3074
3075 for n := range s.GeoLocation {
3076 s.GeoLocation[n].encode(w)
3077 }
3078
3079 if s.RelatedTo != nil {
3080 s.RelatedTo.encode(w)
3081 }
3082
3083 if s.DefaultAlarm != nil {
3084 s.DefaultAlarm.encode(w)
3085 }
3086
3087 }
3088
3089 func (s *AlarmAudio) valid() error {
3090 if err := s.Trigger.valid(); err != nil {
3091 return fmt.Errorf(errValidatingProp, cAlarmAudio, cTrigger, err)
3092 }
3093
3094 if s.Duration != nil {
3095 if err := s.Duration.valid(); err != nil {
3096 return fmt.Errorf(errValidatingProp, cAlarmAudio, cDuration, err)
3097 }
3098 }
3099
3100 if s.Repeat != nil {
3101 if err := s.Repeat.valid(); err != nil {
3102 return fmt.Errorf(errValidatingProp, cAlarmAudio, cRepeat, err)
3103 }
3104 }
3105
3106 for n := range s.Attachment {
3107 if err := s.Attachment[n].valid(); err != nil {
3108 return fmt.Errorf(errValidatingProp, cAlarmAudio, cAttachment, err)
3109 }
3110 }
3111
3112 if s.UID != nil {
3113 if err := s.UID.valid(); err != nil {
3114 return fmt.Errorf(errValidatingProp, cAlarmAudio, cUID, err)
3115 }
3116 }
3117
3118 for n := range s.AlarmAgent {
3119 if err := s.AlarmAgent[n].valid(); err != nil {
3120 return fmt.Errorf(errValidatingProp, cAlarmAudio, cAlarmAgent, err)
3121 }
3122 }
3123
3124 if s.AlarmStatus != nil {
3125 if err := s.AlarmStatus.valid(); err != nil {
3126 return fmt.Errorf(errValidatingProp, cAlarmAudio, cAlarmStatus, err)
3127 }
3128 }
3129
3130 for n := range s.LastTriggered {
3131 if err := s.LastTriggered[n].valid(); err != nil {
3132 return fmt.Errorf(errValidatingProp, cAlarmAudio, cLastTriggered, err)
3133 }
3134 }
3135
3136 if s.Acknowledged != nil {
3137 if err := s.Acknowledged.valid(); err != nil {
3138 return fmt.Errorf(errValidatingProp, cAlarmAudio, cAcknowledged, err)
3139 }
3140 }
3141
3142 if s.Proximity != nil {
3143 if err := s.Proximity.valid(); err != nil {
3144 return fmt.Errorf(errValidatingProp, cAlarmAudio, cProximity, err)
3145 }
3146 }
3147
3148 for n := range s.GeoLocation {
3149 if err := s.GeoLocation[n].valid(); err != nil {
3150 return fmt.Errorf(errValidatingProp, cAlarmAudio, cGeoLocation, err)
3151 }
3152 }
3153
3154 if s.RelatedTo != nil {
3155 if err := s.RelatedTo.valid(); err != nil {
3156 return fmt.Errorf(errValidatingProp, cAlarmAudio, cRelatedTo, err)
3157 }
3158 }
3159
3160 if s.DefaultAlarm != nil {
3161 if err := s.DefaultAlarm.valid(); err != nil {
3162 return fmt.Errorf(errValidatingProp, cAlarmAudio, cDefaultAlarm, err)
3163 }
3164 }
3165
3166 return nil
3167 }
3168
3169 // AlarmDisplay provides a group of components that define a Display Alarm.
3170 type AlarmDisplay struct {
3171 Description PropDescription
3172 Trigger PropTrigger
3173 Duration *PropDuration
3174 Repeat *PropRepeat
3175 UID *PropUID
3176 AlarmAgent []PropAlarmAgent
3177 AlarmStatus *PropAlarmStatus
3178 LastTriggered []PropLastTriggered
3179 Acknowledged *PropAcknowledged
3180 Proximity *PropProximity
3181 GeoLocation []PropGeoLocation
3182 RelatedTo *PropRelatedTo
3183 DefaultAlarm *PropDefaultAlarm
3184 }
3185
3186 func (s *AlarmDisplay) decode(t tokeniser) error {
3187 var requiredDescription, requiredTrigger bool
3188
3189 Loop:
3190 for {
3191 p, err := t.GetPhrase()
3192 if err != nil {
3193 return fmt.Errorf(errDecodingType, cAlarmDisplay, err)
3194 } else if p.Type == parser.PhraseDone {
3195 return fmt.Errorf(errDecodingType, cAlarmDisplay, io.ErrUnexpectedEOF)
3196 }
3197
3198 params := p.Data[1 : len(p.Data)-1]
3199 value := p.Data[len(p.Data)-1].Data
3200
3201 switch strings.ToUpper(p.Data[0].Data) {
3202 case "BEGIN":
3203 switch n := strings.ToUpper(value); n {
3204 default:
3205 if err := decodeDummy(t, n); err != nil {
3206 return fmt.Errorf(errDecodingType, cAlarmDisplay, err)
3207 }
3208 }
3209 case "DESCRIPTION":
3210 if requiredDescription {
3211 return fmt.Errorf(errMultiple, cAlarmDisplay, cDescription)
3212 }
3213
3214 requiredDescription = true
3215
3216 if err := s.Description.decode(params, value); err != nil {
3217 return fmt.Errorf(errDecodingProp, cAlarmDisplay, cDescription, err)
3218 }
3219 case "TRIGGER":
3220 if requiredTrigger {
3221 return fmt.Errorf(errMultiple, cAlarmDisplay, cTrigger)
3222 }
3223
3224 requiredTrigger = true
3225
3226 if err := s.Trigger.decode(params, value); err != nil {
3227 return fmt.Errorf(errDecodingProp, cAlarmDisplay, cTrigger, err)
3228 }
3229 case "DURATION":
3230 if s.Duration != nil {
3231 return fmt.Errorf(errMultiple, cAlarmDisplay, cDuration)
3232 }
3233
3234 s.Duration = new(PropDuration)
3235
3236 if err := s.Duration.decode(params, value); err != nil {
3237 return fmt.Errorf(errDecodingProp, cAlarmDisplay, cDuration, err)
3238 }
3239 case "REPEAT":
3240 if s.Repeat != nil {
3241 return fmt.Errorf(errMultiple, cAlarmDisplay, cRepeat)
3242 }
3243
3244 s.Repeat = new(PropRepeat)
3245
3246 if err := s.Repeat.decode(params, value); err != nil {
3247 return fmt.Errorf(errDecodingProp, cAlarmDisplay, cRepeat, err)
3248 }
3249 case "UID":
3250 if s.UID != nil {
3251 return fmt.Errorf(errMultiple, cAlarmDisplay, cUID)
3252 }
3253
3254 s.UID = new(PropUID)
3255
3256 if err := s.UID.decode(params, value); err != nil {
3257 return fmt.Errorf(errDecodingProp, cAlarmDisplay, cUID, err)
3258 }
3259 case "ALARM-AGENT":
3260 var e PropAlarmAgent
3261
3262 if err := e.decode(params, value); err != nil {
3263 return fmt.Errorf(errDecodingProp, cAlarmDisplay, cAlarmAgent, err)
3264 }
3265
3266 s.AlarmAgent = append(s.AlarmAgent, e)
3267 case "STATUS":
3268 if s.AlarmStatus != nil {
3269 return fmt.Errorf(errMultiple, cAlarmDisplay, cAlarmStatus)
3270 }
3271
3272 s.AlarmStatus = new(PropAlarmStatus)
3273
3274 if err := s.AlarmStatus.decode(params, value); err != nil {
3275 return fmt.Errorf(errDecodingProp, cAlarmDisplay, cAlarmStatus, err)
3276 }
3277 case "LAST-TRIGGERED":
3278 var e PropLastTriggered
3279
3280 if err := e.decode(params, value); err != nil {
3281 return fmt.Errorf(errDecodingProp, cAlarmDisplay, cLastTriggered, err)
3282 }
3283
3284 s.LastTriggered = append(s.LastTriggered, e)
3285 case "ACKNOWLEDGED":
3286 if s.Acknowledged != nil {
3287 return fmt.Errorf(errMultiple, cAlarmDisplay, cAcknowledged)
3288 }
3289
3290 s.Acknowledged = new(PropAcknowledged)
3291
3292 if err := s.Acknowledged.decode(params, value); err != nil {
3293 return fmt.Errorf(errDecodingProp, cAlarmDisplay, cAcknowledged, err)
3294 }
3295 case "PROXIMITY":
3296 if s.Proximity != nil {
3297 return fmt.Errorf(errMultiple, cAlarmDisplay, cProximity)
3298 }
3299
3300 s.Proximity = new(PropProximity)
3301
3302 if err := s.Proximity.decode(params, value); err != nil {
3303 return fmt.Errorf(errDecodingProp, cAlarmDisplay, cProximity, err)
3304 }
3305 case "GEO-LOCATION":
3306 var e PropGeoLocation
3307
3308 if err := e.decode(params, value); err != nil {
3309 return fmt.Errorf(errDecodingProp, cAlarmDisplay, cGeoLocation, err)
3310 }
3311
3312 s.GeoLocation = append(s.GeoLocation, e)
3313 case "RELATED-TO":
3314 if s.RelatedTo != nil {
3315 return fmt.Errorf(errMultiple, cAlarmDisplay, cRelatedTo)
3316 }
3317
3318 s.RelatedTo = new(PropRelatedTo)
3319
3320 if err := s.RelatedTo.decode(params, value); err != nil {
3321 return fmt.Errorf(errDecodingProp, cAlarmDisplay, cRelatedTo, err)
3322 }
3323 case "DEFAULT-ALARM":
3324 if s.DefaultAlarm != nil {
3325 return fmt.Errorf(errMultiple, cAlarmDisplay, cDefaultAlarm)
3326 }
3327
3328 s.DefaultAlarm = new(PropDefaultAlarm)
3329
3330 if err := s.DefaultAlarm.decode(params, value); err != nil {
3331 return fmt.Errorf(errDecodingProp, cAlarmDisplay, cDefaultAlarm, err)
3332 }
3333 case "END":
3334 if value != "VALARM" {
3335 return fmt.Errorf(errDecodingType, cAlarmDisplay, ErrInvalidEnd)
3336 }
3337
3338 break Loop
3339 }
3340 }
3341
3342 if !requiredDescription || !requiredTrigger {
3343 return fmt.Errorf(errDecodingType, cAlarmDisplay, ErrMissingRequired)
3344 }
3345
3346 if s.GeoLocation != nil && (s.Proximity == nil) {
3347 return fmt.Errorf(errDecodingType, cAlarmDisplay, ErrRequirementNotMet)
3348 }
3349
3350 return nil
3351 }
3352
3353 func (s *AlarmDisplay) encode(w writer) {
3354 s.Description.encode(w)
3355 s.Trigger.encode(w)
3356
3357 if s.Duration != nil {
3358 s.Duration.encode(w)
3359 }
3360
3361 if s.Repeat != nil {
3362 s.Repeat.encode(w)
3363 }
3364
3365 if s.UID != nil {
3366 s.UID.encode(w)
3367 }
3368
3369 for n := range s.AlarmAgent {
3370 s.AlarmAgent[n].encode(w)
3371 }
3372
3373 if s.AlarmStatus != nil {
3374 s.AlarmStatus.encode(w)
3375 }
3376
3377 for n := range s.LastTriggered {
3378 s.LastTriggered[n].encode(w)
3379 }
3380
3381 if s.Acknowledged != nil {
3382 s.Acknowledged.encode(w)
3383 }
3384
3385 if s.Proximity != nil {
3386 s.Proximity.encode(w)
3387 }
3388
3389 for n := range s.GeoLocation {
3390 s.GeoLocation[n].encode(w)
3391 }
3392
3393 if s.RelatedTo != nil {
3394 s.RelatedTo.encode(w)
3395 }
3396
3397 if s.DefaultAlarm != nil {
3398 s.DefaultAlarm.encode(w)
3399 }
3400
3401 }
3402
3403 func (s *AlarmDisplay) valid() error {
3404 if err := s.Description.valid(); err != nil {
3405 return fmt.Errorf(errValidatingProp, cAlarmDisplay, cDescription, err)
3406 }
3407
3408 if err := s.Trigger.valid(); err != nil {
3409 return fmt.Errorf(errValidatingProp, cAlarmDisplay, cTrigger, err)
3410 }
3411
3412 if s.Duration != nil {
3413 if err := s.Duration.valid(); err != nil {
3414 return fmt.Errorf(errValidatingProp, cAlarmDisplay, cDuration, err)
3415 }
3416 }
3417
3418 if s.Repeat != nil {
3419 if err := s.Repeat.valid(); err != nil {
3420 return fmt.Errorf(errValidatingProp, cAlarmDisplay, cRepeat, err)
3421 }
3422 }
3423
3424 if s.UID != nil {
3425 if err := s.UID.valid(); err != nil {
3426 return fmt.Errorf(errValidatingProp, cAlarmDisplay, cUID, err)
3427 }
3428 }
3429
3430 for n := range s.AlarmAgent {
3431 if err := s.AlarmAgent[n].valid(); err != nil {
3432 return fmt.Errorf(errValidatingProp, cAlarmDisplay, cAlarmAgent, err)
3433 }
3434 }
3435
3436 if s.AlarmStatus != nil {
3437 if err := s.AlarmStatus.valid(); err != nil {
3438 return fmt.Errorf(errValidatingProp, cAlarmDisplay, cAlarmStatus, err)
3439 }
3440 }
3441
3442 for n := range s.LastTriggered {
3443 if err := s.LastTriggered[n].valid(); err != nil {
3444 return fmt.Errorf(errValidatingProp, cAlarmDisplay, cLastTriggered, err)
3445 }
3446 }
3447
3448 if s.Acknowledged != nil {
3449 if err := s.Acknowledged.valid(); err != nil {
3450 return fmt.Errorf(errValidatingProp, cAlarmDisplay, cAcknowledged, err)
3451 }
3452 }
3453
3454 if s.Proximity != nil {
3455 if err := s.Proximity.valid(); err != nil {
3456 return fmt.Errorf(errValidatingProp, cAlarmDisplay, cProximity, err)
3457 }
3458 }
3459
3460 for n := range s.GeoLocation {
3461 if err := s.GeoLocation[n].valid(); err != nil {
3462 return fmt.Errorf(errValidatingProp, cAlarmDisplay, cGeoLocation, err)
3463 }
3464 }
3465
3466 if s.RelatedTo != nil {
3467 if err := s.RelatedTo.valid(); err != nil {
3468 return fmt.Errorf(errValidatingProp, cAlarmDisplay, cRelatedTo, err)
3469 }
3470 }
3471
3472 if s.DefaultAlarm != nil {
3473 if err := s.DefaultAlarm.valid(); err != nil {
3474 return fmt.Errorf(errValidatingProp, cAlarmDisplay, cDefaultAlarm, err)
3475 }
3476 }
3477
3478 return nil
3479 }
3480
3481 // AlarmEmail provides a group of components that define an Email Alarm.
3482 type AlarmEmail struct {
3483 Description PropDescription
3484 Trigger PropTrigger
3485 Summary PropSummary
3486 Attendee *PropAttendee
3487 Duration *PropDuration
3488 Repeat *PropRepeat
3489 UID *PropUID
3490 AlarmAgent []PropAlarmAgent
3491 AlarmStatus *PropAlarmStatus
3492 LastTriggered []PropLastTriggered
3493 Acknowledged *PropAcknowledged
3494 Proximity *PropProximity
3495 GeoLocation []PropGeoLocation
3496 RelatedTo *PropRelatedTo
3497 DefaultAlarm *PropDefaultAlarm
3498 }
3499
3500 func (s *AlarmEmail) decode(t tokeniser) error {
3501 var requiredDescription, requiredTrigger, requiredSummary bool
3502
3503 Loop:
3504 for {
3505 p, err := t.GetPhrase()
3506 if err != nil {
3507 return fmt.Errorf(errDecodingType, cAlarmEmail, err)
3508 } else if p.Type == parser.PhraseDone {
3509 return fmt.Errorf(errDecodingType, cAlarmEmail, io.ErrUnexpectedEOF)
3510 }
3511
3512 params := p.Data[1 : len(p.Data)-1]
3513 value := p.Data[len(p.Data)-1].Data
3514
3515 switch strings.ToUpper(p.Data[0].Data) {
3516 case "BEGIN":
3517 switch n := strings.ToUpper(value); n {
3518 default:
3519 if err := decodeDummy(t, n); err != nil {
3520 return fmt.Errorf(errDecodingType, cAlarmEmail, err)
3521 }
3522 }
3523 case "DESCRIPTION":
3524 if requiredDescription {
3525 return fmt.Errorf(errMultiple, cAlarmEmail, cDescription)
3526 }
3527
3528 requiredDescription = true
3529
3530 if err := s.Description.decode(params, value); err != nil {
3531 return fmt.Errorf(errDecodingProp, cAlarmEmail, cDescription, err)
3532 }
3533 case "TRIGGER":
3534 if requiredTrigger {
3535 return fmt.Errorf(errMultiple, cAlarmEmail, cTrigger)
3536 }
3537
3538 requiredTrigger = true
3539
3540 if err := s.Trigger.decode(params, value); err != nil {
3541 return fmt.Errorf(errDecodingProp, cAlarmEmail, cTrigger, err)
3542 }
3543 case "SUMMARY":
3544 if requiredSummary {
3545 return fmt.Errorf(errMultiple, cAlarmEmail, cSummary)
3546 }
3547
3548 requiredSummary = true
3549
3550 if err := s.Summary.decode(params, value); err != nil {
3551 return fmt.Errorf(errDecodingProp, cAlarmEmail, cSummary, err)
3552 }
3553 case "ATTENDEE":
3554 if s.Attendee != nil {
3555 return fmt.Errorf(errMultiple, cAlarmEmail, cAttendee)
3556 }
3557
3558 s.Attendee = new(PropAttendee)
3559
3560 if err := s.Attendee.decode(params, value); err != nil {
3561 return fmt.Errorf(errDecodingProp, cAlarmEmail, cAttendee, err)
3562 }
3563 case "DURATION":
3564 if s.Duration != nil {
3565 return fmt.Errorf(errMultiple, cAlarmEmail, cDuration)
3566 }
3567
3568 s.Duration = new(PropDuration)
3569
3570 if err := s.Duration.decode(params, value); err != nil {
3571 return fmt.Errorf(errDecodingProp, cAlarmEmail, cDuration, err)
3572 }
3573 case "REPEAT":
3574 if s.Repeat != nil {
3575 return fmt.Errorf(errMultiple, cAlarmEmail, cRepeat)
3576 }
3577
3578 s.Repeat = new(PropRepeat)
3579
3580 if err := s.Repeat.decode(params, value); err != nil {
3581 return fmt.Errorf(errDecodingProp, cAlarmEmail, cRepeat, err)
3582 }
3583 case "UID":
3584 if s.UID != nil {
3585 return fmt.Errorf(errMultiple, cAlarmEmail, cUID)
3586 }
3587
3588 s.UID = new(PropUID)
3589
3590 if err := s.UID.decode(params, value); err != nil {
3591 return fmt.Errorf(errDecodingProp, cAlarmEmail, cUID, err)
3592 }
3593 case "ALARM-AGENT":
3594 var e PropAlarmAgent
3595
3596 if err := e.decode(params, value); err != nil {
3597 return fmt.Errorf(errDecodingProp, cAlarmEmail, cAlarmAgent, err)
3598 }
3599
3600 s.AlarmAgent = append(s.AlarmAgent, e)
3601 case "STATUS":
3602 if s.AlarmStatus != nil {
3603 return fmt.Errorf(errMultiple, cAlarmEmail, cAlarmStatus)
3604 }
3605
3606 s.AlarmStatus = new(PropAlarmStatus)
3607
3608 if err := s.AlarmStatus.decode(params, value); err != nil {
3609 return fmt.Errorf(errDecodingProp, cAlarmEmail, cAlarmStatus, err)
3610 }
3611 case "LAST-TRIGGERED":
3612 var e PropLastTriggered
3613
3614 if err := e.decode(params, value); err != nil {
3615 return fmt.Errorf(errDecodingProp, cAlarmEmail, cLastTriggered, err)
3616 }
3617
3618 s.LastTriggered = append(s.LastTriggered, e)
3619 case "ACKNOWLEDGED":
3620 if s.Acknowledged != nil {
3621 return fmt.Errorf(errMultiple, cAlarmEmail, cAcknowledged)
3622 }
3623
3624 s.Acknowledged = new(PropAcknowledged)
3625
3626 if err := s.Acknowledged.decode(params, value); err != nil {
3627 return fmt.Errorf(errDecodingProp, cAlarmEmail, cAcknowledged, err)
3628 }
3629 case "PROXIMITY":
3630 if s.Proximity != nil {
3631 return fmt.Errorf(errMultiple, cAlarmEmail, cProximity)
3632 }
3633
3634 s.Proximity = new(PropProximity)
3635
3636 if err := s.Proximity.decode(params, value); err != nil {
3637 return fmt.Errorf(errDecodingProp, cAlarmEmail, cProximity, err)
3638 }
3639 case "GEO-LOCATION":
3640 var e PropGeoLocation
3641
3642 if err := e.decode(params, value); err != nil {
3643 return fmt.Errorf(errDecodingProp, cAlarmEmail, cGeoLocation, err)
3644 }
3645
3646 s.GeoLocation = append(s.GeoLocation, e)
3647 case "RELATED-TO":
3648 if s.RelatedTo != nil {
3649 return fmt.Errorf(errMultiple, cAlarmEmail, cRelatedTo)
3650 }
3651
3652 s.RelatedTo = new(PropRelatedTo)
3653
3654 if err := s.RelatedTo.decode(params, value); err != nil {
3655 return fmt.Errorf(errDecodingProp, cAlarmEmail, cRelatedTo, err)
3656 }
3657 case "DEFAULT-ALARM":
3658 if s.DefaultAlarm != nil {
3659 return fmt.Errorf(errMultiple, cAlarmEmail, cDefaultAlarm)
3660 }
3661
3662 s.DefaultAlarm = new(PropDefaultAlarm)
3663
3664 if err := s.DefaultAlarm.decode(params, value); err != nil {
3665 return fmt.Errorf(errDecodingProp, cAlarmEmail, cDefaultAlarm, err)
3666 }
3667 case "END":
3668 if value != "VALARM" {
3669 return fmt.Errorf(errDecodingType, cAlarmEmail, ErrInvalidEnd)
3670 }
3671
3672 break Loop
3673 }
3674 }
3675
3676 if !requiredDescription || !requiredTrigger || !requiredSummary {
3677 return fmt.Errorf(errDecodingType, cAlarmEmail, ErrMissingRequired)
3678 }
3679
3680 if s.GeoLocation != nil && (s.Proximity == nil) {
3681 return fmt.Errorf(errDecodingType, cAlarmEmail, ErrRequirementNotMet)
3682 }
3683
3684 if t := s.Duration == nil; t == (s.Repeat == nil) {
3685 return fmt.Errorf(errDecodingType, cAlarmEmail, ErrRequirementNotMet)
3686 }
3687
3688 return nil
3689 }
3690
3691 func (s *AlarmEmail) encode(w writer) {
3692 s.Description.encode(w)
3693 s.Trigger.encode(w)
3694 s.Summary.encode(w)
3695
3696 if s.Attendee != nil {
3697 s.Attendee.encode(w)
3698 }
3699
3700 if s.Duration != nil {
3701 s.Duration.encode(w)
3702 }
3703
3704 if s.Repeat != nil {
3705 s.Repeat.encode(w)
3706 }
3707
3708 if s.UID != nil {
3709 s.UID.encode(w)
3710 }
3711
3712 for n := range s.AlarmAgent {
3713 s.AlarmAgent[n].encode(w)
3714 }
3715
3716 if s.AlarmStatus != nil {
3717 s.AlarmStatus.encode(w)
3718 }
3719
3720 for n := range s.LastTriggered {
3721 s.LastTriggered[n].encode(w)
3722 }
3723
3724 if s.Acknowledged != nil {
3725 s.Acknowledged.encode(w)
3726 }
3727
3728 if s.Proximity != nil {
3729 s.Proximity.encode(w)
3730 }
3731
3732 for n := range s.GeoLocation {
3733 s.GeoLocation[n].encode(w)
3734 }
3735
3736 if s.RelatedTo != nil {
3737 s.RelatedTo.encode(w)
3738 }
3739
3740 if s.DefaultAlarm != nil {
3741 s.DefaultAlarm.encode(w)
3742 }
3743
3744 }
3745
3746 func (s *AlarmEmail) valid() error {
3747 if err := s.Description.valid(); err != nil {
3748 return fmt.Errorf(errValidatingProp, cAlarmEmail, cDescription, err)
3749 }
3750
3751 if err := s.Trigger.valid(); err != nil {
3752 return fmt.Errorf(errValidatingProp, cAlarmEmail, cTrigger, err)
3753 }
3754
3755 if err := s.Summary.valid(); err != nil {
3756 return fmt.Errorf(errValidatingProp, cAlarmEmail, cSummary, err)
3757 }
3758
3759 if s.Attendee != nil {
3760 if err := s.Attendee.valid(); err != nil {
3761 return fmt.Errorf(errValidatingProp, cAlarmEmail, cAttendee, err)
3762 }
3763 }
3764
3765 if s.Duration != nil {
3766 if err := s.Duration.valid(); err != nil {
3767 return fmt.Errorf(errValidatingProp, cAlarmEmail, cDuration, err)
3768 }
3769 }
3770
3771 if s.Repeat != nil {
3772 if err := s.Repeat.valid(); err != nil {
3773 return fmt.Errorf(errValidatingProp, cAlarmEmail, cRepeat, err)
3774 }
3775 }
3776
3777 if s.UID != nil {
3778 if err := s.UID.valid(); err != nil {
3779 return fmt.Errorf(errValidatingProp, cAlarmEmail, cUID, err)
3780 }
3781 }
3782
3783 for n := range s.AlarmAgent {
3784 if err := s.AlarmAgent[n].valid(); err != nil {
3785 return fmt.Errorf(errValidatingProp, cAlarmEmail, cAlarmAgent, err)
3786 }
3787 }
3788
3789 if s.AlarmStatus != nil {
3790 if err := s.AlarmStatus.valid(); err != nil {
3791 return fmt.Errorf(errValidatingProp, cAlarmEmail, cAlarmStatus, err)
3792 }
3793 }
3794
3795 for n := range s.LastTriggered {
3796 if err := s.LastTriggered[n].valid(); err != nil {
3797 return fmt.Errorf(errValidatingProp, cAlarmEmail, cLastTriggered, err)
3798 }
3799 }
3800
3801 if s.Acknowledged != nil {
3802 if err := s.Acknowledged.valid(); err != nil {
3803 return fmt.Errorf(errValidatingProp, cAlarmEmail, cAcknowledged, err)
3804 }
3805 }
3806
3807 if s.Proximity != nil {
3808 if err := s.Proximity.valid(); err != nil {
3809 return fmt.Errorf(errValidatingProp, cAlarmEmail, cProximity, err)
3810 }
3811 }
3812
3813 for n := range s.GeoLocation {
3814 if err := s.GeoLocation[n].valid(); err != nil {
3815 return fmt.Errorf(errValidatingProp, cAlarmEmail, cGeoLocation, err)
3816 }
3817 }
3818
3819 if s.RelatedTo != nil {
3820 if err := s.RelatedTo.valid(); err != nil {
3821 return fmt.Errorf(errValidatingProp, cAlarmEmail, cRelatedTo, err)
3822 }
3823 }
3824
3825 if s.DefaultAlarm != nil {
3826 if err := s.DefaultAlarm.valid(); err != nil {
3827 return fmt.Errorf(errValidatingProp, cAlarmEmail, cDefaultAlarm, err)
3828 }
3829 }
3830
3831 return nil
3832 }
3833
3834 // AlarmURI provides a group of components that define a URI Alarm.
3835 type AlarmURI struct {
3836 URI PropURI
3837 Duration *PropDuration
3838 Repeat *PropRepeat
3839 UID *PropUID
3840 AlarmAgent []PropAlarmAgent
3841 AlarmStatus *PropAlarmStatus
3842 LastTriggered []PropLastTriggered
3843 Acknowledged *PropAcknowledged
3844 Proximity *PropProximity
3845 GeoLocation []PropGeoLocation
3846 RelatedTo *PropRelatedTo
3847 DefaultAlarm *PropDefaultAlarm
3848 }
3849
3850 func (s *AlarmURI) decode(t tokeniser) error {
3851 var requiredURI bool
3852
3853 Loop:
3854 for {
3855 p, err := t.GetPhrase()
3856 if err != nil {
3857 return fmt.Errorf(errDecodingType, cAlarmURI, err)
3858 } else if p.Type == parser.PhraseDone {
3859 return fmt.Errorf(errDecodingType, cAlarmURI, io.ErrUnexpectedEOF)
3860 }
3861
3862 params := p.Data[1 : len(p.Data)-1]
3863 value := p.Data[len(p.Data)-1].Data
3864
3865 switch strings.ToUpper(p.Data[0].Data) {
3866 case "BEGIN":
3867 switch n := strings.ToUpper(value); n {
3868 default:
3869 if err := decodeDummy(t, n); err != nil {
3870 return fmt.Errorf(errDecodingType, cAlarmURI, err)
3871 }
3872 }
3873 case "URI":
3874 if requiredURI {
3875 return fmt.Errorf(errMultiple, cAlarmURI, cURI)
3876 }
3877
3878 requiredURI = true
3879
3880 if err := s.URI.decode(params, value); err != nil {
3881 return fmt.Errorf(errDecodingProp, cAlarmURI, cURI, err)
3882 }
3883 case "DURATION":
3884 if s.Duration != nil {
3885 return fmt.Errorf(errMultiple, cAlarmURI, cDuration)
3886 }
3887
3888 s.Duration = new(PropDuration)
3889
3890 if err := s.Duration.decode(params, value); err != nil {
3891 return fmt.Errorf(errDecodingProp, cAlarmURI, cDuration, err)
3892 }
3893 case "REPEAT":
3894 if s.Repeat != nil {
3895 return fmt.Errorf(errMultiple, cAlarmURI, cRepeat)
3896 }
3897
3898 s.Repeat = new(PropRepeat)
3899
3900 if err := s.Repeat.decode(params, value); err != nil {
3901 return fmt.Errorf(errDecodingProp, cAlarmURI, cRepeat, err)
3902 }
3903 case "UID":
3904 if s.UID != nil {
3905 return fmt.Errorf(errMultiple, cAlarmURI, cUID)
3906 }
3907
3908 s.UID = new(PropUID)
3909
3910 if err := s.UID.decode(params, value); err != nil {
3911 return fmt.Errorf(errDecodingProp, cAlarmURI, cUID, err)
3912 }
3913 case "ALARM-AGENT":
3914 var e PropAlarmAgent
3915
3916 if err := e.decode(params, value); err != nil {
3917 return fmt.Errorf(errDecodingProp, cAlarmURI, cAlarmAgent, err)
3918 }
3919
3920 s.AlarmAgent = append(s.AlarmAgent, e)
3921 case "STATUS":
3922 if s.AlarmStatus != nil {
3923 return fmt.Errorf(errMultiple, cAlarmURI, cAlarmStatus)
3924 }
3925
3926 s.AlarmStatus = new(PropAlarmStatus)
3927
3928 if err := s.AlarmStatus.decode(params, value); err != nil {
3929 return fmt.Errorf(errDecodingProp, cAlarmURI, cAlarmStatus, err)
3930 }
3931 case "LAST-TRIGGERED":
3932 var e PropLastTriggered
3933
3934 if err := e.decode(params, value); err != nil {
3935 return fmt.Errorf(errDecodingProp, cAlarmURI, cLastTriggered, err)
3936 }
3937
3938 s.LastTriggered = append(s.LastTriggered, e)
3939 case "ACKNOWLEDGED":
3940 if s.Acknowledged != nil {
3941 return fmt.Errorf(errMultiple, cAlarmURI, cAcknowledged)
3942 }
3943
3944 s.Acknowledged = new(PropAcknowledged)
3945
3946 if err := s.Acknowledged.decode(params, value); err != nil {
3947 return fmt.Errorf(errDecodingProp, cAlarmURI, cAcknowledged, err)
3948 }
3949 case "PROXIMITY":
3950 if s.Proximity != nil {
3951 return fmt.Errorf(errMultiple, cAlarmURI, cProximity)
3952 }
3953
3954 s.Proximity = new(PropProximity)
3955
3956 if err := s.Proximity.decode(params, value); err != nil {
3957 return fmt.Errorf(errDecodingProp, cAlarmURI, cProximity, err)
3958 }
3959 case "GEO-LOCATION":
3960 var e PropGeoLocation
3961
3962 if err := e.decode(params, value); err != nil {
3963 return fmt.Errorf(errDecodingProp, cAlarmURI, cGeoLocation, err)
3964 }
3965
3966 s.GeoLocation = append(s.GeoLocation, e)
3967 case "RELATED-TO":
3968 if s.RelatedTo != nil {
3969 return fmt.Errorf(errMultiple, cAlarmURI, cRelatedTo)
3970 }
3971
3972 s.RelatedTo = new(PropRelatedTo)
3973
3974 if err := s.RelatedTo.decode(params, value); err != nil {
3975 return fmt.Errorf(errDecodingProp, cAlarmURI, cRelatedTo, err)
3976 }
3977 case "DEFAULT-ALARM":
3978 if s.DefaultAlarm != nil {
3979 return fmt.Errorf(errMultiple, cAlarmURI, cDefaultAlarm)
3980 }
3981
3982 s.DefaultAlarm = new(PropDefaultAlarm)
3983
3984 if err := s.DefaultAlarm.decode(params, value); err != nil {
3985 return fmt.Errorf(errDecodingProp, cAlarmURI, cDefaultAlarm, err)
3986 }
3987 case "END":
3988 if value != "VALARM" {
3989 return fmt.Errorf(errDecodingType, cAlarmURI, ErrInvalidEnd)
3990 }
3991
3992 break Loop
3993 }
3994 }
3995
3996 if !requiredURI {
3997 return fmt.Errorf(errDecodingType, cAlarmURI, ErrMissingRequired)
3998 }
3999
4000 if s.GeoLocation != nil && (s.Proximity == nil) {
4001 return fmt.Errorf(errDecodingType, cAlarmURI, ErrRequirementNotMet)
4002 }
4003
4004 if t := s.Duration == nil; t == (s.Repeat == nil) {
4005 return fmt.Errorf(errDecodingType, cAlarmURI, ErrRequirementNotMet)
4006 }
4007
4008 return nil
4009 }
4010
4011 func (s *AlarmURI) encode(w writer) {
4012 s.URI.encode(w)
4013
4014 if s.Duration != nil {
4015 s.Duration.encode(w)
4016 }
4017
4018 if s.Repeat != nil {
4019 s.Repeat.encode(w)
4020 }
4021
4022 if s.UID != nil {
4023 s.UID.encode(w)
4024 }
4025
4026 for n := range s.AlarmAgent {
4027 s.AlarmAgent[n].encode(w)
4028 }
4029
4030 if s.AlarmStatus != nil {
4031 s.AlarmStatus.encode(w)
4032 }
4033
4034 for n := range s.LastTriggered {
4035 s.LastTriggered[n].encode(w)
4036 }
4037
4038 if s.Acknowledged != nil {
4039 s.Acknowledged.encode(w)
4040 }
4041
4042 if s.Proximity != nil {
4043 s.Proximity.encode(w)
4044 }
4045
4046 for n := range s.GeoLocation {
4047 s.GeoLocation[n].encode(w)
4048 }
4049
4050 if s.RelatedTo != nil {
4051 s.RelatedTo.encode(w)
4052 }
4053
4054 if s.DefaultAlarm != nil {
4055 s.DefaultAlarm.encode(w)
4056 }
4057
4058 }
4059
4060 func (s *AlarmURI) valid() error {
4061 if err := s.URI.valid(); err != nil {
4062 return fmt.Errorf(errValidatingProp, cAlarmURI, cURI, err)
4063 }
4064
4065 if s.Duration != nil {
4066 if err := s.Duration.valid(); err != nil {
4067 return fmt.Errorf(errValidatingProp, cAlarmURI, cDuration, err)
4068 }
4069 }
4070
4071 if s.Repeat != nil {
4072 if err := s.Repeat.valid(); err != nil {
4073 return fmt.Errorf(errValidatingProp, cAlarmURI, cRepeat, err)
4074 }
4075 }
4076
4077 if s.UID != nil {
4078 if err := s.UID.valid(); err != nil {
4079 return fmt.Errorf(errValidatingProp, cAlarmURI, cUID, err)
4080 }
4081 }
4082
4083 for n := range s.AlarmAgent {
4084 if err := s.AlarmAgent[n].valid(); err != nil {
4085 return fmt.Errorf(errValidatingProp, cAlarmURI, cAlarmAgent, err)
4086 }
4087 }
4088
4089 if s.AlarmStatus != nil {
4090 if err := s.AlarmStatus.valid(); err != nil {
4091 return fmt.Errorf(errValidatingProp, cAlarmURI, cAlarmStatus, err)
4092 }
4093 }
4094
4095 for n := range s.LastTriggered {
4096 if err := s.LastTriggered[n].valid(); err != nil {
4097 return fmt.Errorf(errValidatingProp, cAlarmURI, cLastTriggered, err)
4098 }
4099 }
4100
4101 if s.Acknowledged != nil {
4102 if err := s.Acknowledged.valid(); err != nil {
4103 return fmt.Errorf(errValidatingProp, cAlarmURI, cAcknowledged, err)
4104 }
4105 }
4106
4107 if s.Proximity != nil {
4108 if err := s.Proximity.valid(); err != nil {
4109 return fmt.Errorf(errValidatingProp, cAlarmURI, cProximity, err)
4110 }
4111 }
4112
4113 for n := range s.GeoLocation {
4114 if err := s.GeoLocation[n].valid(); err != nil {
4115 return fmt.Errorf(errValidatingProp, cAlarmURI, cGeoLocation, err)
4116 }
4117 }
4118
4119 if s.RelatedTo != nil {
4120 if err := s.RelatedTo.valid(); err != nil {
4121 return fmt.Errorf(errValidatingProp, cAlarmURI, cRelatedTo, err)
4122 }
4123 }
4124
4125 if s.DefaultAlarm != nil {
4126 if err := s.DefaultAlarm.valid(); err != nil {
4127 return fmt.Errorf(errValidatingProp, cAlarmURI, cDefaultAlarm, err)
4128 }
4129 }
4130
4131 return nil
4132 }
4133
4134 // AlarmNone.
4135 type AlarmNone struct{}
4136
4137 func (s *AlarmNone) decode(t tokeniser) error {
4138 Loop:
4139 for {
4140 p, err := t.GetPhrase()
4141 if err != nil {
4142 return fmt.Errorf(errDecodingType, cAlarmNone, err)
4143 } else if p.Type == parser.PhraseDone {
4144 return fmt.Errorf(errDecodingType, cAlarmNone, io.ErrUnexpectedEOF)
4145 }
4146
4147 value := p.Data[len(p.Data)-1].Data
4148
4149 switch strings.ToUpper(p.Data[0].Data) {
4150 case "BEGIN":
4151 switch n := strings.ToUpper(value); n {
4152 default:
4153 if err := decodeDummy(t, n); err != nil {
4154 return fmt.Errorf(errDecodingType, cAlarmNone, err)
4155 }
4156 }
4157 case "END":
4158 if value != "VALARM" {
4159 return fmt.Errorf(errDecodingType, cAlarmNone, ErrInvalidEnd)
4160 }
4161
4162 break Loop
4163 }
4164 }
4165 return nil
4166 }
4167
4168 func (s *AlarmNone) encode(w writer) {
4169 }
4170
4171 func (s *AlarmNone) valid() error {
4172 return nil
4173 }
4174
4175 // decodeDummy reads unknown sections, discarding the data.
4176 func decodeDummy(t tokeniser, n string) error {
4177 for {
4178 p, err := t.GetPhrase()
4179 if err != nil {
4180 return err
4181 } else if p.Type == parser.PhraseDone {
4182 return io.ErrUnexpectedEOF
4183 }
4184
4185 switch strings.ToUpper(p.Data[0].Data) {
4186 case "BEGIN":
4187 if err := decodeDummy(t, p.Data[len(p.Data)-1].Data); err != nil {
4188 return err
4189 }
4190 case "END":
4191 if strings.ToUpper(p.Data[len(p.Data)-1].Data) == n {
4192 return nil
4193 }
4194
4195 return ErrInvalidEnd
4196 }
4197 }
4198 }
4199
4200 // Errors.
4201 var (
4202 ErrInvalidEnd = errors.New("invalid end of section")
4203 ErrMissingRequired = errors.New("required property missing")
4204 ErrRequirementNotMet = errors.New("requirement not met")
4205 )
4206
4207 const (
4208 errMultiple = "error decoding %s: multiple %s"
4209 cCalendar = "Calendar"
4210 cEvent = "Event"
4211 cTodo = "Todo"
4212 cJournal = "Journal"
4213 cTimezone = "Timezone"
4214 cStandard = "Standard"
4215 cDaylight = "Daylight"
4216 cAlarmAudio = "AlarmAudio"
4217 cAlarmDisplay = "AlarmDisplay"
4218 cAlarmEmail = "AlarmEmail"
4219 cAlarmURI = "AlarmURI"
4220 cAlarmNone = "AlarmNone"
4221 )
4222