You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
738 lines
17 KiB
738 lines
17 KiB
4 years ago
|
/*
|
||
|
* $Id: calendar.c,v 1.4 2010-01-17 00:38:47 judd Exp $
|
||
|
*
|
||
|
* calendar.c - Support for PalmOne Calendar application (CalendarDB-PDat),
|
||
|
* this is a copy of datebook.c with the calendar fields added.
|
||
|
*
|
||
|
* (c) 2008, Jon Schewe
|
||
|
*
|
||
|
* This library is free software; you can redistribute it and/or modify it
|
||
|
* under the terms of the GNU Library General Public License as published by
|
||
|
* the Free Software Foundation; either version 2 of the License, or (at
|
||
|
* your option) any later version.
|
||
|
*
|
||
|
* This library is distributed in the hope that it will be useful, but
|
||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library
|
||
|
* General Public License for more details.
|
||
|
*
|
||
|
* You should have received a copy of the GNU Library General Public License
|
||
|
* along with this library; if not, write to the Free Software Foundation,
|
||
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||
|
*/
|
||
|
|
||
|
#include <stdio.h>
|
||
|
#include <stdlib.h>
|
||
|
#include <string.h>
|
||
|
#include <errno.h>
|
||
|
|
||
|
#ifdef TIME_WITH_SYS_TIME
|
||
|
# include <sys/time.h>
|
||
|
# include <time.h>
|
||
|
#else
|
||
|
# ifdef HAVE_SYS_TIME_H
|
||
|
# include <sys/time.h>
|
||
|
# else
|
||
|
# include <time.h>
|
||
|
# endif
|
||
|
#endif
|
||
|
|
||
|
#include "pi-macros.h"
|
||
|
#include "pi-calendar.h"
|
||
|
|
||
|
#define alarmFlag 64
|
||
|
#define repeatFlag 32
|
||
|
#define noteFlag 16
|
||
|
#define exceptFlag 8
|
||
|
#define descFlag 4
|
||
|
#define locFlag 2
|
||
|
|
||
|
/***********************************************************************
|
||
|
*
|
||
|
* Function: new_CalendarEvent
|
||
|
*
|
||
|
* Summary: Create empty calendar event
|
||
|
*
|
||
|
* Parameters: CalendarEvent_t*
|
||
|
*
|
||
|
* Returns: void
|
||
|
*
|
||
|
***********************************************************************/
|
||
|
void
|
||
|
new_CalendarEvent(CalendarEvent_t *a)
|
||
|
{
|
||
|
int i = 0;
|
||
|
|
||
|
a->event = 0;
|
||
|
a->begin.tm_hour = 0;
|
||
|
a->begin.tm_min = 0;
|
||
|
a->begin.tm_sec = 0;
|
||
|
a->begin.tm_year = 2000;
|
||
|
a->begin.tm_mon = 0;
|
||
|
a->begin.tm_mday = 0;
|
||
|
a->begin.tm_isdst = -1;
|
||
|
a->end.tm_hour = 0;
|
||
|
a->end.tm_min = 0;
|
||
|
a->end.tm_sec = 0;
|
||
|
a->end.tm_year = 2000;
|
||
|
a->end.tm_mon = 0;
|
||
|
a->end.tm_mday = 0;
|
||
|
a->end.tm_isdst = -1;
|
||
|
a->alarm = 0;
|
||
|
a->advance = 0;
|
||
|
a->advanceUnits = 0;
|
||
|
a->repeatType = 0;
|
||
|
a->repeatForever = 0;
|
||
|
a->repeatEnd.tm_hour = 0;
|
||
|
a->repeatEnd.tm_min = 0;
|
||
|
a->repeatEnd.tm_sec = 0;
|
||
|
a->repeatEnd.tm_year = 2000;
|
||
|
a->repeatEnd.tm_mon = 0;
|
||
|
a->repeatEnd.tm_mday = 0;
|
||
|
a->repeatEnd.tm_isdst = -1;
|
||
|
|
||
|
a->repeatFrequency = 0;
|
||
|
a->repeatDay = 0;
|
||
|
for (i = 0; i < 7; i++) {
|
||
|
a->repeatDays[i] = 0;
|
||
|
}
|
||
|
a->repeatWeekstart = 0;
|
||
|
a->exceptions = 0;
|
||
|
a->exception = NULL;
|
||
|
a->description = NULL;
|
||
|
a->note = NULL;
|
||
|
a->location = NULL;
|
||
|
a->tz = NULL;
|
||
|
|
||
|
/* initialize the blobs to NULL */
|
||
|
for (i=0; i<MAX_BLOBS; i++) {
|
||
|
a->blob[i]=NULL;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/***********************************************************************
|
||
|
*
|
||
|
* Function: copy_CalendarEvent
|
||
|
*
|
||
|
* Summary: Copy the data from one calendar event to another. The destination
|
||
|
* calendar event must already be cleared, either by creating new or by
|
||
|
* calling free_CalendarEvent on it first.
|
||
|
*
|
||
|
* Parameters: CalendarEvent_t*, CalendarEvent_t*
|
||
|
*
|
||
|
* Returns: int -1 on failure (errno will be set), 0 on success
|
||
|
*
|
||
|
***********************************************************************/
|
||
|
int
|
||
|
copy_CalendarEvent(const CalendarEvent_t *source, CalendarEvent_t *dest)
|
||
|
{
|
||
|
int i = 0;
|
||
|
|
||
|
dest->event = source->event;
|
||
|
memcpy(&(dest->begin), &(source->begin), sizeof(struct tm));
|
||
|
memcpy(&(dest->end), &(source->end), sizeof(struct tm));
|
||
|
dest->alarm = source->alarm;
|
||
|
dest->advance = source->advance;
|
||
|
dest->advanceUnits = source->advanceUnits;
|
||
|
dest->repeatType = source->repeatType;
|
||
|
dest->repeatForever = source->repeatForever;
|
||
|
memcpy(&(dest->repeatEnd), &(source->repeatEnd), sizeof(struct tm));
|
||
|
|
||
|
dest->repeatFrequency = source->repeatFrequency;
|
||
|
dest->repeatDay = source->repeatDay;
|
||
|
for (i = 0; i < 7; i++) {
|
||
|
dest->repeatDays[i] = source->repeatDays[i];
|
||
|
}
|
||
|
dest->repeatWeekstart = source->repeatWeekstart;
|
||
|
dest->exceptions = source->exceptions;
|
||
|
if(source->exceptions > 0) {
|
||
|
dest->exception = (struct tm*)malloc(source->exceptions * sizeof(struct tm));
|
||
|
if(NULL == dest->exception) {
|
||
|
errno = ENOMEM;
|
||
|
return -1;
|
||
|
}
|
||
|
for(i=0; i<source->exceptions; i++) {
|
||
|
memcpy(&(dest->exception[i]), &(source->exception[i]), sizeof(struct tm));
|
||
|
}
|
||
|
}
|
||
|
if(NULL != source->description) {
|
||
|
dest->description = strdup(source->description);
|
||
|
} else {
|
||
|
dest->description = NULL;
|
||
|
}
|
||
|
if(NULL != source->note) {
|
||
|
dest->note = strdup(source->note);
|
||
|
} else {
|
||
|
dest->note = NULL;
|
||
|
}
|
||
|
if(NULL != source->location) {
|
||
|
dest->location = strdup(source->location);
|
||
|
} else {
|
||
|
dest->location = NULL;
|
||
|
}
|
||
|
|
||
|
/* copy the blobs */
|
||
|
for (i=0; i<MAX_BLOBS; i++) {
|
||
|
if(source->blob[i] != NULL) {
|
||
|
dest->blob[i] = dup_Blob(source->blob[i]);
|
||
|
if(NULL == dest->blob[i]) {
|
||
|
return -1;
|
||
|
}
|
||
|
} else {
|
||
|
dest->blob[i] = NULL;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if(source->tz != NULL) {
|
||
|
dest->tz = dup_Timezone(source->tz);
|
||
|
if(NULL == dest->tz) {
|
||
|
return -1;
|
||
|
}
|
||
|
} else {
|
||
|
dest->tz = NULL;
|
||
|
}
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
/***********************************************************************
|
||
|
*
|
||
|
* Function: free_CalendarEvent
|
||
|
*
|
||
|
* Summary: Frees members of the calendar event structure
|
||
|
*
|
||
|
* Parameters: CalendarEvent_t*
|
||
|
*
|
||
|
* Returns: void
|
||
|
*
|
||
|
***********************************************************************/
|
||
|
void
|
||
|
free_CalendarEvent(CalendarEvent_t *a)
|
||
|
{
|
||
|
int i;
|
||
|
|
||
|
if (a->exception != NULL) {
|
||
|
free(a->exception);
|
||
|
a->exception = NULL;
|
||
|
}
|
||
|
|
||
|
if (a->description != NULL) {
|
||
|
free(a->description);
|
||
|
a->description = NULL;
|
||
|
}
|
||
|
|
||
|
if (a->note != NULL) {
|
||
|
free(a->note);
|
||
|
a->note = NULL;
|
||
|
}
|
||
|
|
||
|
if(a->location != NULL) {
|
||
|
free(a->location);
|
||
|
a->location = NULL;
|
||
|
}
|
||
|
|
||
|
if(NULL != a->tz) {
|
||
|
free_Timezone(a->tz);
|
||
|
free(a->tz);
|
||
|
}
|
||
|
|
||
|
for(i=0; i<MAX_BLOBS; ++i) {
|
||
|
if(NULL != a->blob[i]) {
|
||
|
free_Blob(a->blob[i]);
|
||
|
|
||
|
free(a->blob[i]);
|
||
|
a->blob[i] = NULL;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/***********************************************************************
|
||
|
*
|
||
|
* Function: unpack_CalendarEvent
|
||
|
*
|
||
|
* Summary: Fill in the calendar event structure based on the raw
|
||
|
* record data
|
||
|
*
|
||
|
* Parameters: CalendarEvent_t*, pi_buffer_t * of buffer, calendarType
|
||
|
*
|
||
|
* Returns: -1 on fail, 0 on success
|
||
|
*
|
||
|
***********************************************************************/
|
||
|
int
|
||
|
unpack_CalendarEvent(CalendarEvent_t *a, const pi_buffer_t *buf, calendarType type)
|
||
|
{
|
||
|
int iflags,
|
||
|
j,
|
||
|
destlen,
|
||
|
i,
|
||
|
result;
|
||
|
unsigned char *p2;
|
||
|
unsigned long d;
|
||
|
|
||
|
destlen = 8;
|
||
|
|
||
|
if (type != calendar_v1)
|
||
|
return -1;
|
||
|
|
||
|
if (buf == NULL || buf->data == NULL || buf->used < destlen) {
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
a->begin.tm_hour = get_byte(buf->data);
|
||
|
a->begin.tm_min = get_byte(buf->data + 1);
|
||
|
a->begin.tm_sec = 0;
|
||
|
d = (unsigned short int) get_short(buf->data + 4);
|
||
|
a->begin.tm_year = (d >> 9) + 4;
|
||
|
a->begin.tm_mon = ((d >> 5) & 15) - 1;
|
||
|
a->begin.tm_mday = d & 31;
|
||
|
a->begin.tm_isdst = -1;
|
||
|
a->end = a->begin;
|
||
|
|
||
|
a->end.tm_hour = get_byte(buf->data + 2);
|
||
|
a->end.tm_min = get_byte(buf->data + 3);
|
||
|
|
||
|
if (get_short(buf->data) == 0xffff) {
|
||
|
a->event = 1;
|
||
|
a->begin.tm_hour = 0;
|
||
|
a->begin.tm_min = 0;
|
||
|
a->end.tm_hour = 0;
|
||
|
a->end.tm_min = 0;
|
||
|
} else {
|
||
|
a->event = 0;
|
||
|
}
|
||
|
|
||
|
mktime(&a->begin);
|
||
|
mktime(&a->end);
|
||
|
|
||
|
iflags = get_byte(buf->data + 6);
|
||
|
|
||
|
/* buf->data+7 is gapfill */
|
||
|
|
||
|
p2 = (unsigned char *) buf->data + 8;
|
||
|
|
||
|
if (iflags & alarmFlag) {
|
||
|
a->alarm = 1;
|
||
|
a->advance = get_byte(p2);
|
||
|
p2 += 1;
|
||
|
a->advanceUnits = get_byte(p2);
|
||
|
p2 += 1;
|
||
|
|
||
|
} else {
|
||
|
a->alarm = 0;
|
||
|
a->advance = 0;
|
||
|
a->advanceUnits = 0;
|
||
|
}
|
||
|
|
||
|
if (iflags & repeatFlag) {
|
||
|
int i,
|
||
|
on;
|
||
|
|
||
|
a->repeatType = (enum calendarRepeatType) get_byte(p2);
|
||
|
p2 += 2;
|
||
|
d = (unsigned short int) get_short(p2);
|
||
|
p2 += 2;
|
||
|
if (d == 0xffff)
|
||
|
a->repeatForever = 1; /* repeatEnd is invalid */
|
||
|
else {
|
||
|
a->repeatEnd.tm_year = (d >> 9) + 4;
|
||
|
a->repeatEnd.tm_mon = ((d >> 5) & 15) - 1;
|
||
|
a->repeatEnd.tm_mday = d & 31;
|
||
|
a->repeatEnd.tm_min = 0;
|
||
|
a->repeatEnd.tm_hour = 0;
|
||
|
a->repeatEnd.tm_sec = 0;
|
||
|
a->repeatEnd.tm_isdst = -1;
|
||
|
mktime(&a->repeatEnd);
|
||
|
a->repeatForever = 0;
|
||
|
}
|
||
|
a->repeatFrequency = get_byte(p2);
|
||
|
p2++;
|
||
|
on = get_byte(p2);
|
||
|
p2++;
|
||
|
a->repeatDay = (enum calendarDayOfMonthType) 0;
|
||
|
for (i = 0; i < 7; i++)
|
||
|
a->repeatDays[i] = 0;
|
||
|
|
||
|
if (a->repeatType == calendarRepeatMonthlyByDay)
|
||
|
a->repeatDay = (enum calendarDayOfMonthType) on;
|
||
|
else if (a->repeatType == calendarRepeatWeekly)
|
||
|
for (i = 0; i < 7; i++)
|
||
|
a->repeatDays[i] = !!(on & (1 << i));
|
||
|
a->repeatWeekstart = get_byte(p2);
|
||
|
p2++;
|
||
|
p2++;
|
||
|
} else {
|
||
|
int i;
|
||
|
|
||
|
a->repeatType = (enum calendarRepeatType) 0;
|
||
|
a->repeatForever = 1; /* repeatEnd is invalid */
|
||
|
a->repeatFrequency = 0;
|
||
|
a->repeatDay = (enum calendarDayOfMonthType) 0;
|
||
|
for (i = 0; i < 7; i++)
|
||
|
a->repeatDays[i] = 0;
|
||
|
a->repeatWeekstart = 0;
|
||
|
}
|
||
|
|
||
|
if (iflags & exceptFlag) {
|
||
|
a->exceptions = get_short(p2);
|
||
|
p2 += 2;
|
||
|
a->exception = malloc(sizeof(struct tm) * a->exceptions);
|
||
|
|
||
|
for (j = 0; j < a->exceptions; j++, p2 += 2) {
|
||
|
d = (unsigned short int) get_short(p2);
|
||
|
a->exception[j].tm_year = (d >> 9) + 4;
|
||
|
a->exception[j].tm_mon = ((d >> 5) & 15) - 1;
|
||
|
a->exception[j].tm_mday = d & 31;
|
||
|
a->exception[j].tm_hour = 0;
|
||
|
a->exception[j].tm_min = 0;
|
||
|
a->exception[j].tm_sec = 0;
|
||
|
a->exception[j].tm_isdst = -1;
|
||
|
mktime(&a->exception[j]);
|
||
|
}
|
||
|
|
||
|
} else {
|
||
|
a->exceptions = 0;
|
||
|
a->exception = 0;
|
||
|
}
|
||
|
|
||
|
if (iflags & descFlag) {
|
||
|
a->description = strdup((char *)p2);
|
||
|
p2 += strlen((char *)p2) + 1;
|
||
|
} else
|
||
|
a->description = 0;
|
||
|
|
||
|
if (iflags & noteFlag) {
|
||
|
a->note = strdup((char *)p2);
|
||
|
p2 += strlen((char *)p2) + 1;
|
||
|
} else {
|
||
|
a->note = 0;
|
||
|
}
|
||
|
|
||
|
if (iflags & locFlag) {
|
||
|
a->location = strdup((char *)p2);
|
||
|
p2 += strlen((char *)p2) + 1;
|
||
|
} else {
|
||
|
a->location = 0;
|
||
|
}
|
||
|
|
||
|
/* initialize the blobs to NULL */
|
||
|
for (i=0; i<MAX_BLOBS; ++i) {
|
||
|
a->blob[i]=NULL;
|
||
|
}
|
||
|
|
||
|
if(p2 - buf->data < buf->used) {
|
||
|
uint8_t blob_count;
|
||
|
|
||
|
/* read the blobs */
|
||
|
a->tz = NULL;
|
||
|
for(blob_count = 0; buf->used - (p2 - buf->data) > 6; ++blob_count) {
|
||
|
if(blob_count >= MAX_BLOBS) {
|
||
|
/* too many blobs were found */
|
||
|
printf("Error, found more than %d blobs: %d\n", MAX_BLOBS, blob_count);
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
a->blob[blob_count] = (Blob_t *)malloc(sizeof(Blob_t));
|
||
|
result = unpack_Blob_p(a->blob[blob_count], p2, 0);
|
||
|
if(-1 == result) {
|
||
|
return -1;
|
||
|
} else {
|
||
|
p2 += result;
|
||
|
}
|
||
|
//printf("DEBUG: record %s read in blob[%d] of size %d\n", a->description, blob_count, a->blob[blob_count]->length);
|
||
|
|
||
|
/* if it's a timezone blob store it */
|
||
|
if (0 == memcmp(a->blob[blob_count]->type, BLOB_TYPE_CALENDAR_TIMEZONE_ID, 4)) {
|
||
|
int result;
|
||
|
if(NULL != a->tz) {
|
||
|
printf("Warning: Found more than one timezone blob! Freeing the previous one and starting again\n");
|
||
|
free_Timezone(a->tz);
|
||
|
free(a->tz);
|
||
|
}
|
||
|
a->tz = (Timezone_t *)malloc(sizeof(Timezone_t));
|
||
|
result = unpack_Timezone_p(a->tz, a->blob[blob_count]->data, 0);
|
||
|
if(-1 == result) {
|
||
|
printf("Error unpacking timezone blob\n");
|
||
|
return -1;
|
||
|
} else if(result != a->blob[blob_count]->length) {
|
||
|
printf("Read the wrong number of bytes for a timezone expected %d but was %d\n", a->blob[blob_count]->length, result);
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
}
|
||
|
}
|
||
|
if(p2 - buf->data < buf->used) {
|
||
|
printf("Extra data found %ld bytes\n", (buf->used - (p2 - buf->data)));
|
||
|
return -1;
|
||
|
}
|
||
|
} else {
|
||
|
a->tz = NULL;
|
||
|
}
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
/***********************************************************************
|
||
|
*
|
||
|
* Function: pack_CalendarEvent
|
||
|
*
|
||
|
* Summary: Fill in the raw calendar event record data based on the
|
||
|
* calendar event structure.
|
||
|
*
|
||
|
* Parameters: CalendarEvent_t*, pi_buffer_t*, calendarType
|
||
|
*
|
||
|
* Returns: -1 on error (bad arguments, mostyle) or 0 on success.
|
||
|
* The buffer is sized to accomodate the required data.
|
||
|
*
|
||
|
***********************************************************************/
|
||
|
int
|
||
|
pack_CalendarEvent(const CalendarEvent_t *a, pi_buffer_t *buf, calendarType type)
|
||
|
{
|
||
|
int iflags,
|
||
|
destlen = 8;
|
||
|
char *pos;
|
||
|
|
||
|
if (type != calendar_v1)
|
||
|
return -1;
|
||
|
|
||
|
if (a == NULL || buf == NULL)
|
||
|
return -1;
|
||
|
|
||
|
if (a->alarm)
|
||
|
destlen += 2;
|
||
|
if (a->repeatType)
|
||
|
destlen += 8;
|
||
|
if (a->exceptions)
|
||
|
destlen += 2 + 2 * a->exceptions;
|
||
|
if (a->note)
|
||
|
destlen += strlen(a->note) + 1;
|
||
|
if (a->description)
|
||
|
destlen += strlen(a->description) + 1;
|
||
|
if (a->location)
|
||
|
destlen += strlen(a->location) + 1;
|
||
|
|
||
|
pi_buffer_expect (buf, destlen);
|
||
|
buf->used = destlen;
|
||
|
|
||
|
set_byte(buf->data, a->begin.tm_hour);
|
||
|
set_byte(buf->data + 1, a->begin.tm_min);
|
||
|
set_byte(buf->data + 2, a->end.tm_hour);
|
||
|
set_byte(buf->data + 3, a->end.tm_min);
|
||
|
set_short(buf->data + 4,
|
||
|
((a->
|
||
|
begin.tm_year - 4) << 9) | ((a->begin.tm_mon +
|
||
|
1) << 5) | a->begin.
|
||
|
tm_mday);
|
||
|
|
||
|
if (a->event) {
|
||
|
set_long(buf->data, 0xffffffff);
|
||
|
}
|
||
|
|
||
|
iflags = 0;
|
||
|
|
||
|
pos = (char *) buf->data + 8;
|
||
|
|
||
|
if (a->alarm) {
|
||
|
iflags |= alarmFlag;
|
||
|
|
||
|
set_byte(pos, a->advance);
|
||
|
set_byte(pos + 1, a->advanceUnits);
|
||
|
pos += 2;
|
||
|
}
|
||
|
|
||
|
if (a->repeatType) {
|
||
|
int i,
|
||
|
on;
|
||
|
|
||
|
iflags |= repeatFlag;
|
||
|
|
||
|
if (a->repeatType == calendarRepeatMonthlyByDay)
|
||
|
on = a->repeatDay;
|
||
|
else if (a->repeatType == calendarRepeatWeekly) {
|
||
|
on = 0;
|
||
|
for (i = 0; i < 7; i++)
|
||
|
if (a->repeatDays[i])
|
||
|
on |= 1 << i;
|
||
|
} else
|
||
|
on = 0;
|
||
|
|
||
|
set_byte(pos, a->repeatType);
|
||
|
set_byte(pos + 1, 0);
|
||
|
pos += 2;
|
||
|
|
||
|
if (a->repeatForever)
|
||
|
set_short(pos, 0xffff);
|
||
|
else
|
||
|
set_short(pos,
|
||
|
((a->
|
||
|
repeatEnd.tm_year -
|
||
|
4) << 9) | ((a->repeatEnd.tm_mon +
|
||
|
1) << 5) | a->repeatEnd.
|
||
|
tm_mday);
|
||
|
|
||
|
pos += 2;
|
||
|
|
||
|
set_byte(pos, a->repeatFrequency);
|
||
|
pos++;
|
||
|
set_byte(pos, on);
|
||
|
pos++;
|
||
|
set_byte(pos, a->repeatWeekstart);
|
||
|
pos++;
|
||
|
set_byte(pos, 0);
|
||
|
pos++;
|
||
|
}
|
||
|
|
||
|
if (a->exceptions) {
|
||
|
int i;
|
||
|
|
||
|
iflags |= exceptFlag;
|
||
|
|
||
|
set_short(pos, a->exceptions);
|
||
|
pos += 2;
|
||
|
|
||
|
for (i = 0; i < a->exceptions; i++, pos += 2)
|
||
|
set_short(pos,
|
||
|
((a->
|
||
|
exception[i].tm_year -
|
||
|
4) << 9) | ((a->exception[i].tm_mon +
|
||
|
1) << 5) | a->
|
||
|
exception[i].tm_mday);
|
||
|
}
|
||
|
|
||
|
if (a->description != NULL) {
|
||
|
iflags |= descFlag;
|
||
|
|
||
|
strcpy(pos, a->description);
|
||
|
pos += strlen(pos) + 1;
|
||
|
}
|
||
|
|
||
|
if (a->note != NULL) {
|
||
|
iflags |= noteFlag;
|
||
|
|
||
|
strcpy(pos, a->note);
|
||
|
pos += strlen(pos) + 1;
|
||
|
}
|
||
|
|
||
|
if (a->location != NULL) {
|
||
|
iflags |= locFlag;
|
||
|
|
||
|
strcpy(pos, a->location);
|
||
|
pos += strlen(pos) + 1;
|
||
|
}
|
||
|
|
||
|
set_byte(buf->data + 6, iflags);
|
||
|
set_byte(buf->data + 7, 0); /* gapfill */
|
||
|
|
||
|
/* Calendar stuff */
|
||
|
uint8_t blob_index;
|
||
|
|
||
|
//write out the blobs
|
||
|
for(blob_index = 0; blob_index < MAX_BLOBS; ++blob_index) {
|
||
|
if(NULL != a->blob[blob_index]) {
|
||
|
pack_Blob(a->blob[blob_index], buf);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
/***********************************************************************
|
||
|
*
|
||
|
* Function: unpack_CalendarAppInfo
|
||
|
*
|
||
|
* Summary: Fill in the app info structure based on the raw app
|
||
|
* info data
|
||
|
*
|
||
|
* Parameters: CalendarAppInfo_t*, char* to record, record length
|
||
|
*
|
||
|
* Returns: 0 on error, the length of the data used from the
|
||
|
* buffer otherwise
|
||
|
*
|
||
|
***********************************************************************/
|
||
|
int
|
||
|
unpack_CalendarAppInfo(CalendarAppInfo_t *ai, pi_buffer_t *buf)
|
||
|
{
|
||
|
int i;
|
||
|
int len;
|
||
|
unsigned char *record;
|
||
|
int used;
|
||
|
|
||
|
len = buf->used;
|
||
|
record = buf->data;
|
||
|
used = unpack_CategoryAppInfo(&ai->category, record, len);
|
||
|
if (!used)
|
||
|
return 0;
|
||
|
record += used;
|
||
|
len -= used;
|
||
|
if (len < 2)
|
||
|
return 0;
|
||
|
ai->startOfWeek = get_byte(record);
|
||
|
// alignment byte
|
||
|
record += 2;
|
||
|
used += 2;
|
||
|
|
||
|
for(i=0; i<18; ++i) {
|
||
|
ai->internal[i] = get_byte(record);
|
||
|
record++;
|
||
|
used++;
|
||
|
}
|
||
|
ai->type = calendar_v1;
|
||
|
|
||
|
return used;
|
||
|
}
|
||
|
|
||
|
/***********************************************************************
|
||
|
*
|
||
|
* Function: pack_CalendarAppInfo
|
||
|
*
|
||
|
* Summary: Fill in the raw app info record data based on the app
|
||
|
* info structure
|
||
|
*
|
||
|
* Parameters: AppointmentAppInfo*, char* to buffer, buffer length
|
||
|
*
|
||
|
* Returns: The length of the buffer required if record is NULL,
|
||
|
* or 0 on error, the length of the data used from the
|
||
|
* buffer otherwise
|
||
|
*
|
||
|
***********************************************************************/
|
||
|
int
|
||
|
pack_CalendarAppInfo(const CalendarAppInfo_t *ai, pi_buffer_t *buf)
|
||
|
{
|
||
|
int i;
|
||
|
int len;
|
||
|
unsigned char *record;
|
||
|
|
||
|
if (!buf) {
|
||
|
return 298;
|
||
|
}
|
||
|
|
||
|
/* AppInfo size should be 298, 300 will do */
|
||
|
len = 300;
|
||
|
pi_buffer_expect(buf, 300);
|
||
|
buf->used = pack_CategoryAppInfo(&ai->category, buf->data, buf->allocated);
|
||
|
if (!buf->used)
|
||
|
return 0;
|
||
|
record = buf->data + buf->used;
|
||
|
len -= buf->used;
|
||
|
if (len < 2)
|
||
|
return 0;
|
||
|
set_short(record, 0);
|
||
|
set_byte(record, ai->startOfWeek);
|
||
|
record += 2;
|
||
|
buf->used += 2;
|
||
|
|
||
|
for(i=0; i<18; ++i) {
|
||
|
set_byte(record, ai->internal[i]);
|
||
|
record ++;
|
||
|
buf->used ++;
|
||
|
}
|
||
|
|
||
|
return (record - buf->data);
|
||
|
}
|
||
|
|
||
|
/* vi: set ts=8 sw=4 sts=4 noexpandtab: cin */
|
||
|
/* ex: set tabstop=4 expandtab: */
|
||
|
/* Local Variables: */
|
||
|
/* indent-tabs-mode: t */
|
||
|
/* c-basic-offset: 8 */
|
||
|
/* End: */
|