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