Diffstat (limited to 'libical/src/libical/icalduration.c') (more/less context) (ignore whitespace changes)
-rw-r--r-- | libical/src/libical/icalduration.c | 323 |
1 files changed, 323 insertions, 0 deletions
diff --git a/libical/src/libical/icalduration.c b/libical/src/libical/icalduration.c new file mode 100644 index 0000000..4468e0f --- a/dev/null +++ b/libical/src/libical/icalduration.c | |||
@@ -0,0 +1,323 @@ | |||
1 | /* -*- Mode: C -*- | ||
2 | ====================================================================== | ||
3 | FILE: icaltime.c | ||
4 | CREATOR: eric 02 June 2000 | ||
5 | |||
6 | $Id$ | ||
7 | $Locker$ | ||
8 | |||
9 | (C) COPYRIGHT 2000, Eric Busboom, http://www.softwarestudio.org | ||
10 | |||
11 | This program is free software; you can redistribute it and/or modify | ||
12 | it under the terms of either: | ||
13 | |||
14 | The LGPL as published by the Free Software Foundation, version | ||
15 | 2.1, available at: http://www.fsf.org/copyleft/lesser.html | ||
16 | |||
17 | Or: | ||
18 | |||
19 | The Mozilla Public License Version 1.0. You may obtain a copy of | ||
20 | the License at http://www.mozilla.org/MPL/ | ||
21 | |||
22 | The Original Code is eric. The Initial Developer of the Original | ||
23 | Code is Eric Busboom | ||
24 | |||
25 | |||
26 | ======================================================================*/ | ||
27 | |||
28 | #ifdef HAVE_CONFIG_H | ||
29 | #include <config.h> | ||
30 | #endif | ||
31 | |||
32 | #include "icalduration.h" | ||
33 | |||
34 | #include <assert.h> | ||
35 | #include <string.h> | ||
36 | #include <stdlib.h> | ||
37 | #include <stdio.h> | ||
38 | |||
39 | #ifdef ICAL_NO_LIBICAL | ||
40 | #define icalerror_set_errno(x) | ||
41 | #define icalerror_check_arg_rv(x,y) | ||
42 | #define icalerror_check_arg_re(x,y,z) | ||
43 | #else | ||
44 | #include "icalerror.h" | ||
45 | #include "icalmemory.h" | ||
46 | #endif | ||
47 | |||
48 | |||
49 | |||
50 | |||
51 | /* From Seth Alves, <alves@hungry.com> */ | ||
52 | struct icaldurationtype icaldurationtype_from_int(int t) | ||
53 | { | ||
54 | struct icaldurationtype dur; | ||
55 | int used = 0; | ||
56 | |||
57 | dur = icaldurationtype_null_duration(); | ||
58 | |||
59 | if(t < 0){ | ||
60 | dur.is_neg = 1; | ||
61 | t = -t; | ||
62 | } | ||
63 | |||
64 | if (t % (60 * 60 * 24 * 7) == 0) { | ||
65 | dur.weeks = t / (60 * 60 * 24 * 7); | ||
66 | } else { | ||
67 | used += dur.weeks * (60 * 60 * 24 * 7); | ||
68 | dur.days = (t - used) / (60 * 60 * 24); | ||
69 | used += dur.days * (60 * 60 * 24); | ||
70 | dur.hours = (t - used) / (60 * 60); | ||
71 | used += dur.hours * (60 * 60); | ||
72 | dur.minutes = (t - used) / (60); | ||
73 | used += dur.minutes * (60); | ||
74 | dur.seconds = (t - used); | ||
75 | } | ||
76 | |||
77 | return dur; | ||
78 | } | ||
79 | |||
80 | #ifndef ICAL_NO_LIBICAL | ||
81 | #include "icalvalue.h" | ||
82 | struct icaldurationtype icaldurationtype_from_string(const char* str) | ||
83 | { | ||
84 | |||
85 | int i; | ||
86 | int begin_flag = 0; | ||
87 | int time_flag = 0; | ||
88 | int date_flag = 0; | ||
89 | int week_flag = 0; | ||
90 | int digits=-1; | ||
91 | int scan_size = -1; | ||
92 | int size = strlen(str); | ||
93 | char p; | ||
94 | struct icaldurationtype d; | ||
95 | |||
96 | memset(&d, 0, sizeof(struct icaldurationtype)); | ||
97 | |||
98 | for(i=0;i != size;i++){ | ||
99 | p = str[i]; | ||
100 | |||
101 | switch(p) | ||
102 | { | ||
103 | case '-': { | ||
104 | if(i != 0 || begin_flag == 1) goto error; | ||
105 | |||
106 | d.is_neg = 1; | ||
107 | break; | ||
108 | } | ||
109 | |||
110 | case 'P': { | ||
111 | if (i != 0 && i !=1 ) goto error; | ||
112 | begin_flag = 1; | ||
113 | break; | ||
114 | } | ||
115 | |||
116 | case 'T': { | ||
117 | time_flag = 1; | ||
118 | break; | ||
119 | } | ||
120 | |||
121 | case '0': | ||
122 | case '1': | ||
123 | case '2': | ||
124 | case '3': | ||
125 | case '4': | ||
126 | case '5': | ||
127 | case '6': | ||
128 | case '7': | ||
129 | case '8': | ||
130 | case '9': | ||
131 | { | ||
132 | |||
133 | /* HACK. Skip any more digits if the l;ast one | ||
134 | read has not been assigned */ | ||
135 | if(digits != -1){ | ||
136 | break; | ||
137 | } | ||
138 | |||
139 | if (begin_flag == 0) goto error; | ||
140 | /* Get all of the digits, not one at a time */ | ||
141 | scan_size = sscanf((char*)(str+i),"%d",&digits); | ||
142 | if(scan_size == 0) goto error; | ||
143 | break; | ||
144 | } | ||
145 | |||
146 | case 'H': { | ||
147 | if (time_flag == 0||week_flag == 1||d.hours !=0||digits ==-1) | ||
148 | goto error; | ||
149 | d.hours = digits; digits = -1; | ||
150 | break; | ||
151 | } | ||
152 | case 'M': { | ||
153 | if (time_flag == 0||week_flag==1||d.minutes != 0||digits ==-1) | ||
154 | goto error; | ||
155 | d.minutes = digits; digits = -1; | ||
156 | break; | ||
157 | } | ||
158 | case 'S': { | ||
159 | if (time_flag == 0||week_flag==1||d.seconds!=0||digits ==-1) | ||
160 | goto error; | ||
161 | d.seconds = digits; digits = -1; | ||
162 | break; | ||
163 | } | ||
164 | case 'W': { | ||
165 | if (time_flag==1||date_flag==1||d.weeks!=0||digits ==-1) | ||
166 | goto error; | ||
167 | week_flag = 1; | ||
168 | d.weeks = digits; digits = -1; | ||
169 | break; | ||
170 | } | ||
171 | case 'D': { | ||
172 | if (time_flag==1||week_flag==1||d.days!=0||digits ==-1) | ||
173 | goto error; | ||
174 | date_flag = 1; | ||
175 | d.days = digits; digits = -1; | ||
176 | break; | ||
177 | } | ||
178 | default: { | ||
179 | goto error; | ||
180 | } | ||
181 | |||
182 | } | ||
183 | } | ||
184 | |||
185 | return d; | ||
186 | |||
187 | |||
188 | error: | ||
189 | icalerror_set_errno(ICAL_MALFORMEDDATA_ERROR); | ||
190 | memset(&d, 0, sizeof(struct icaldurationtype)); | ||
191 | return d; | ||
192 | |||
193 | } | ||
194 | |||
195 | #define TMP_BUF_SIZE 1024 | ||
196 | void append_duration_segment(char** buf, char** buf_ptr, size_t* buf_size, | ||
197 | char* sep, unsigned int value) { | ||
198 | |||
199 | char temp[TMP_BUF_SIZE]; | ||
200 | |||
201 | sprintf(temp,"%d",value); | ||
202 | |||
203 | icalmemory_append_string(buf, buf_ptr, buf_size, temp); | ||
204 | icalmemory_append_string(buf, buf_ptr, buf_size, sep); | ||
205 | |||
206 | } | ||
207 | |||
208 | char* icaldurationtype_as_ical_string(struct icaldurationtype d) | ||
209 | { | ||
210 | |||
211 | char *buf, *output_line; | ||
212 | size_t buf_size = 256; | ||
213 | char* buf_ptr = 0; | ||
214 | int seconds; | ||
215 | |||
216 | buf = (char*)icalmemory_new_buffer(buf_size); | ||
217 | buf_ptr = buf; | ||
218 | |||
219 | |||
220 | seconds = icaldurationtype_as_int(d); | ||
221 | |||
222 | if(seconds !=0){ | ||
223 | |||
224 | if(d.is_neg == 1){ | ||
225 | icalmemory_append_char(&buf, &buf_ptr, &buf_size, '-'); | ||
226 | } | ||
227 | |||
228 | icalmemory_append_char(&buf, &buf_ptr, &buf_size, 'P'); | ||
229 | |||
230 | if (d.weeks != 0 ) { | ||
231 | append_duration_segment(&buf, &buf_ptr, &buf_size, "W", d.weeks); | ||
232 | } | ||
233 | |||
234 | if (d.days != 0 ) { | ||
235 | append_duration_segment(&buf, &buf_ptr, &buf_size, "D", d.days); | ||
236 | } | ||
237 | |||
238 | if (d.hours != 0 || d.minutes != 0 || d.seconds != 0) { | ||
239 | |||
240 | icalmemory_append_string(&buf, &buf_ptr, &buf_size, "T"); | ||
241 | |||
242 | if (d.hours != 0 ) { | ||
243 | append_duration_segment(&buf, &buf_ptr, &buf_size, "H", d.hours); | ||
244 | } | ||
245 | if (d.minutes != 0 ) { | ||
246 | append_duration_segment(&buf, &buf_ptr, &buf_size, "M", | ||
247 | d.minutes); | ||
248 | } | ||
249 | if (d.seconds != 0 ) { | ||
250 | append_duration_segment(&buf, &buf_ptr, &buf_size, "S", | ||
251 | d.seconds); | ||
252 | } | ||
253 | |||
254 | } | ||
255 | } else { | ||
256 | icalmemory_append_string(&buf, &buf_ptr, &buf_size, "PTS0"); | ||
257 | } | ||
258 | |||
259 | output_line = icalmemory_tmp_copy(buf); | ||
260 | icalmemory_free_buffer(buf); | ||
261 | |||
262 | return output_line; | ||
263 | |||
264 | } | ||
265 | |||
266 | #endif | ||
267 | |||
268 | |||
269 | /* From Russel Steinthal */ | ||
270 | int icaldurationtype_as_int(struct icaldurationtype dur) | ||
271 | { | ||
272 | return (int)( (dur.seconds + | ||
273 | (60 * dur.minutes) + | ||
274 | (60 * 60 * dur.hours) + | ||
275 | (60 * 60 * 24 * dur.days) + | ||
276 | (60 * 60 * 24 * 7 * dur.weeks)) | ||
277 | * (dur.is_neg==1? -1 : 1) ) ; | ||
278 | } | ||
279 | |||
280 | struct icaldurationtype icaldurationtype_null_duration() | ||
281 | { | ||
282 | struct icaldurationtype d; | ||
283 | |||
284 | memset(&d,0,sizeof(struct icaldurationtype)); | ||
285 | |||
286 | return d; | ||
287 | } | ||
288 | |||
289 | int icaldurationtype_is_null_duration(struct icaldurationtype d) | ||
290 | { | ||
291 | if(icaldurationtype_as_int(d) == 0){ | ||
292 | return 1; | ||
293 | } else { | ||
294 | return 0; | ||
295 | } | ||
296 | } | ||
297 | |||
298 | |||
299 | |||
300 | struct icaltimetype icaltime_add(struct icaltimetype t, | ||
301 | struct icaldurationtype d) | ||
302 | { | ||
303 | int dt = icaldurationtype_as_int(d); | ||
304 | |||
305 | t.second += dt; | ||
306 | |||
307 | t = icaltime_normalize(t); | ||
308 | |||
309 | return t; | ||
310 | } | ||
311 | |||
312 | struct icaldurationtype icaltime_subtract(struct icaltimetype t1, | ||
313 | struct icaltimetype t2) | ||
314 | { | ||
315 | |||
316 | time_t t1t = icaltime_as_timet(t1); | ||
317 | time_t t2t = icaltime_as_timet(t2); | ||
318 | |||
319 | return icaldurationtype_from_int(t1t-t2t); | ||
320 | |||
321 | |||
322 | } | ||
323 | |||