root/Mulberry/branches/users/shared/externals/v4.1d1/CICalendar/Source/CICalendarProperty.cpp @ 329

Revision 329, 19.8 kB (checked in by svnusers, 6 months ago)

md: merged in revisions 318..326 from Kenneth's branch, added path to XMLLib to Makefile.in for CICalendar build, reverted some of Kenneth's changes in Libraries/CICalendar

Line 
1/*
2    Copyright (c) 2007 Cyrus Daboo. All rights reserved.
3   
4    Licensed under the Apache License, Version 2.0 (the "License");
5    you may not use this file except in compliance with the License.
6    You may obtain a copy of the License at
7   
8        http://www.apache.org/licenses/LICENSE-2.0
9   
10    Unless required by applicable law or agreed to in writing, software
11    distributed under the License is distributed on an "AS IS" BASIS,
12    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13    See the License for the specific language governing permissions and
14    limitations under the License.
15*/
16
17/*
18        CICalendarProperty.cpp
19
20        Author:
21        Description:    <describe the CICalendarProperty class here>
22*/
23
24#include "CICalendarProperty.h"
25
26#include "CICalendarCalAddressValue.h"
27#include "CICalendarDateTimeValue.h"
28#include "CICalendarDefinitions.h"
29#include "CICalendarDurationValue.h"
30#include "CICalendarIntegerValue.h"
31#include "CICalendarMultiValue.h"
32#include "CICalendarPeriodValue.h"
33#include "CICalendarPlainTextValue.h"
34#include "CICalendarRecurrenceValue.h"
35#include "CICalendarURIValue.h"
36#include "CICalendarUTCOffsetValue.h"
37#include "CICalendarValue.h"
38#include "CStringUtils.h"
39
40#include <iostream>
41#include <memory>
42#include <strstream>
43
44using namespace iCal;
45
46CICalendarProperty::CValueTypeMap CICalendarProperty::sDefaultValueTypeMap;
47CICalendarProperty::CValueTypeMap CICalendarProperty::sValueTypeMap;
48CICalendarProperty::CTypeValueMap CICalendarProperty::sTypeValueMap;
49CICalendarProperty::CMultiValues CICalendarProperty::sMultiValues;
50
51void CICalendarProperty::_init_attr_value(const int32_t& ival)
52{
53        // Value
54        mValue = new CICalendarIntegerValue(ival);
55
56        // Attributes
57        SetupValueAttribute();
58}
59
60void CICalendarProperty::_init_attr_value(const cdstring& txt, CICalendarValue::EICalValueType value_type)
61{
62        // Value
63        mValue = CICalendarValue::CreateFromType(value_type);
64        CICalendarPlainTextValue* tvalue = dynamic_cast<CICalendarPlainTextValue*>(mValue);
65        if (tvalue != NULL)
66                tvalue->SetValue(txt);
67
68        // Attributes
69        SetupValueAttribute();
70}
71
72void CICalendarProperty::_init_attr_value(const CICalendarDateTime& dt)
73{
74        // Value
75        mValue = new CICalendarDateTimeValue(dt);
76
77        // Attributes
78        SetupValueAttribute();
79       
80        // Look for timezone
81        if (!dt.IsDateOnly() && !dt.GetTimezone().GetUTC() && !dt.GetTimezone().GetTimezoneID().empty())
82        {
83                mAttributes.erase(cICalAttribute_TZID);
84                mAttributes.insert(CICalendarAttributeMap::value_type(cICalAttribute_TZID, CICalendarAttribute(cICalAttribute_TZID, dt.GetTimezone().GetTimezoneID())));
85        }
86}
87
88void CICalendarProperty::_init_attr_value(const CICalendarDateTimeList& dtl)
89{
90        // Value
91        mValue = new CICalendarMultiValue((dtl.size() > 0) && dtl.front().IsDateOnly() ? CICalendarValue::eValueType_Date : CICalendarValue::eValueType_DateTime);
92        for(CICalendarDateTimeList::const_iterator iter = dtl.begin(); iter != dtl.end(); iter++)
93        {
94                static_cast<CICalendarMultiValue*>(mValue)->AddValue(new CICalendarDateTimeValue(*iter));
95        }
96
97        // Attributes
98        SetupValueAttribute();
99       
100        // Look for timezone
101        if ((dtl.size() > 0) && !dtl.front().IsDateOnly() && !dtl.front().GetTimezone().GetUTC() && !dtl.front().GetTimezone().GetTimezoneID().empty())
102        {
103                mAttributes.erase(cICalAttribute_TZID);
104                mAttributes.insert(CICalendarAttributeMap::value_type(cICalAttribute_TZID, CICalendarAttribute(cICalAttribute_TZID, dtl.front().GetTimezone().GetTimezoneID())));
105        }
106}
107
108void CICalendarProperty::_init_attr_value(const CICalendarDuration& du)
109{
110        // Value
111        mValue = new CICalendarDurationValue(du);
112
113        // Attributes
114        SetupValueAttribute();
115}
116
117void CICalendarProperty::_init_attr_value(const CICalendarPeriod& pe)
118{
119        // Value
120        mValue = new CICalendarPeriodValue(pe);
121
122        // Attributes
123        SetupValueAttribute();
124}
125
126void CICalendarProperty::_init_attr_value(const CICalendarRecurrence& recur)
127{
128        // Value
129        mValue = new CICalendarRecurrenceValue(recur);
130
131        // Attributes
132        SetupValueAttribute();
133}
134
135void CICalendarProperty::_init_map()
136{
137        // Only if empty
138        if (sDefaultValueTypeMap.empty())
139        {
140                // 2445 4.8.1
141                sDefaultValueTypeMap.insert(CValueTypeMap::value_type(cICalProperty_ATTACH, CICalendarValue::eValueType_URI));
142                sDefaultValueTypeMap.insert(CValueTypeMap::value_type(cICalProperty_CATEGORIES, CICalendarValue::eValueType_Text));
143                sDefaultValueTypeMap.insert(CValueTypeMap::value_type(cICalProperty_CLASS, CICalendarValue::eValueType_Text));
144                sDefaultValueTypeMap.insert(CValueTypeMap::value_type(cICalProperty_COMMENT, CICalendarValue::eValueType_Text));
145                sDefaultValueTypeMap.insert(CValueTypeMap::value_type(cICalProperty_DESCRIPTION, CICalendarValue::eValueType_Text));
146                sDefaultValueTypeMap.insert(CValueTypeMap::value_type(cICalProperty_GEO, CICalendarValue::eValueType_Geo));
147                sDefaultValueTypeMap.insert(CValueTypeMap::value_type(cICalProperty_LOCATION, CICalendarValue::eValueType_Text));
148                sDefaultValueTypeMap.insert(CValueTypeMap::value_type(cICalProperty_PERCENT_COMPLETE, CICalendarValue::eValueType_Integer));
149                sDefaultValueTypeMap.insert(CValueTypeMap::value_type(cICalProperty_PRIORITY, CICalendarValue::eValueType_Integer));
150                sDefaultValueTypeMap.insert(CValueTypeMap::value_type(cICalProperty_RESOURCES, CICalendarValue::eValueType_Text));
151                sDefaultValueTypeMap.insert(CValueTypeMap::value_type(cICalProperty_STATUS, CICalendarValue::eValueType_Text));
152                sDefaultValueTypeMap.insert(CValueTypeMap::value_type(cICalProperty_SUMMARY, CICalendarValue::eValueType_Text));
153
154                // 2445 4.8.2
155                sDefaultValueTypeMap.insert(CValueTypeMap::value_type(cICalProperty_COMPLETED, CICalendarValue::eValueType_DateTime));
156                sDefaultValueTypeMap.insert(CValueTypeMap::value_type(cICalProperty_DTEND, CICalendarValue::eValueType_DateTime));
157                sDefaultValueTypeMap.insert(CValueTypeMap::value_type(cICalProperty_DUE, CICalendarValue::eValueType_DateTime));
158                sDefaultValueTypeMap.insert(CValueTypeMap::value_type(cICalProperty_DTSTART, CICalendarValue::eValueType_DateTime));
159                sDefaultValueTypeMap.insert(CValueTypeMap::value_type(cICalProperty_DURATION, CICalendarValue::eValueType_Duration));
160                sDefaultValueTypeMap.insert(CValueTypeMap::value_type(cICalProperty_FREEBUSY, CICalendarValue::eValueType_Period));
161                sDefaultValueTypeMap.insert(CValueTypeMap::value_type(cICalProperty_TRANSP, CICalendarValue::eValueType_Text));
162
163                // 2445 4.8.3
164                sDefaultValueTypeMap.insert(CValueTypeMap::value_type(cICalProperty_TZID, CICalendarValue::eValueType_Text));
165                sDefaultValueTypeMap.insert(CValueTypeMap::value_type(cICalProperty_TZNAME, CICalendarValue::eValueType_Text));
166                sDefaultValueTypeMap.insert(CValueTypeMap::value_type(cICalProperty_TZOFFSETFROM, CICalendarValue::eValueType_UTC_Offset));
167                sDefaultValueTypeMap.insert(CValueTypeMap::value_type(cICalProperty_TZOFFSETTO, CICalendarValue::eValueType_UTC_Offset));
168                sDefaultValueTypeMap.insert(CValueTypeMap::value_type(cICalProperty_TZURL, CICalendarValue::eValueType_URI));
169
170                // 2445 4.8.4
171                sDefaultValueTypeMap.insert(CValueTypeMap::value_type(cICalProperty_ATTENDEE, CICalendarValue::eValueType_CalAddress));
172                sDefaultValueTypeMap.insert(CValueTypeMap::value_type(cICalProperty_CONTACT, CICalendarValue::eValueType_Text));
173                sDefaultValueTypeMap.insert(CValueTypeMap::value_type(cICalProperty_ORGANIZER, CICalendarValue::eValueType_CalAddress));
174                sDefaultValueTypeMap.insert(CValueTypeMap::value_type(cICalProperty_RECURRENCE_ID, CICalendarValue::eValueType_DateTime));
175                sDefaultValueTypeMap.insert(CValueTypeMap::value_type(cICalProperty_RELATED_TO, CICalendarValue::eValueType_Text));
176                sDefaultValueTypeMap.insert(CValueTypeMap::value_type(cICalProperty_URL, CICalendarValue::eValueType_URI));
177                sDefaultValueTypeMap.insert(CValueTypeMap::value_type(cICalProperty_UID, CICalendarValue::eValueType_Text));
178
179                // 2445 4.8.5
180                sDefaultValueTypeMap.insert(CValueTypeMap::value_type(cICalProperty_EXDATE, CICalendarValue::eValueType_DateTime));
181                sDefaultValueTypeMap.insert(CValueTypeMap::value_type(cICalProperty_EXRULE, CICalendarValue::eValueType_Recur));
182                sDefaultValueTypeMap.insert(CValueTypeMap::value_type(cICalProperty_RDATE, CICalendarValue::eValueType_DateTime));
183                sDefaultValueTypeMap.insert(CValueTypeMap::value_type(cICalProperty_RRULE, CICalendarValue::eValueType_Recur));
184
185                // 2445 4.8.6
186                sDefaultValueTypeMap.insert(CValueTypeMap::value_type(cICalProperty_ACTION, CICalendarValue::eValueType_Text));
187                sDefaultValueTypeMap.insert(CValueTypeMap::value_type(cICalProperty_REPEAT, CICalendarValue::eValueType_Integer));
188                sDefaultValueTypeMap.insert(CValueTypeMap::value_type(cICalProperty_TRIGGER, CICalendarValue::eValueType_Duration));
189
190                // 2445 4.8.7
191                sDefaultValueTypeMap.insert(CValueTypeMap::value_type(cICalProperty_CREATED, CICalendarValue::eValueType_DateTime));
192                sDefaultValueTypeMap.insert(CValueTypeMap::value_type(cICalProperty_DTSTAMP, CICalendarValue::eValueType_DateTime));
193                sDefaultValueTypeMap.insert(CValueTypeMap::value_type(cICalProperty_LAST_MODIFIED, CICalendarValue::eValueType_DateTime));
194                sDefaultValueTypeMap.insert(CValueTypeMap::value_type(cICalProperty_SEQUENCE, CICalendarValue::eValueType_Integer));
195               
196                // Apple Extensions
197                sDefaultValueTypeMap.insert(CValueTypeMap::value_type(cICalProperty_XWRCALNAME, CICalendarValue::eValueType_Text));
198                sDefaultValueTypeMap.insert(CValueTypeMap::value_type(cICalProperty_XWRCALDESC, CICalendarValue::eValueType_Text));
199               
200                // Mulberry extensions
201                sDefaultValueTypeMap.insert(CValueTypeMap::value_type(cICalProperty_X_PRIVATE_RURL, CICalendarValue::eValueType_Text));
202                sDefaultValueTypeMap.insert(CValueTypeMap::value_type(cICalProperty_X_PRIVATE_ETAG, CICalendarValue::eValueType_Text));
203                sDefaultValueTypeMap.insert(CValueTypeMap::value_type(cICalProperty_ACTION_X_SPEAKTEXT, CICalendarValue::eValueType_Text));
204                sDefaultValueTypeMap.insert(CValueTypeMap::value_type(cICalProperty_ALARM_X_LASTTRIGGER, CICalendarValue::eValueType_DateTime));
205                sDefaultValueTypeMap.insert(CValueTypeMap::value_type(cICalProperty_ALARM_X_ALARMSTATUS, CICalendarValue::eValueType_Text));
206        }
207
208        // Only if empty
209        if (sValueTypeMap.empty())
210        {
211                // 2445 4.3
212                sValueTypeMap.insert(CValueTypeMap::value_type(cICalValue_BINARY, CICalendarValue::eValueType_Binary));
213                sValueTypeMap.insert(CValueTypeMap::value_type(cICalValue_BOOLEAN, CICalendarValue::eValueType_Boolean));
214                sValueTypeMap.insert(CValueTypeMap::value_type(cICalValue_CAL_ADDRESS, CICalendarValue::eValueType_CalAddress));
215                sValueTypeMap.insert(CValueTypeMap::value_type(cICalValue_DATE, CICalendarValue::eValueType_Date));
216                sValueTypeMap.insert(CValueTypeMap::value_type(cICalValue_DATE_TIME, CICalendarValue::eValueType_DateTime));
217                sValueTypeMap.insert(CValueTypeMap::value_type(cICalValue_DURATION, CICalendarValue::eValueType_Duration));
218                sValueTypeMap.insert(CValueTypeMap::value_type(cICalValue_FLOAT, CICalendarValue::eValueType_Float));
219                sValueTypeMap.insert(CValueTypeMap::value_type(cICalValue_INTEGER, CICalendarValue::eValueType_Integer));
220                sValueTypeMap.insert(CValueTypeMap::value_type(cICalValue_PERIOD, CICalendarValue::eValueType_Period));
221                sValueTypeMap.insert(CValueTypeMap::value_type(cICalValue_RECUR, CICalendarValue::eValueType_Recur));
222                sValueTypeMap.insert(CValueTypeMap::value_type(cICalValue_TEXT, CICalendarValue::eValueType_Text));
223                sValueTypeMap.insert(CValueTypeMap::value_type(cICalValue_TIME, CICalendarValue::eValueType_Time));
224                sValueTypeMap.insert(CValueTypeMap::value_type(cICalValue_URI, CICalendarValue::eValueType_URI));
225                sValueTypeMap.insert(CValueTypeMap::value_type(cICalValue_UTC_OFFSET, CICalendarValue::eValueType_UTC_Offset));
226
227        }
228
229        if (sTypeValueMap.empty())
230        {
231                // 2445 4.3
232                sTypeValueMap.insert(CTypeValueMap::value_type(CICalendarValue::eValueType_Binary, cICalValue_BINARY));
233                sTypeValueMap.insert(CTypeValueMap::value_type(CICalendarValue::eValueType_Boolean, cICalValue_BOOLEAN));
234                sTypeValueMap.insert(CTypeValueMap::value_type(CICalendarValue::eValueType_CalAddress, cICalValue_CAL_ADDRESS));
235                sTypeValueMap.insert(CTypeValueMap::value_type(CICalendarValue::eValueType_Date, cICalValue_DATE));
236                sTypeValueMap.insert(CTypeValueMap::value_type(CICalendarValue::eValueType_DateTime, cICalValue_DATE_TIME));
237                sTypeValueMap.insert(CTypeValueMap::value_type(CICalendarValue::eValueType_Duration, cICalValue_DURATION));
238                sTypeValueMap.insert(CTypeValueMap::value_type(CICalendarValue::eValueType_Float, cICalValue_FLOAT));
239                sTypeValueMap.insert(CTypeValueMap::value_type(CICalendarValue::eValueType_Geo, cICalValue_FLOAT));
240                sTypeValueMap.insert(CTypeValueMap::value_type(CICalendarValue::eValueType_Integer, cICalValue_INTEGER));
241                sTypeValueMap.insert(CTypeValueMap::value_type(CICalendarValue::eValueType_Period, cICalValue_PERIOD));
242                sTypeValueMap.insert(CTypeValueMap::value_type(CICalendarValue::eValueType_Recur, cICalValue_RECUR));
243                sTypeValueMap.insert(CTypeValueMap::value_type(CICalendarValue::eValueType_Text, cICalValue_TEXT));
244                sTypeValueMap.insert(CTypeValueMap::value_type(CICalendarValue::eValueType_Time, cICalValue_TIME));
245                sTypeValueMap.insert(CTypeValueMap::value_type(CICalendarValue::eValueType_URI, cICalValue_URI));
246                sTypeValueMap.insert(CTypeValueMap::value_type(CICalendarValue::eValueType_UTC_Offset, cICalValue_UTC_OFFSET));
247
248        }
249
250        if (sMultiValues.empty())
251        {
252                sMultiValues.insert(cICalProperty_CATEGORIES);
253                sMultiValues.insert(cICalProperty_RESOURCES);
254                sMultiValues.insert(cICalProperty_FREEBUSY);
255                sMultiValues.insert(cICalProperty_EXDATE);
256                sMultiValues.insert(cICalProperty_RDATE);
257        }
258}
259
260void CICalendarProperty::AddAttribute(const CICalendarAttribute& attr)
261{
262        mAttributes.insert(CICalendarAttributeMap::value_type(attr.GetName(), attr));
263}
264
265void CICalendarProperty::RemoveAttributes(const cdstring& attr)
266{
267        mAttributes.erase(attr);
268}
269
270const CICalendarCalAddressValue* CICalendarProperty::GetCalAddressValue() const
271{
272        return dynamic_cast<CICalendarCalAddressValue*>(mValue);
273}
274
275const CICalendarDateTimeValue* CICalendarProperty::GetDateTimeValue() const
276{
277        return dynamic_cast<CICalendarDateTimeValue*>(mValue);
278}
279
280const CICalendarDurationValue* CICalendarProperty::GetDurationValue() const
281{
282        return dynamic_cast<CICalendarDurationValue*>(mValue);
283}
284
285const CICalendarIntegerValue* CICalendarProperty::GetIntegerValue() const
286{
287        return dynamic_cast<CICalendarIntegerValue*>(mValue);
288}
289
290const CICalendarMultiValue* CICalendarProperty::GetMultiValue() const
291{
292        return dynamic_cast<CICalendarMultiValue*>(mValue);
293}
294
295const CICalendarPeriodValue* CICalendarProperty::GetPeriodValue() const
296{
297        return dynamic_cast<CICalendarPeriodValue*>(mValue);
298}
299
300const CICalendarRecurrenceValue* CICalendarProperty::GetRecurrenceValue() const
301{
302        return dynamic_cast<CICalendarRecurrenceValue*>(mValue);
303}
304
305const CICalendarPlainTextValue* CICalendarProperty::GetTextValue() const
306{
307        return dynamic_cast<CICalendarPlainTextValue*>(mValue);
308}
309
310const CICalendarURIValue* CICalendarProperty::GetURIValue() const
311{
312        return dynamic_cast<CICalendarURIValue*>(mValue);
313}
314
315const CICalendarUTCOffsetValue* CICalendarProperty::GetUTCOffsetValue() const
316{
317        return dynamic_cast<CICalendarUTCOffsetValue*>(mValue);
318}
319
320bool CICalendarProperty::Parse(cdstring& data)
321{
322        char* p = const_cast<char*>(data.c_str());
323
324        // Look for attribute or value delimiter
325        {
326                std::auto_ptr<char> prop_name(::strduptokenstr(&p, ";:"));
327                if ((prop_name.get() == NULL) || (*p == 0))
328                        return false;
329
330                // We have the name
331                mName.assign(prop_name.get());
332        }
333
334        // Now loop getting data
335        bool done = false;
336        while(!done && (*p != 0))
337        {
338                switch(*p)
339                {
340                case ';':
341                        // Parse attribute
342                        {
343                                // Move past delimiter
344                                p++;
345
346                                // Get quoted string or token
347                                std::auto_ptr<char> attribute_name(::strduptokenstr(&p, "="));
348                                if (attribute_name.get() == NULL)
349                                        return false;
350                                p++;
351                                std::auto_ptr<char> attribute_value(::strduptokenstr(&p, ":;,"));
352                                // CD: parameter values can be empty
353                                //if (attribute_value.get() == NULL)
354                                //      return false;
355
356                                // Now add attribute value
357                                CICalendarAttribute attrvalue(attribute_name.get(), attribute_value.get());
358                                mAttributes.insert(CICalendarAttributeMap::value_type(attrvalue.GetName(), attrvalue));
359
360                                // Look for additional values
361                                while(*p == ',')
362                                {
363                                        p++;
364                                        std::auto_ptr<char> attribute_value2(::strduptokenstr(&p, ":;,"));
365                                        if (attribute_value2.get() != NULL)
366                                                attrvalue.AddValue(attribute_value2.get());
367                                }
368                        }
369                        break;
370                case ':':
371                        CreateValue(p + 1);
372                        done = true;
373                        break;
374                default:;
375                }
376        }
377       
378        // We must have a value of some kind
379        return (mValue != NULL);
380}
381
382void CICalendarProperty::CreateValue(const char* data)
383{
384        // Tidy first
385        delete mValue;
386        mValue = NULL;
387
388        // Get value type from property name
389        CICalendarValue::EICalValueType type = CICalendarValue::eValueType_Text;
390        _init_map();
391        CValueTypeMap::const_iterator found = sDefaultValueTypeMap.find(mName);
392        if (found != sDefaultValueTypeMap.end())
393                type = (*found).second;
394
395        // Check whether custom value is set
396        if (mAttributes.count(cICalAttribute_VALUE))
397        {
398                CValueTypeMap::const_iterator found = sValueTypeMap.find(GetAttributeValue(cICalAttribute_VALUE));
399                if (found != sValueTypeMap.end())
400                        type = (*found).second;
401        }
402
403        // Check for multivalued
404        if (sMultiValues.count(mName))
405        {
406                mValue = new CICalendarMultiValue(type);
407        }
408        else
409        {
410                // Create the type
411                mValue = CICalendarValue::CreateFromType(type);
412        }
413
414        // Now parse the data
415        mValue->Parse(data);
416
417        // Special post-create for some types
418        switch(type)
419        {
420        case CICalendarValue::eValueType_Time:
421        case CICalendarValue::eValueType_DateTime:
422        {
423                // Look for TZID attribute
424                cdstring tzid;
425                if (HasAttribute(cICalAttribute_TZID))
426                {
427                        tzid = GetAttributeValue(cICalAttribute_TZID);
428                }
429               
430                if (dynamic_cast<CICalendarDateTimeValue*>(mValue) != NULL)
431                        static_cast<CICalendarDateTimeValue*>(mValue)->GetValue().GetTimezone().SetTimezoneID(tzid);
432                else if (dynamic_cast<CICalendarMultiValue*>(mValue) != NULL)
433                {
434                        for(CICalendarValueList::iterator iter = static_cast<CICalendarMultiValue*>(mValue)->GetValues().begin(); iter != static_cast<CICalendarMultiValue*>(mValue)->GetValues().end(); iter++)
435                        {
436                                if (dynamic_cast<CICalendarDateTimeValue*>(*iter) != NULL)
437                                        static_cast<CICalendarDateTimeValue*>(*iter)->GetValue().GetTimezone().SetTimezoneID(tzid);
438                        }
439                }
440                break;
441        }
442        default:;
443        }
444}
445
446// Make sure current VALUE= attribute matches the actual data we have
447// or is absent if default value
448void CICalendarProperty::SetupValueAttribute()
449{
450        mAttributes.erase(cICalAttribute_VALUE);
451
452        // Only if we have a value right now
453        if (mValue == NULL)
454                return;
455
456        // See if current type is default for this property
457        _init_map();
458        CValueTypeMap::const_iterator found = sDefaultValueTypeMap.find(mName);
459        if (found != sDefaultValueTypeMap.end())
460        {
461                CICalendarValue::EICalValueType default_type = (*found).second;
462                if (default_type != mValue->GetType())
463                {
464                        CTypeValueMap::const_iterator found2 = sTypeValueMap.find(mValue->GetType());
465                        if (found2 != sTypeValueMap.end())
466                        {
467                                mAttributes.insert(CICalendarAttributeMap::value_type(cICalAttribute_VALUE, CICalendarAttribute(cICalAttribute_VALUE, (*found2).second)));
468                        }
469                }
470        }
471}
472
473void CICalendarProperty::Generate(std::ostream& os) const
474{
475        const_cast<CICalendarProperty*>(this)->SetupValueAttribute();
476
477        // Must write to temp buffer and then wrap
478        std::ostrstream sout;
479       
480        sout << mName;
481
482        // Write all attributes
483        for(CICalendarAttributeMap::const_iterator iter = mAttributes.begin(); iter != mAttributes.end(); iter++)
484        {
485                sout << ";";
486                (*iter).second.Generate(sout);
487        }
488
489        // Write value
490        sout << ":";
491        if (mValue)
492                mValue->Generate(sout);
493       
494        sout << std::ends;
495        cdstring temp;
496        temp.steal(sout.str());
497        if (temp.length() < 75)
498                os << temp.c_str();
499        else
500        {
501                const char* p = temp.c_str();
502                const char* q = p + temp.length();
503                while(p < q)
504                {
505                        if (p != temp.c_str())
506                        {
507                                os << net_endl << " ";
508                        }
509
510                        int bytes = q - p;
511                        if (bytes > 74)
512                        {
513                                bytes = 74;
514                               
515                                // Make sure we do not split in the middle of a utf-8 multi-octet sequence
516                                unsigned char* up = (unsigned char*) p;
517                                while((up[bytes] > 0x7F) && ((up[bytes] & 0xC0) == 0x80))
518                                        bytes--;
519                        }
520                        os.write(p, bytes);
521                        p += bytes;
522                }
523        }
524
525        os << net_endl;
526}
Note: See TracBrowser for help on using the browser.