winevent.cpp
来自「funambol window mobile客户端源代码」· C++ 代码 · 共 878 行 · 第 1/2 页
CPP
878 行
//
// Conversion: vObject -> WinEvent.
// --------------------------------
// Note: properties found are added to the propertyMap, so that the
// map will contain only parsed properties after this process.
//
if(element = getVObjectPropertyValue(vo, L"SUMMARY")) {
setProperty(L"Subject", element);
}
if(element = getVObjectPropertyValue(vo, L"LOCATION")) {
setProperty(L"Location", element);
}
if(element = getVObjectPropertyValue(vo, L"DESCRIPTION")) {
setProperty(L"Body", element);
}
if(element = getVObjectPropertyValue(vo, L"X-FUNAMBOL-FOLDER")) {
setProperty(L"Folder", element);
}
//
// DTSTART, DTEND:
// Set the start and end date. If the start is 00:00 and end is 23:59 the appointment is decided to be
// an all day event. So the AllDayEvent property is set to '1' in the propertyMap.
//
if(element = getVObjectPropertyValue(vo, L"DTSTART")){
startDateValue = element;
stringTimeToDouble(element, &startDate); // 'startDate' will be used also for RRULE parsing
}
if(element = getVObjectPropertyValue(vo, L"DTEND")) {
endDateValue = element;
stringTimeToDouble(element, &endDate);
}
if (startDate && endDate) {
// ALL-DAY EVENT
bool isAllDay = false;
if(element = getVObjectPropertyValue(vo, L"X-FUNAMBOL-ALLDAY")){
isAllDay = wcscmp(element, L"1")? false : true;
}
if (!isAllDay) {
// All-day check #2: interval [00:00 - 23:59]
isAllDay = isAllDayInterval(startDate, endDate);
}
if (!isAllDay) {
// All-day check #3: format "yyyyMMdd"
if (startDateValue.size() == 8 && endDateValue.size() == 8 ) {
isAllDay = true;
}
}
if (isAllDay) {
// Safe check on endDate: min value is 'startDate + 1'
if (endDate <= startDate) {
endDate = startDate + 1;
}
// for EndDates like "20071121T235900": we convert into "20071122"
double endDateTime = endDate - (int)endDate;
if (endDateTime > 0.9) {
endDate = (int)endDate + 1;
}
// Format dates like: "yyyyMMdd"
doubleToStringTime(endDateValue, endDate, true);
doubleToStringTime(startDateValue, startDate, true);
}
setProperty(L"Start", startDateValue );
setProperty(L"End", endDateValue );
setProperty(L"AllDayEvent", isAllDay? L"1" : L"0");
}
if(element = getVObjectPropertyValue(vo, L"X-MICROSOFT-CDO-BUSYSTATUS")) {
setProperty(L"BusyStatus", element);
}
if(element = getVObjectPropertyValue(vo, L"CATEGORIES")) {
setProperty(L"Categories", element);
}
if (element = getVObjectPropertyValue(vo, L"CLASS")) {
WCHAR tmp[10];
if (!wcscmp(element, TEXT("CONFIDENTIAL")) ) {
wsprintf(tmp, TEXT("%i"), winConfidential); // Confidential = 3
}
else if (!wcscmp(element, TEXT("PRIVATE")) ) {
wsprintf(tmp, TEXT("%i"), winPrivate); // Private = 2
}
else {
wsprintf(tmp, TEXT("%i"), winNormal); // Normal = 0
}
setProperty(L"Sensitivity", tmp);
}
if(element = getVObjectPropertyValue(vo, L"PRIORITY")) {
setProperty(L"Importance", element);
}
if(element = getVObjectPropertyValue(vo, L"STATUS")) {
setProperty(L"MeetingStatus", element);
}
if(element = getVObjectPropertyValue(vo, L"X-MICROSOFT-CDO-REPLYTIME")) {
setProperty(L"ReplyTime", element);
}
// AALARM
// The value consists of: RunTime, SnoozeTime, RepeatCount, AudioContent
if(element = getVObjectPropertyValue(vo, L"AALARM")) {
WCHAR tmp[10];
WCHAR* runTimeValue = vo->getProperty(TEXT("AALARM"))->getPropComponent(1);
if (wcslen(runTimeValue) > 0) {
setProperty(L"ReminderSet", L"1");
DATE runTime = 0;
stringTimeToDouble(runTimeValue, &runTime);
long minBeforeEvent = round((startDate - runTime) * 1440);
// Safety check: values < 0 not accepted.
if (minBeforeEvent < 0) {
minBeforeEvent = 0;
}
wsprintf(tmp, TEXT("%i"), minBeforeEvent);
setProperty(L"ReminderMinutesBeforeStart", tmp);
// Reminder sound file path
WCHAR* filePath = vo->getProperty(TEXT("AALARM"))->getPropComponent(4);
if (filePath && wcslen(filePath)>0) {
setProperty(L"ReminderSoundFile", filePath);
}
else {
setProperty(L"ReminderSoundFile", L"");
}
}
else {
// RunTime not found -> no reminder
setProperty(L"ReminderSet", L"0");
}
}
else {
// AALARM not found -> reset reminder!
// Note: this is done for compatibility with most devices: if alarm not set
// AALARM property is not sent.
setProperty(L"ReminderSet", L"0");
}
if ( (element = getVObjectPropertyValue(vo, L"RRULE")) &&
(wcslen(element) > 0) ) {
setProperty(L"IsRecurring", L"1");
// RRULE -> Recurrence pattern
// Fill recPattern propertyMap.
recPattern.setStartDate(startDate);
recPattern.parse(element);
// EXDATE -> fill excludeDate list
VProperty* vprop = vo->getProperty(L"EXDATE");
if(vprop) {
for (int i=0; element = vprop->getValue(i); i++) {
if (wcslen(element) > 0) {
excludeDate.push_back(element);
}
}
}
// RDATE -> fill includeDate list
vprop = vo->getProperty(L"RDATE");
if(vprop) {
for (int i=0; element = vprop->getValue(i); i++) {
if (wcslen(element) > 0) {
includeDate.push_back(element);
}
}
}
// TIMEZONE
bool tzFound = parseTimezone(vo);
useTimezone = tzFound;
getRecPattern()->setUseTimezone(tzFound);
}
else {
// Not recurring.
setProperty(L"IsRecurring", L"0");
}
//
// TODO: parse ATTENDEES and fill recipients list
//
//
// ---- Other Funambol defined properties ----
// Support for other fields that don't have a
// specific correspondence in vCalendar.
if (element = getVObjectPropertyValue(vo, L"X-FUNAMBOL-BILLINGINFO")) {
setProperty(TEXT("BillingInformation"), element);
}
if(element = getVObjectPropertyValue(vo, L"X-FUNAMBOL-COMPANIES")) {
setProperty(L"Companies", element);
}
if(element = getVObjectPropertyValue(vo, L"X-FUNAMBOL-MILEAGE")) {
setProperty(L"Mileage", element);
}
if(element = getVObjectPropertyValue(vo, L"X-FUNAMBOL-NOAGING")) {
setProperty(L"NoAging", element);
}
if(element = getVObjectPropertyValue(vo, L"X-FUNAMBOL-AALARMOPTIONS")) {
setProperty(L"ReminderOptions", element);
}
return 0;
}
// Utility to check the productID and version of VObject passed.
bool WinEvent::checkVCalendarTypeAndVersion(VObject* vo) {
WCHAR* prodID = vo->getProdID();
WCHAR* version = vo->getVersion();
if (!prodID) {
LOG.error(ERR_ITEM_VOBJ_TYPE_NOTFOUND, L"VCALENDAR");
return false;
}
if (wcscmp(prodID, L"VCALENDAR")) {
LOG.error(ERR_ITEM_VOBJ_WRONG_TYPE, prodID, L"VCALENDAR");
return false;
}
if (!version) {
// Just log a warning...
LOG.info(INFO_ITEM_VOBJ_VERSION_NOTFOUND, VCALENDAR_VERSION);
}
else if (wcscmp(version, VCALENDAR_VERSION)) {
// Just log a warning...
LOG.info(INFO_ITEM_VOBJ_WRONG_VERSION, version, VCALENDAR_VERSION);
}
return true;
}
WinRecurrence* WinEvent::getRecPattern() {
return &recPattern;
}
exceptionList* WinEvent::getExcludeDates() {
return &excludeDate;
}
exceptionList* WinEvent::getIncludeDates() {
return &includeDate;
}
recipientList* WinEvent::getRecipients() {
return &recipients;
}
const TIME_ZONE_INFORMATION* WinEvent::getTimezone() {
if (useTimezone) {
return &tzInfo;
}
return NULL;
}
void WinEvent::setTimezone(const TIME_ZONE_INFORMATION* tz) {
if (tz) {
// Copy all values.
tzInfo.Bias = tz->Bias;
tzInfo.DaylightBias = tz->DaylightBias;
tzInfo.DaylightDate = tz->DaylightDate;
tzInfo.StandardBias = tz->StandardBias;
tzInfo.StandardDate = tz->StandardDate;
//wsprintf(tzInfo.DaylightName, TEXT("%s"), tz->DaylightName);
//wsprintf(tzInfo.StandardName, TEXT("%s"), tz->StandardName);
wcsncpy(tzInfo.DaylightName, tz->DaylightName, 32);
wcsncpy(tzInfo.StandardName, tz->StandardName, 32);
// use the method, to access right specialized object.
WinRecurrence* rec = getRecPattern();
if (rec) { rec->setUseTimezone(true); }
useTimezone = true;
}
}
bool WinEvent::hasTimezone() {
return useTimezone;
}
bool WinEvent::parseTimezone(VObject* vo) {
bool found = false;
WCHAR* element = NULL;
if ((element = getVObjectPropertyValue(vo, L"TZ")) && wcslen(element) > 0) {
int bias = parseBias(element);
wstring dstFlag, dstOffset, standardName, daylightName;
list<wstring> daylightDates;
list<wstring> standardDates;
//
// Search all DAYLIGHT properties (one for every year)
//
for(int i=0; i < vo->propertiesCount(); i++) {
VProperty* vp = vo->getProperty(i);
if (!wcscmp(vp->getName(), TEXT("DAYLIGHT"))) {
// Found a DAYLIGHT property. Many props are redundant, now are overwritten.
if (element = vp->getPropComponent(1)) { dstFlag = element; }
if (element = vp->getPropComponent(2)) { dstOffset = element; }
if (element = vp->getPropComponent(3)) { daylightDates.push_back(element); }
if (element = vp->getPropComponent(4)) { standardDates.push_back(element); }
if (element = vp->getPropComponent(5)) { standardName = element; }
if (element = vp->getPropComponent(6)) { daylightName = element; }
}
// - to be faster? -
//else if (!wcscmp(vp->getName(), TEXT("VEVENT"))) {
// break;
//}
}
//
// If we have all required data, fill the tzInfo structure.
//
if (dstFlag == TEXT("FALSE")) {
// Easy timezone, no DST
found = true;
tzInfo.Bias = bias;
tzInfo.StandardBias = 0; // Cannot retrieve it, assume = 0 (usually is 0)
tzInfo.DaylightBias = -60; // most of the tiemzone is -60. only 1 is not (baghdad)
memset((void*)(&tzInfo.DaylightDate), 0, sizeof(SYSTEMTIME));
memset((void*)(&tzInfo.StandardDate) , 0, sizeof(SYSTEMTIME));
wcsncpy(tzInfo.StandardName, standardName.c_str(), 32);
wcsncpy(tzInfo.DaylightName, daylightName.c_str(), 32);
}
else if (dstFlag.size() && dstOffset.size() && daylightDates.size() && standardDates.size() ) {
// Standard timezone, the DST rules are extracted from list of dates
// >> Bias = -TZ
// >> StandardBias = 0 (Cannot retrieve it, assume = 0 as usually is 0)
// >> DaylightBias = - (DSTOffset + Bias)
bool rightValue = true;
found = true;
tzInfo.Bias = bias;
tzInfo.StandardBias = 0;
tzInfo.DaylightBias = parseBias(dstOffset.c_str()) - bias;
tzInfo.DaylightDate = getTzRuleFromDates(daylightDates, &rightValue);
tzInfo.StandardDate = getTzRuleFromDates(standardDates, &rightValue);
wcsncpy(tzInfo.StandardName, standardName.c_str(), 32);
wcsncpy(tzInfo.DaylightName, daylightName.c_str(), 32);
}
}
else {
// No timezone received.
found = false;
}
return found;
}
void WinEvent::getIntervalOfRecurrence(int* yearBegin, int* yearEnd) {
wstring element;
if (getProperty(L"Start", element)) {
if (element.size() >= 4) {
swscanf(element.c_str(), L"%4d", yearBegin);
}
if (getRecPattern()->getProperty(L"NoEndDate", element) && (element == L"0")) {
if (getRecPattern()->getProperty(L"PatternEndDate", element)) {
if (element.size() >= 4) {
swscanf(element.c_str(), L"%4d", yearEnd);
}
}
}
}
}
long WinEvent::getCRC() {
wstring values;
// Event props
mapIterator it = propertyMap.begin();
while (it != propertyMap.end()) {
values.append(it->second);
it ++;
}
// Append rec props only if recurring
wstring isRec;
if (getProperty(TEXT("IsRecurring"), isRec)) {
if (isRec == TEXT("1")) {
// note: use 'getRecPattern()' to retrieve the correct recPattern object
it = getRecPattern()->propertyMap.begin();
while (it != getRecPattern()->propertyMap.end()) {
values.append(it->second);
it ++;
}
// Exceptions
exceptionsIterator ex = excludeDate.begin();
while (ex != excludeDate.end()) {
values.append(*ex);
ex ++;
}
ex = includeDate.begin();
while (ex != includeDate.end()) {
values.append(*ex);
ex ++;
}
}
}
const WCHAR* s = values.c_str();
unsigned long crc32 = 0;
unsigned long dwErrorCode = NO_ERROR;
unsigned char byte = 0;
crc32 = 0xFFFFFFFF;
while(*s != TEXT('\0')) {
byte = (unsigned char) *s;
crc32 = ((crc32) >> 8) ^ crc32Table[(byte) ^ ((crc32) & 0x000000FF)];
s++;
}
crc32 = ~crc32;
return crc32;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?