1 /* -*- Mode: C -*- */
2 /*======================================================================
3  FILE: icalrecur.h
4  CREATOR: eric 20 March 2000
5 
6 
7  (C) COPYRIGHT 2000, Eric Busboom <eric@softwarestudio.org>
8      http://www.softwarestudio.org
9 
10  This program is free software; you can redistribute it and/or modify
11  it under the terms of either:
12 
13     The LGPL as published by the Free Software Foundation, version
14     2.1, available at: http://www.fsf.org/copyleft/lesser.html
15 
16   Or:
17 
18     The Mozilla Public License Version 1.0. You may obtain a copy of
19     the License at http://www.mozilla.org/MPL/
20 */
21 
22 /**
23 @file icalrecur.h
24 @brief Routines for dealing with recurring time
25 
26 How to use:
27 
28 1) Get a rule and a start time from a component
29 
30 @code
31         icalproperty rrule;
32         struct icalrecurrencetype recur;
33         struct icaltimetype dtstart;
34 
35 	rrule = icalcomponent_get_first_property(comp,ICAL_RRULE_PROPERTY);
36 	recur = icalproperty_get_rrule(rrule);
37 	start = icalproperty_get_dtstart(dtstart);
38 @endcode
39 
40 Or, just make them up:
41 
42 @code
43         recur = icalrecurrencetype_from_string("FREQ=YEARLY;BYDAY=SU,WE");
44         dtstart = icaltime_from_string("19970101T123000")
45 @endcode
46 
47 2) Create an iterator
48 
49 @code
50         icalrecur_iterator* ritr;
51         ritr = icalrecur_iterator_new(recur,start);
52 @endcode
53 
54 3) Iterator over the occurrences
55 
56 @code
57         struct icaltimetype next;
58         while (next = icalrecur_iterator_next(ritr)
59                && !icaltime_is_null_time(next){
60                 Do something with next
61         }
62 @endcode
63 
64 Note that that the time returned by icalrecur_iterator_next is in
65 whatever timezone that dtstart is in.
66 
67 */
68 
69 #ifndef ICALRECUR_H
70 #define ICALRECUR_H
71 
72 #include <time.h>
73 #include "icaltime.h"
74 
75 /*
76  * Recurrance enumerations
77  */
78 
79 typedef enum icalrecurrencetype_frequency
80 {
81     /* These enums are used to index an array, so don't change the
82        order or the integers */
83 
84     ICAL_SECONDLY_RECURRENCE=0,
85     ICAL_MINUTELY_RECURRENCE=1,
86     ICAL_HOURLY_RECURRENCE=2,
87     ICAL_DAILY_RECURRENCE=3,
88     ICAL_WEEKLY_RECURRENCE=4,
89     ICAL_MONTHLY_RECURRENCE=5,
90     ICAL_YEARLY_RECURRENCE=6,
91     ICAL_NO_RECURRENCE=7
92 
93 } icalrecurrencetype_frequency;
94 
95 typedef enum icalrecurrencetype_weekday
96 {
97     ICAL_NO_WEEKDAY,
98     ICAL_SUNDAY_WEEKDAY,
99     ICAL_MONDAY_WEEKDAY,
100     ICAL_TUESDAY_WEEKDAY,
101     ICAL_WEDNESDAY_WEEKDAY,
102     ICAL_THURSDAY_WEEKDAY,
103     ICAL_FRIDAY_WEEKDAY,
104     ICAL_SATURDAY_WEEKDAY
105 } icalrecurrencetype_weekday;
106 
107 enum {
108     ICAL_RECURRENCE_ARRAY_MAX = 0x7f7f,
109     ICAL_RECURRENCE_ARRAY_MAX_BYTE = 0x7f
110 };
111 
112 
113 
114 /**
115  * Recurrence type routines
116  */
117 
118 /* See RFC 2445 Section 4.3.10, RECUR Value, for an explaination of
119    the values and fields in struct icalrecurrencetype */
120 
121 #define ICAL_BY_SECOND_SIZE 61
122 #define ICAL_BY_MINUTE_SIZE 61
123 #define ICAL_BY_HOUR_SIZE 25
124 #define ICAL_BY_DAY_SIZE 364 /* 7 days * 52 weeks */
125 #define ICAL_BY_MONTHDAY_SIZE 32
126 #define ICAL_BY_YEARDAY_SIZE 367
127 #define ICAL_BY_WEEKNO_SIZE 54
128 #define ICAL_BY_MONTH_SIZE 13
129 #define ICAL_BY_SETPOS_SIZE 367
130 
131 /** Main struct for holding digested recurrence rules */
132 struct icalrecurrencetype
133 {
134 	icalrecurrencetype_frequency freq;
135 
136 
137 	/* until and count are mutually exclusive. */
138        	struct icaltimetype until;
139 	int count;
140 
141 	short interval;
142 
143 	icalrecurrencetype_weekday week_start;
144 
145 	/* The BY* parameters can each take a list of values. Here I
146 	 * assume that the list of values will not be larger than the
147 	 * range of the value -- that is, the client will not name a
148 	 * value more than once.
149 
150 	 * Each of the lists is terminated with the value
151 	 * ICAL_RECURRENCE_ARRAY_MAX unless the the list is full.
152 	 */
153 
154 	short by_second[ICAL_BY_SECOND_SIZE];
155 	short by_minute[ICAL_BY_MINUTE_SIZE];
156 	short by_hour[ICAL_BY_HOUR_SIZE];
157 	short by_day[ICAL_BY_DAY_SIZE]; /* Encoded value, see below */
158 	short by_month_day[ICAL_BY_MONTHDAY_SIZE];
159 	short by_year_day[ ICAL_BY_YEARDAY_SIZE];
160 	short by_week_no[ICAL_BY_WEEKNO_SIZE];
161 	short by_month[ICAL_BY_MONTH_SIZE];
162 	short by_set_pos[ICAL_BY_SETPOS_SIZE];
163 };
164 
165 
166 void icalrecurrencetype_clear(struct icalrecurrencetype *r);
167 
168 /**
169  * Array Encoding
170  *
171  * The 'day' element of the by_day array is encoded to allow
172  * representation of both the day of the week ( Monday, Tueday), but also
173  * the Nth day of the week ( First tuesday of the month, last thursday of
174  * the year) These routines decode the day values
175  */
176 
177 /** 1 == Monday, etc. */
178 enum icalrecurrencetype_weekday icalrecurrencetype_day_day_of_week(short day);
179 
180 /** 0 == any of day of week. 1 == first, 2 = second, -2 == second to last, etc */
181 int icalrecurrencetype_day_position(short day);
182 
183 icalrecurrencetype_weekday icalrecur_string_to_weekday(const char* str);
184 
185 /** Recurrance rule parser */
186 
187 /** Convert between strings and recurrencetype structures. */
188 struct icalrecurrencetype icalrecurrencetype_from_string(const char* str);
189 char* icalrecurrencetype_as_string(struct icalrecurrencetype *recur);
190 char* icalrecurrencetype_as_string_r(struct icalrecurrencetype *recur);
191 
192 
193 /** Recurrence iteration routines */
194 
195 typedef struct icalrecur_iterator_impl  icalrecur_iterator;
196 
197 /** Create a new recurrence rule iterator */
198 icalrecur_iterator* icalrecur_iterator_new(struct icalrecurrencetype rule,
199                                            struct icaltimetype dtstart);
200 
201 /** Get the next occurrence from an iterator */
202 struct icaltimetype icalrecur_iterator_next(icalrecur_iterator*);
203 
204 void icalrecur_iterator_decrement_count(icalrecur_iterator*);
205 
206 /** Free the iterator */
207 void icalrecur_iterator_free(icalrecur_iterator*);
208 
209 /**
210  * Fills array up with at most 'count' time_t values, each
211  *  representing an occurrence time in seconds past the POSIX epoch
212  */
213 int icalrecur_expand_recurrence(char* rule, time_t start,
214 				int count, time_t* array);
215 
216 
217 #endif
218