summaryrefslogtreecommitdiff
authortille <tille>2002-05-15 09:53:39 (UTC)
committer tille <tille>2002-05-15 09:53:39 (UTC)
commit7977d9c5793100040b645974be1573572a550f62 (patch) (side-by-side diff)
treebd1265a21c2ea7495fa0e9446e80239e25c5aeed
parentb1198cf567577dba9710b9fb19d924c766202c38 (diff)
downloadopie-7977d9c5793100040b645974be1573572a550f62.zip
opie-7977d9c5793100040b645974be1573572a550f62.tar.gz
opie-7977d9c5793100040b645974be1573572a550f62.tar.bz2
hack to get rig of segfaults after reading </DATEBOOK>
Diffstat (more/less context) (show whitespace changes)
-rw-r--r--library/datebookdb.cpp3
1 files changed, 2 insertions, 1 deletions
diff --git a/library/datebookdb.cpp b/library/datebookdb.cpp
index 2ac9a0c..a26fe8f 100644
--- a/library/datebookdb.cpp
+++ b/library/datebookdb.cpp
@@ -544,385 +544,386 @@ QValueList<EffectiveEvent> DateBookDB::getEffectiveEvents( const QDate &from,
QDate endDate = startDate.addDays( duration );
while ( sub_it <= endDate && sub_it <= to ) {
EffectiveEvent tmpEffEv = effEv;
Event tmpEv = *it;
tmpEffEv.setEvent( tmpEv );
if ( sub_it != startDate )
tmpEffEv.setStart( QTime(0,0,0) );
if ( sub_it != endDate )
tmpEffEv.setEnd( QTime(23,59,59) );
tmpEffEv.setDate( sub_it );
tmpEffEv.setEffectiveDates( startDate, endDate );
tmpList.append( tmpEffEv );
sub_it = sub_it.addDays( 1 );
}
itDate = endDate;
} else {
Event tmpEv = *it;
effEv.setEvent( tmpEv );
tmpList.append( effEv );
itDate = repeat.date().addDays( 1 );
}
}
}
qHeapSort( tmpList );
return tmpList;
}
QValueList<EffectiveEvent> DateBookDB::getEffectiveEvents( const QDateTime &dt)
{
QValueList<EffectiveEvent> day = getEffectiveEvents(dt.date(), dt.date());
QValueListConstIterator<EffectiveEvent> it;
QValueList<EffectiveEvent> tmpList;
QDateTime dtTmp;
for (it = day.begin(); it != day.end(); ++it ) {
dtTmp = QDateTime( (*it).date(), (*it).start() );
// at the moment we don't have second granularity, be nice about that..
if ( QABS(dt.secsTo(dtTmp)) < 60 )
tmpList.append( *it );
}
return tmpList;
}
void DateBookDB::addEvent( const Event &ev, bool doalarm )
{
// write to the journal...
saveJournalEntry( ev, ACTION_ADD, -1, false );
addJFEvent( ev, doalarm );
d->clean = false;
}
void DateBookDB::addJFEvent( const Event &ev, bool doalarm )
{
if ( doalarm && ev.hasAlarm() )
addEventAlarm( ev );
if ( ev.hasRepeat() )
repeatEvents.append( ev );
else
eventList.append( ev );
}
void DateBookDB::editEvent( const Event &old, Event &editedEv )
{
int oldIndex=0;
bool oldHadRepeat = old.hasRepeat();
Event orig;
// write to the journal...
if ( oldHadRepeat ) {
if ( origRepeat( old, orig ) ) // should work always...
oldIndex = repeatEvents.findIndex( orig );
} else
oldIndex = eventList.findIndex( old );
saveJournalEntry( editedEv, ACTION_REPLACE, oldIndex, oldHadRepeat );
// Delete old event
if ( old.hasAlarm() )
delEventAlarm( old );
if ( oldHadRepeat ) {
if ( editedEv.hasRepeat() ) { // This mean that origRepeat was run above and
// orig is initialized
// assumption, when someone edits a repeating event, they
// want to change them all, maybe not perfect, but it works
// for the moment...
repeatEvents.remove( orig );
} else
removeRepeat( old );
} else {
QValueList<Event>::Iterator it = eventList.find( old );
if ( it != eventList.end() )
eventList.remove( it );
}
// Add new event
if ( editedEv.hasAlarm() )
addEventAlarm( editedEv );
if ( editedEv.hasRepeat() )
repeatEvents.append( editedEv );
else
eventList.append( editedEv );
d->clean = false;
}
void DateBookDB::removeEvent( const Event &ev )
{
// write to the journal...
saveJournalEntry( ev, ACTION_REMOVE, -1, false );
removeJFEvent( ev );
d->clean = false;
}
void DateBookDB::removeJFEvent( const Event&ev )
{
if ( ev.hasAlarm() )
delEventAlarm( ev );
if ( ev.hasRepeat() ) {
removeRepeat( ev );
} else {
QValueList<Event>::Iterator it = eventList.find( ev );
if ( it != eventList.end() )
eventList.remove( it );
}
}
// also handles journaling...
void DateBookDB::loadFile( const QString &strFile )
{
QFile f( strFile );
if ( !f.open( IO_ReadOnly ) )
return;
enum Attribute {
FDescription = 0,
FLocation,
FCategories,
FUid,
FType,
FAlarm,
FSound,
FRType,
FRWeekdays,
FRPosition,
FRFreq,
FRHasEndDate,
FREndDate,
FRStart,
FREnd,
FNote,
FCreated,
FAction,
FActionKey,
FJournalOrigHadRepeat
};
QAsciiDict<int> dict( 97 );
dict.setAutoDelete( TRUE );
dict.insert( "description", new int(FDescription) );
dict.insert( "location", new int(FLocation) );
dict.insert( "categories", new int(FCategories) );
dict.insert( "uid", new int(FUid) );
dict.insert( "type", new int(FType) );
dict.insert( "alarm", new int(FAlarm) );
dict.insert( "sound", new int(FSound) );
dict.insert( "rtype", new int(FRType) );
dict.insert( "rweekdays", new int(FRWeekdays) );
dict.insert( "rposition", new int(FRPosition) );
dict.insert( "rfreq", new int(FRFreq) );
dict.insert( "rhasenddate", new int(FRHasEndDate) );
dict.insert( "enddt", new int(FREndDate) );
dict.insert( "start", new int(FRStart) );
dict.insert( "end", new int(FREnd) );
dict.insert( "note", new int(FNote) );
dict.insert( "created", new int(FCreated) );
dict.insert( "action", new int(FAction) );
dict.insert( "actionkey", new int(FActionKey) );
dict.insert( "actionorig", new int (FJournalOrigHadRepeat) );
QByteArray ba = f.readAll();
char* dt = ba.data();
int len = ba.size();
int currentAction,
journalKey,
origHadRepeat; // should be bool, but we need tri-state(not being used)
int i = 0;
char *point;
- while ( ( point = strstr( dt+i, "<event " ) ) != 0 ) {
+ // hack to get rid of segfaults after reading </DATEBOOK>
+ while ( (dt+i != 0) && (( point = strstr( dt+i, "<event " ) ) != 0 )) {
i = point - dt;
// if we are reading in events in the general case,
// we are just adding them, so let the actions represent that...
currentAction = ACTION_ADD;
journalKey = -1;
origHadRepeat = -1;
// some temporary variables for dates and times ...
//int startY = 0, startM = 0, startD = 0, starth = 0, startm = 0, starts = 0;
//int endY = 0, endM = 0, endD = 0, endh = 0, endm = 0, ends = 0;
//int enddtY = 0, enddtM = 0, enddtD = 0;
// ... for the alarm settings ...
int alarmTime = -1; Event::SoundTypeChoice alarmSound = Event::Silent;
// ... and for the recurrence
Event::RepeatPattern rp;
Event e;
i += 7;
while( 1 ) {
while ( i < len && (dt[i] == ' ' || dt[i] == '\n' || dt[i] == '\r') )
++i;
if ( i >= len-2 || (dt[i] == '/' && dt[i+1] == '>') )
break;
// we have another attribute, read it.
int j = i;
while ( j < len && dt[j] != '=' )
++j;
char *attr = dt+i;
dt[j] = '\0';
i = ++j; // skip =
while ( i < len && dt[i] != '"' )
++i;
j = ++i;
bool haveAmp = FALSE;
bool haveUtf = FALSE;
while ( j < len && dt[j] != '"' ) {
if ( dt[j] == '&' )
haveAmp = TRUE;
if ( ((unsigned char)dt[j]) > 0x7f )
haveUtf = TRUE;
++j;
}
if ( i == j ) {
// leave out empty attributes
i = j + 1;
continue;
}
QString value = haveUtf ? QString::fromUtf8( dt+i, j-i )
: QString::fromLatin1( dt+i, j-i );
if ( haveAmp )
value = Qtopia::plainString( value );
i = j + 1;
//qDebug("attr='%s' value='%s'", attr.data(), value.latin1() );
int * find = dict[ attr ];
#if 1
if ( !find ) {
// custom field
e.setCustomField(attr, value);
continue;
}
switch( *find ) {
case FDescription:
e.setDescription( value );
break;
case FLocation:
e.setLocation( value );
break;
case FCategories:
e.setCategories( Qtopia::Record::idsFromString( value ) );
break;
case FUid:
e.setUid( value.toInt() );
break;
case FType:
if ( value == "AllDay" )
e.setType( Event::AllDay );
else
e.setType( Event::Normal );
break;
case FAlarm:
alarmTime = value.toInt();
break;
case FSound:
alarmSound = value == "loud" ? Event::Loud : Event::Silent;
break;
// recurrence stuff
case FRType:
if ( value == "Daily" )
rp.type = Event::Daily;
else if ( value == "Weekly" )
rp.type = Event::Weekly;
else if ( value == "MonthlyDay" )
rp.type = Event::MonthlyDay;
else if ( value == "MonthlyDate" )
rp.type = Event::MonthlyDate;
else if ( value == "Yearly" )
rp.type = Event::Yearly;
else
rp.type = Event::NoRepeat;
break;
case FRWeekdays:
rp.days = value.toInt();
break;
case FRPosition:
rp.position = value.toInt();
break;
case FRFreq:
rp.frequency = value.toInt();
break;
case FRHasEndDate:
rp.hasEndDate = value.toInt();
break;
case FREndDate: {
rp.endDateUTC = (time_t) value.toLong();
break;
}
case FRStart: {
e.setStart( (time_t) value.toLong() );
break;
}
case FREnd: {
e.setEnd( (time_t) value.toLong() );
break;
}
case FNote:
e.setNotes( value );
break;
case FCreated:
rp.createTime = value.toInt();
break;
case FAction:
currentAction = value.toInt();
break;
case FActionKey:
journalKey = value.toInt();
break;
case FJournalOrigHadRepeat:
origHadRepeat = value.toInt();
break;
default:
qDebug( "huh??? missing enum? -- attr.: %s", attr );
break;
}
#endif
}
// "post processing" (dates, times, alarm, recurrence)
// start date/time
e.setRepeat( rp.type != Event::NoRepeat, rp );
if ( alarmTime != -1 )
e.setAlarm( TRUE, alarmTime, alarmSound );
// now do our action based on the current action...
switch ( currentAction ) {
case ACTION_ADD:
addJFEvent( e );
break;
case ACTION_REMOVE:
removeJFEvent( e );
break;
case ACTION_REPLACE:
// be a little bit careful,
// in case of a messed up journal...
if ( journalKey > -1 && origHadRepeat > -1 ) {
// get the original from proper list...
if ( origHadRepeat )
removeJFEvent( *(repeatEvents.at(journalKey)) );
else
removeJFEvent( *(eventList.at(journalKey)) );
addJFEvent( e );
}
break;
default:
break;
}
}
f.close();
}
void DateBookDB::init()
{
d = new DateBookDBPrivate;
d->clean = false;
QString str = dateBookFilename();
if ( str.isNull() ) {
QMessageBox::warning( 0, QObject::tr("Out of Space"),
QObject::tr("Unable to create start up files\n"