summaryrefslogtreecommitdiffabout
path: root/libical/src/libical/icalduration.c
Unidiff
Diffstat (limited to 'libical/src/libical/icalduration.c') (more/less context) (ignore whitespace changes)
-rw-r--r--libical/src/libical/icalduration.c323
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> */
52struct 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"
82struct 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
196void 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
208char* 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 */
270int 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
280struct icaldurationtype icaldurationtype_null_duration()
281{
282 struct icaldurationtype d;
283
284 memset(&d,0,sizeof(struct icaldurationtype));
285
286 return d;
287}
288
289int 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
300struct 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
312struct 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