-rw-r--r-- | libopie/pim/odatebookaccessbackend_xml.cpp | 29 | ||||
-rw-r--r-- | libopie/pim/otodoaccessxml.cpp | 30 | ||||
-rw-r--r-- | libopie/pim/test/oevent_test.cpp | 21 | ||||
-rw-r--r-- | libopie2/opiepim/backend/odatebookaccessbackend_xml.cpp | 29 | ||||
-rw-r--r-- | libopie2/opiepim/backend/otodoaccessxml.cpp | 30 |
5 files changed, 114 insertions, 25 deletions
diff --git a/libopie/pim/odatebookaccessbackend_xml.cpp b/libopie/pim/odatebookaccessbackend_xml.cpp index bc51996..24b69fe 100644 --- a/libopie/pim/odatebookaccessbackend_xml.cpp +++ b/libopie/pim/odatebookaccessbackend_xml.cpp | |||
@@ -1,73 +1,100 @@ | |||
1 | #include <errno.h> | 1 | #include <errno.h> |
2 | #include <fcntl.h> | 2 | #include <fcntl.h> |
3 | 3 | ||
4 | #include <stdio.h> | 4 | #include <stdio.h> |
5 | #include <stdlib.h> | 5 | #include <stdlib.h> |
6 | 6 | ||
7 | #include <sys/types.h> | 7 | #include <sys/types.h> |
8 | #include <sys/mman.h> | 8 | #include <sys/mman.h> |
9 | #include <sys/stat.h> | 9 | #include <sys/stat.h> |
10 | 10 | ||
11 | #include <unistd.h> | 11 | #include <unistd.h> |
12 | 12 | ||
13 | #include <qasciidict.h> | 13 | #include <qasciidict.h> |
14 | #include <qfile.h> | 14 | #include <qfile.h> |
15 | 15 | ||
16 | #include <qtopia/global.h> | 16 | #include <qtopia/global.h> |
17 | #include <qtopia/stringutil.h> | 17 | #include <qtopia/stringutil.h> |
18 | #include <qtopia/timeconversion.h> | 18 | #include <qtopia/timeconversion.h> |
19 | 19 | ||
20 | #include "opimnotifymanager.h" | 20 | #include "opimnotifymanager.h" |
21 | #include "orecur.h" | 21 | #include "orecur.h" |
22 | #include "otimezone.h" | 22 | #include "otimezone.h" |
23 | #include "odatebookaccessbackend_xml.h" | 23 | #include "odatebookaccessbackend_xml.h" |
24 | 24 | ||
25 | namespace { | 25 | namespace { |
26 | // FROM TT again | ||
27 | char *strstrlen(const char *haystack, int hLen, const char* needle, int nLen) | ||
28 | { | ||
29 | char needleChar; | ||
30 | char haystackChar; | ||
31 | if (!needle || !haystack || !hLen || !nLen) | ||
32 | return 0; | ||
33 | |||
34 | const char* hsearch = haystack; | ||
35 | |||
36 | if ((needleChar = *needle++) != 0) { | ||
37 | nLen--; //(to make up for needle++) | ||
38 | do { | ||
39 | do { | ||
40 | if ((haystackChar = *hsearch++) == 0) | ||
41 | return (0); | ||
42 | if (hsearch >= haystack + hLen) | ||
43 | return (0); | ||
44 | } while (haystackChar != needleChar); | ||
45 | } while (strncmp(hsearch, needle, QMIN(hLen - (hsearch - haystack), nLen)) != 0); | ||
46 | hsearch--; | ||
47 | } | ||
48 | return ((char *)hsearch); | ||
49 | } | ||
50 | } | ||
51 | |||
52 | namespace { | ||
26 | time_t start, end, created, rp_end; | 53 | time_t start, end, created, rp_end; |
27 | ORecur* rec; | 54 | ORecur* rec; |
28 | ORecur* recur() { | 55 | ORecur* recur() { |
29 | if (!rec) | 56 | if (!rec) |
30 | rec = new ORecur; | 57 | rec = new ORecur; |
31 | 58 | ||
32 | return rec; | 59 | return rec; |
33 | } | 60 | } |
34 | int alarmTime; | 61 | int alarmTime; |
35 | int snd; | 62 | int snd; |
36 | enum Attribute{ | 63 | enum Attribute{ |
37 | FDescription = 0, | 64 | FDescription = 0, |
38 | FLocation, | 65 | FLocation, |
39 | FCategories, | 66 | FCategories, |
40 | FUid, | 67 | FUid, |
41 | FType, | 68 | FType, |
42 | FAlarm, | 69 | FAlarm, |
43 | FSound, | 70 | FSound, |
44 | FRType, | 71 | FRType, |
45 | FRWeekdays, | 72 | FRWeekdays, |
46 | FRPosition, | 73 | FRPosition, |
47 | FRFreq, | 74 | FRFreq, |
48 | FRHasEndDate, | 75 | FRHasEndDate, |
49 | FREndDate, | 76 | FREndDate, |
50 | FRStart, | 77 | FRStart, |
51 | FREnd, | 78 | FREnd, |
52 | FNote, | 79 | FNote, |
53 | FCreated, | 80 | FCreated, |
54 | FTimeZone, | 81 | FTimeZone, |
55 | FRecParent, | 82 | FRecParent, |
56 | FRecChildren, | 83 | FRecChildren, |
57 | FExceptions | 84 | FExceptions |
58 | }; | 85 | }; |
59 | inline void save( const OEvent& ev, QString& buf ) { | 86 | inline void save( const OEvent& ev, QString& buf ) { |
60 | buf += " description=\"" + Qtopia::escapeString(ev.description() ) + "\""; | 87 | buf += " description=\"" + Qtopia::escapeString(ev.description() ) + "\""; |
61 | if (!ev.location().isEmpty() ) | 88 | if (!ev.location().isEmpty() ) |
62 | buf += " location=\"" + Qtopia::escapeString(ev.location() ) + "\""; | 89 | buf += " location=\"" + Qtopia::escapeString(ev.location() ) + "\""; |
63 | 90 | ||
64 | buf += " categories=\""+ Qtopia::escapeString( Qtopia::Record::idsToString( ev.categories() ) ) + "\""; | 91 | buf += " categories=\""+ Qtopia::escapeString( Qtopia::Record::idsToString( ev.categories() ) ) + "\""; |
65 | buf += " uid=\"" + QString::number( ev.uid() ) + "\""; | 92 | buf += " uid=\"" + QString::number( ev.uid() ) + "\""; |
66 | 93 | ||
67 | if (ev.isAllDay() ) | 94 | if (ev.isAllDay() ) |
68 | buf += " type=\"AllDay\""; | 95 | buf += " type=\"AllDay\""; |
69 | 96 | ||
70 | if (ev.hasNotifiers() ) { | 97 | if (ev.hasNotifiers() ) { |
71 | OPimAlarm alarm = ev.notifiers().alarms()[0]; // take only the first | 98 | OPimAlarm alarm = ev.notifiers().alarms()[0]; // take only the first |
72 | int minutes = alarm.dateTime().secsTo( ev.startDateTime() ) / 60; | 99 | int minutes = alarm.dateTime().secsTo( ev.startDateTime() ) / 60; |
73 | buf += " alarm=\"" + QString::number(minutes) + "\" sound=\""; | 100 | buf += " alarm=\"" + QString::number(minutes) + "\" sound=\""; |
@@ -297,97 +324,97 @@ bool ODateBookAccessBackend_XML::loadFile() { | |||
297 | int fd = ::open( QFile::encodeName(m_name).data(), O_RDONLY ); | 324 | int fd = ::open( QFile::encodeName(m_name).data(), O_RDONLY ); |
298 | if ( fd < 0 ) return false; | 325 | if ( fd < 0 ) return false; |
299 | 326 | ||
300 | struct stat attribute; | 327 | struct stat attribute; |
301 | if ( ::fstat(fd, &attribute ) == -1 ) { | 328 | if ( ::fstat(fd, &attribute ) == -1 ) { |
302 | ::close( fd ); | 329 | ::close( fd ); |
303 | return false; | 330 | return false; |
304 | } | 331 | } |
305 | void* map_addr = ::mmap(NULL, attribute.st_size, PROT_READ, MAP_SHARED, fd, 0 ); | 332 | void* map_addr = ::mmap(NULL, attribute.st_size, PROT_READ, MAP_SHARED, fd, 0 ); |
306 | if ( map_addr == ( (caddr_t)-1) ) { | 333 | if ( map_addr == ( (caddr_t)-1) ) { |
307 | ::close( fd ); | 334 | ::close( fd ); |
308 | return false; | 335 | return false; |
309 | } | 336 | } |
310 | 337 | ||
311 | ::madvise( map_addr, attribute.st_size, MADV_SEQUENTIAL ); | 338 | ::madvise( map_addr, attribute.st_size, MADV_SEQUENTIAL ); |
312 | ::close( fd ); | 339 | ::close( fd ); |
313 | 340 | ||
314 | QAsciiDict<int> dict(FExceptions+1); | 341 | QAsciiDict<int> dict(FExceptions+1); |
315 | dict.setAutoDelete( true ); | 342 | dict.setAutoDelete( true ); |
316 | dict.insert( "description", new int(FDescription) ); | 343 | dict.insert( "description", new int(FDescription) ); |
317 | dict.insert( "location", new int(FLocation) ); | 344 | dict.insert( "location", new int(FLocation) ); |
318 | dict.insert( "categories", new int(FCategories) ); | 345 | dict.insert( "categories", new int(FCategories) ); |
319 | dict.insert( "uid", new int(FUid) ); | 346 | dict.insert( "uid", new int(FUid) ); |
320 | dict.insert( "type", new int(FType) ); | 347 | dict.insert( "type", new int(FType) ); |
321 | dict.insert( "alarm", new int(FAlarm) ); | 348 | dict.insert( "alarm", new int(FAlarm) ); |
322 | dict.insert( "sound", new int(FSound) ); | 349 | dict.insert( "sound", new int(FSound) ); |
323 | dict.insert( "rtype", new int(FRType) ); | 350 | dict.insert( "rtype", new int(FRType) ); |
324 | dict.insert( "rweekdays", new int(FRWeekdays) ); | 351 | dict.insert( "rweekdays", new int(FRWeekdays) ); |
325 | dict.insert( "rposition", new int(FRPosition) ); | 352 | dict.insert( "rposition", new int(FRPosition) ); |
326 | dict.insert( "rfreq", new int(FRFreq) ); | 353 | dict.insert( "rfreq", new int(FRFreq) ); |
327 | dict.insert( "rhasenddate", new int(FRHasEndDate) ); | 354 | dict.insert( "rhasenddate", new int(FRHasEndDate) ); |
328 | dict.insert( "enddt", new int(FREndDate) ); | 355 | dict.insert( "enddt", new int(FREndDate) ); |
329 | dict.insert( "start", new int(FRStart) ); | 356 | dict.insert( "start", new int(FRStart) ); |
330 | dict.insert( "end", new int(FREnd) ); | 357 | dict.insert( "end", new int(FREnd) ); |
331 | dict.insert( "note", new int(FNote) ); | 358 | dict.insert( "note", new int(FNote) ); |
332 | dict.insert( "created", new int(FCreated) ); | 359 | dict.insert( "created", new int(FCreated) ); |
333 | dict.insert( "recparent", new int(FRecParent) ); | 360 | dict.insert( "recparent", new int(FRecParent) ); |
334 | dict.insert( "recchildren", new int(FRecChildren) ); | 361 | dict.insert( "recchildren", new int(FRecChildren) ); |
335 | dict.insert( "exceptions", new int(FExceptions) ); | 362 | dict.insert( "exceptions", new int(FExceptions) ); |
336 | dict.insert( "timezone", new int(FTimeZone) ); | 363 | dict.insert( "timezone", new int(FTimeZone) ); |
337 | 364 | ||
338 | char* dt = (char*)map_addr; | 365 | char* dt = (char*)map_addr; |
339 | int len = attribute.st_size; | 366 | int len = attribute.st_size; |
340 | int i = 0; | 367 | int i = 0; |
341 | char* point; | 368 | char* point; |
342 | const char* collectionString = "<event "; | 369 | const char* collectionString = "<event "; |
343 | int strLen = ::strlen(collectionString); | 370 | int strLen = ::strlen(collectionString); |
344 | int *find; | 371 | int *find; |
345 | while ( dt + 1 != 0 && (( point = ::strstr( dt+i, collectionString ) ) != 0 ) ) { | 372 | while ( ( point = ::strstrlen( dt+i, len -i, collectionString, strLen ) ) != 0 ) { |
346 | i = point -dt; | 373 | i = point -dt; |
347 | i+= strLen; | 374 | i+= strLen; |
348 | 375 | ||
349 | alarmTime = -1; | 376 | alarmTime = -1; |
350 | snd = 0; // silent | 377 | snd = 0; // silent |
351 | 378 | ||
352 | OEvent ev; | 379 | OEvent ev; |
353 | rec = 0; | 380 | rec = 0; |
354 | 381 | ||
355 | while ( TRUE ) { | 382 | while ( TRUE ) { |
356 | while ( i < len && (dt[i] == ' ' || dt[i] == '\n' || dt[i] == '\r') ) | 383 | while ( i < len && (dt[i] == ' ' || dt[i] == '\n' || dt[i] == '\r') ) |
357 | ++i; | 384 | ++i; |
358 | if ( i >= len-2 || (dt[i] == '/' && dt[i+1] == '>') ) | 385 | if ( i >= len-2 || (dt[i] == '/' && dt[i+1] == '>') ) |
359 | break; | 386 | break; |
360 | 387 | ||
361 | 388 | ||
362 | // we have another attribute, read it. | 389 | // we have another attribute, read it. |
363 | int j = i; | 390 | int j = i; |
364 | while ( j < len && dt[j] != '=' ) | 391 | while ( j < len && dt[j] != '=' ) |
365 | ++j; | 392 | ++j; |
366 | QCString attr( dt+i, j-i+1); | 393 | QCString attr( dt+i, j-i+1); |
367 | 394 | ||
368 | i = ++j; // skip = | 395 | i = ++j; // skip = |
369 | 396 | ||
370 | // find the start of quotes | 397 | // find the start of quotes |
371 | while ( i < len && dt[i] != '"' ) | 398 | while ( i < len && dt[i] != '"' ) |
372 | ++i; | 399 | ++i; |
373 | j = ++i; | 400 | j = ++i; |
374 | 401 | ||
375 | bool haveUtf = FALSE; | 402 | bool haveUtf = FALSE; |
376 | bool haveEnt = FALSE; | 403 | bool haveEnt = FALSE; |
377 | while ( j < len && dt[j] != '"' ) { | 404 | while ( j < len && dt[j] != '"' ) { |
378 | if ( ((unsigned char)dt[j]) > 0x7f ) | 405 | if ( ((unsigned char)dt[j]) > 0x7f ) |
379 | haveUtf = TRUE; | 406 | haveUtf = TRUE; |
380 | if ( dt[j] == '&' ) | 407 | if ( dt[j] == '&' ) |
381 | haveEnt = TRUE; | 408 | haveEnt = TRUE; |
382 | ++j; | 409 | ++j; |
383 | } | 410 | } |
384 | if ( i == j ) { | 411 | if ( i == j ) { |
385 | // empty value | 412 | // empty value |
386 | i = j + 1; | 413 | i = j + 1; |
387 | continue; | 414 | continue; |
388 | } | 415 | } |
389 | 416 | ||
390 | QCString value( dt+i, j-i+1 ); | 417 | QCString value( dt+i, j-i+1 ); |
391 | i = j + 1; | 418 | i = j + 1; |
392 | 419 | ||
393 | QString str = (haveUtf ? QString::fromUtf8( value ) | 420 | QString str = (haveUtf ? QString::fromUtf8( value ) |
diff --git a/libopie/pim/otodoaccessxml.cpp b/libopie/pim/otodoaccessxml.cpp index 22b2469..cda300b 100644 --- a/libopie/pim/otodoaccessxml.cpp +++ b/libopie/pim/otodoaccessxml.cpp | |||
@@ -1,136 +1,164 @@ | |||
1 | #include <errno.h> | 1 | #include <errno.h> |
2 | #include <fcntl.h> | 2 | #include <fcntl.h> |
3 | 3 | ||
4 | #include <sys/mman.h> | 4 | #include <sys/mman.h> |
5 | #include <sys/stat.h> | 5 | #include <sys/stat.h> |
6 | #include <sys/types.h> | 6 | #include <sys/types.h> |
7 | 7 | ||
8 | #include <unistd.h> | 8 | #include <unistd.h> |
9 | 9 | ||
10 | 10 | ||
11 | #include <qfile.h> | 11 | #include <qfile.h> |
12 | #include <qvector.h> | 12 | #include <qvector.h> |
13 | 13 | ||
14 | #include <qpe/global.h> | 14 | #include <qpe/global.h> |
15 | #include <qpe/stringutil.h> | 15 | #include <qpe/stringutil.h> |
16 | #include <qpe/timeconversion.h> | 16 | #include <qpe/timeconversion.h> |
17 | 17 | ||
18 | #include "otodoaccessxml.h" | 18 | #include "otodoaccessxml.h" |
19 | 19 | ||
20 | namespace { | ||
21 | // FROM TT again | ||
22 | char *strstrlen(const char *haystack, int hLen, const char* needle, int nLen) | ||
23 | { | ||
24 | char needleChar; | ||
25 | char haystackChar; | ||
26 | if (!needle || !haystack || !hLen || !nLen) | ||
27 | return 0; | ||
28 | |||
29 | const char* hsearch = haystack; | ||
30 | |||
31 | if ((needleChar = *needle++) != 0) { | ||
32 | nLen--; //(to make up for needle++) | ||
33 | do { | ||
34 | do { | ||
35 | if ((haystackChar = *hsearch++) == 0) | ||
36 | return (0); | ||
37 | if (hsearch >= haystack + hLen) | ||
38 | return (0); | ||
39 | } while (haystackChar != needleChar); | ||
40 | } while (strncmp(hsearch, needle, QMIN(hLen - (hsearch - haystack), nLen)) != 0); | ||
41 | hsearch--; | ||
42 | } | ||
43 | return ((char *)hsearch); | ||
44 | } | ||
45 | } | ||
46 | |||
47 | |||
20 | OTodoAccessXML::OTodoAccessXML( const QString& appName, | 48 | OTodoAccessXML::OTodoAccessXML( const QString& appName, |
21 | const QString& fileName ) | 49 | const QString& fileName ) |
22 | : OTodoAccessBackend(), m_app( appName ), m_opened( false ), m_changed( false ) | 50 | : OTodoAccessBackend(), m_app( appName ), m_opened( false ), m_changed( false ) |
23 | { | 51 | { |
24 | if (!fileName.isEmpty() ) | 52 | if (!fileName.isEmpty() ) |
25 | m_file = fileName; | 53 | m_file = fileName; |
26 | else | 54 | else |
27 | m_file = Global::applicationFileName( "todolist", "todolist.xml" ); | 55 | m_file = Global::applicationFileName( "todolist", "todolist.xml" ); |
28 | } | 56 | } |
29 | OTodoAccessXML::~OTodoAccessXML() { | 57 | OTodoAccessXML::~OTodoAccessXML() { |
30 | 58 | ||
31 | } | 59 | } |
32 | bool OTodoAccessXML::load() { | 60 | bool OTodoAccessXML::load() { |
33 | m_opened = true; | 61 | m_opened = true; |
34 | m_changed = false; | 62 | m_changed = false; |
35 | /* initialize dict */ | 63 | /* initialize dict */ |
36 | /* | 64 | /* |
37 | * UPDATE dict if you change anything!!! | 65 | * UPDATE dict if you change anything!!! |
38 | */ | 66 | */ |
39 | QAsciiDict<int> dict(21); | 67 | QAsciiDict<int> dict(21); |
40 | dict.setAutoDelete( TRUE ); | 68 | dict.setAutoDelete( TRUE ); |
41 | dict.insert("Categories" , new int(OTodo::Category) ); | 69 | dict.insert("Categories" , new int(OTodo::Category) ); |
42 | dict.insert("Uid" , new int(OTodo::Uid) ); | 70 | dict.insert("Uid" , new int(OTodo::Uid) ); |
43 | dict.insert("HasDate" , new int(OTodo::HasDate) ); | 71 | dict.insert("HasDate" , new int(OTodo::HasDate) ); |
44 | dict.insert("Completed" , new int(OTodo::Completed) ); | 72 | dict.insert("Completed" , new int(OTodo::Completed) ); |
45 | dict.insert("Description" , new int(OTodo::Description) ); | 73 | dict.insert("Description" , new int(OTodo::Description) ); |
46 | dict.insert("Summary" , new int(OTodo::Summary) ); | 74 | dict.insert("Summary" , new int(OTodo::Summary) ); |
47 | dict.insert("Priority" , new int(OTodo::Priority) ); | 75 | dict.insert("Priority" , new int(OTodo::Priority) ); |
48 | dict.insert("DateDay" , new int(OTodo::DateDay) ); | 76 | dict.insert("DateDay" , new int(OTodo::DateDay) ); |
49 | dict.insert("DateMonth" , new int(OTodo::DateMonth) ); | 77 | dict.insert("DateMonth" , new int(OTodo::DateMonth) ); |
50 | dict.insert("DateYear" , new int(OTodo::DateYear) ); | 78 | dict.insert("DateYear" , new int(OTodo::DateYear) ); |
51 | dict.insert("Progress" , new int(OTodo::Progress) ); | 79 | dict.insert("Progress" , new int(OTodo::Progress) ); |
52 | dict.insert("Completed", new int(OTodo::Completed) ); | 80 | dict.insert("Completed", new int(OTodo::Completed) ); |
53 | dict.insert("CrossReference", new int(OTodo::CrossReference) ); | 81 | dict.insert("CrossReference", new int(OTodo::CrossReference) ); |
54 | dict.insert("State", new int(OTodo::State) ); | 82 | dict.insert("State", new int(OTodo::State) ); |
55 | dict.insert("Recurrence", new int(OTodo::Recurrence) ); | 83 | dict.insert("Recurrence", new int(OTodo::Recurrence) ); |
56 | dict.insert("Alarms", new int(OTodo::Alarms) ); | 84 | dict.insert("Alarms", new int(OTodo::Alarms) ); |
57 | dict.insert("Reminders", new int(OTodo::Reminders) ); | 85 | dict.insert("Reminders", new int(OTodo::Reminders) ); |
58 | dict.insert("Notifiers", new int(OTodo::Notifiers) ); | 86 | dict.insert("Notifiers", new int(OTodo::Notifiers) ); |
59 | dict.insert("Maintainer", new int(OTodo::Maintainer) ); | 87 | dict.insert("Maintainer", new int(OTodo::Maintainer) ); |
60 | 88 | ||
61 | // here the custom XML parser from TT it's GPL | 89 | // here the custom XML parser from TT it's GPL |
62 | // but we want to push OpiePIM... to TT..... | 90 | // but we want to push OpiePIM... to TT..... |
63 | // mmap part from zecke :) | 91 | // mmap part from zecke :) |
64 | int fd = ::open( QFile::encodeName(m_file).data(), O_RDONLY ); | 92 | int fd = ::open( QFile::encodeName(m_file).data(), O_RDONLY ); |
65 | struct stat attribut; | 93 | struct stat attribut; |
66 | if ( fd < 0 ) return false; | 94 | if ( fd < 0 ) return false; |
67 | 95 | ||
68 | if ( fstat(fd, &attribut ) == -1 ) { | 96 | if ( fstat(fd, &attribut ) == -1 ) { |
69 | ::close( fd ); | 97 | ::close( fd ); |
70 | return false; | 98 | return false; |
71 | } | 99 | } |
72 | void* map_addr = ::mmap(NULL, attribut.st_size, PROT_READ, MAP_SHARED, fd, 0 ); | 100 | void* map_addr = ::mmap(NULL, attribut.st_size, PROT_READ, MAP_SHARED, fd, 0 ); |
73 | if ( map_addr == ( (caddr_t)-1) ) { | 101 | if ( map_addr == ( (caddr_t)-1) ) { |
74 | ::close(fd ); | 102 | ::close(fd ); |
75 | return false; | 103 | return false; |
76 | } | 104 | } |
77 | /* advise the kernel who we want to read it */ | 105 | /* advise the kernel who we want to read it */ |
78 | ::madvise( map_addr, attribut.st_size, MADV_SEQUENTIAL ); | 106 | ::madvise( map_addr, attribut.st_size, MADV_SEQUENTIAL ); |
79 | /* we do not the file any more */ | 107 | /* we do not the file any more */ |
80 | ::close( fd ); | 108 | ::close( fd ); |
81 | 109 | ||
82 | char* dt = (char*)map_addr; | 110 | char* dt = (char*)map_addr; |
83 | int len = attribut.st_size; | 111 | int len = attribut.st_size; |
84 | int i = 0; | 112 | int i = 0; |
85 | char *point; | 113 | char *point; |
86 | const char* collectionString = "<Task "; | 114 | const char* collectionString = "<Task "; |
87 | int strLen = strlen(collectionString); | 115 | int strLen = strlen(collectionString); |
88 | while ( dt+i != 0 && ( point = strstr( dt+i, collectionString ) ) != 0l ) { | 116 | while ( ( point = strstrlen( dt+i, len -i, collectionString, strLen ) ) != 0l ) { |
89 | i = point -dt; | 117 | i = point -dt; |
90 | i+= strLen; | 118 | i+= strLen; |
91 | qWarning("Found a start at %d %d", i, (point-dt) ); | 119 | qWarning("Found a start at %d %d", i, (point-dt) ); |
92 | 120 | ||
93 | OTodo ev; | 121 | OTodo ev; |
94 | m_year = m_month = m_day = 0; | 122 | m_year = m_month = m_day = 0; |
95 | 123 | ||
96 | while ( TRUE ) { | 124 | while ( TRUE ) { |
97 | while ( i < len && (dt[i] == ' ' || dt[i] == '\n' || dt[i] == '\r') ) | 125 | while ( i < len && (dt[i] == ' ' || dt[i] == '\n' || dt[i] == '\r') ) |
98 | ++i; | 126 | ++i; |
99 | if ( i >= len-2 || (dt[i] == '/' && dt[i+1] == '>') ) | 127 | if ( i >= len-2 || (dt[i] == '/' && dt[i+1] == '>') ) |
100 | break; | 128 | break; |
101 | 129 | ||
102 | // we have another attribute, read it. | 130 | // we have another attribute, read it. |
103 | int j = i; | 131 | int j = i; |
104 | while ( j < len && dt[j] != '=' ) | 132 | while ( j < len && dt[j] != '=' ) |
105 | ++j; | 133 | ++j; |
106 | QCString attr( dt+i, j-i+1); | 134 | QCString attr( dt+i, j-i+1); |
107 | 135 | ||
108 | i = ++j; // skip = | 136 | i = ++j; // skip = |
109 | 137 | ||
110 | // find the start of quotes | 138 | // find the start of quotes |
111 | while ( i < len && dt[i] != '"' ) | 139 | while ( i < len && dt[i] != '"' ) |
112 | ++i; | 140 | ++i; |
113 | j = ++i; | 141 | j = ++i; |
114 | 142 | ||
115 | bool haveUtf = FALSE; | 143 | bool haveUtf = FALSE; |
116 | bool haveEnt = FALSE; | 144 | bool haveEnt = FALSE; |
117 | while ( j < len && dt[j] != '"' ) { | 145 | while ( j < len && dt[j] != '"' ) { |
118 | if ( ((unsigned char)dt[j]) > 0x7f ) | 146 | if ( ((unsigned char)dt[j]) > 0x7f ) |
119 | haveUtf = TRUE; | 147 | haveUtf = TRUE; |
120 | if ( dt[j] == '&' ) | 148 | if ( dt[j] == '&' ) |
121 | haveEnt = TRUE; | 149 | haveEnt = TRUE; |
122 | ++j; | 150 | ++j; |
123 | } | 151 | } |
124 | if ( i == j ) { | 152 | if ( i == j ) { |
125 | // empty value | 153 | // empty value |
126 | i = j + 1; | 154 | i = j + 1; |
127 | continue; | 155 | continue; |
128 | } | 156 | } |
129 | 157 | ||
130 | QCString value( dt+i, j-i+1 ); | 158 | QCString value( dt+i, j-i+1 ); |
131 | i = j + 1; | 159 | i = j + 1; |
132 | 160 | ||
133 | QString str = (haveUtf ? QString::fromUtf8( value ) | 161 | QString str = (haveUtf ? QString::fromUtf8( value ) |
134 | : QString::fromLatin1( value ) ); | 162 | : QString::fromLatin1( value ) ); |
135 | if ( haveEnt ) | 163 | if ( haveEnt ) |
136 | str = Qtopia::plainString( str ); | 164 | str = Qtopia::plainString( str ); |
diff --git a/libopie/pim/test/oevent_test.cpp b/libopie/pim/test/oevent_test.cpp index 247b83b..d83ee0b 100644 --- a/libopie/pim/test/oevent_test.cpp +++ b/libopie/pim/test/oevent_test.cpp | |||
@@ -1,54 +1,33 @@ | |||
1 | #include <qdatetime.h> | 1 | #include <qdatetime.h> |
2 | 2 | ||
3 | #include "../oevent.h" | 3 | #include "../oevent.h" |
4 | #include "../odatebookaccess.h" | 4 | #include "../odatebookaccess.h" |
5 | 5 | ||
6 | int main(int argc, char* argv ) { | 6 | int main(int argc, char* argv ) { |
7 | OEvent ev; | ||
8 | // ev.setUid( 20 ); | ||
9 | |||
10 | ev.setDescription( "Foo Descsfewrf" ); | ||
11 | |||
12 | OEvent ev2 = ev; | ||
13 | ev2.setDescription("Foo3"); | ||
14 | qWarning("%s", ev2.description().latin1() ); | ||
15 | qWarning("%s", ev.description().latin1() ); | ||
16 | |||
17 | QDateTime time = QDateTime::currentDateTime(); | ||
18 | ev2.setStartDateTime( time ); | ||
19 | ev2.setTimeZone( "Europe/London" ); | ||
20 | |||
21 | qWarning("%s", ev2.startDateTime().toString().latin1() ); | ||
22 | qWarning("%s", ev2.startDateTimeInZone().toString().latin1() ); | ||
23 | qWarning("%d %d", ev.isAllDay(), ev2.isAllDay() ); | ||
24 | |||
25 | ODateBookAccess acc; | 7 | ODateBookAccess acc; |
26 | if(!acc.load() ) qWarning("could not load"); | 8 | if(!acc.load() ) qWarning("could not load"); |
27 | 9 | ||
28 | ODateBookAccess::List::Iterator it; | 10 | ODateBookAccess::List::Iterator it; |
29 | ODateBookAccess::List list = acc.allRecords(); | 11 | ODateBookAccess::List list = acc.allRecords(); |
30 | 12 | ||
31 | for( it = list.begin(); it != list.end(); ++it ){ | 13 | for( it = list.begin(); it != list.end(); ++it ){ |
32 | OEvent ev = (*it); | 14 | OEvent ev = (*it); |
33 | qWarning("Summary: %s",ev.description().latin1() ); | 15 | qWarning("Summary: %s",ev.description().latin1() ); |
34 | qWarning("Start: %s End: %s",ev.startDateTime().toString().latin1(), ev.endDateTime().toString().latin1() ); | 16 | qWarning("Start: %s End: %s",ev.startDateTime().toString().latin1(), ev.endDateTime().toString().latin1() ); |
35 | qWarning("All Day: %d",ev.isAllDay() ); | 17 | qWarning("All Day: %d",ev.isAllDay() ); |
36 | 18 | ||
37 | } | 19 | } |
38 | QDate date1(2003,02,01 ); | 20 | QDate date1(2003,02,01 ); |
39 | QDate date2(2003,03,01 ); | 21 | QDate date2(2003,03,01 ); |
40 | 22 | ||
41 | OEffectiveEvent::ValueList effList = acc.effectiveEvents( date1,date2 ); | 23 | OEffectiveEvent::ValueList effList = acc.effectiveEvents( date1,date2 ); |
42 | OEffectiveEvent::ValueList::Iterator effIt; | 24 | OEffectiveEvent::ValueList::Iterator effIt; |
43 | 25 | ||
44 | for( effIt = effList.begin(); effIt != effList.end(); ++effIt ){ | 26 | for( effIt = effList.begin(); effIt != effList.end(); ++effIt ){ |
45 | OEffectiveEvent ef = (*effIt); | 27 | OEffectiveEvent ef = (*effIt); |
46 | qWarning("Summary: %s", ef.description().latin1() ); | 28 | qWarning("Summary: %s", ef.description().latin1() ); |
47 | qWarning("Date: %s", ef.date().toString().latin1() ); | 29 | qWarning("Date: %s", ef.date().toString().latin1() ); |
48 | } | 30 | } |
49 | ev.setUid( 1 ); | ||
50 | acc.add( ev ); | ||
51 | acc.save(); | ||
52 | 31 | ||
53 | return 0; | 32 | return 0; |
54 | } | 33 | } |
diff --git a/libopie2/opiepim/backend/odatebookaccessbackend_xml.cpp b/libopie2/opiepim/backend/odatebookaccessbackend_xml.cpp index bc51996..24b69fe 100644 --- a/libopie2/opiepim/backend/odatebookaccessbackend_xml.cpp +++ b/libopie2/opiepim/backend/odatebookaccessbackend_xml.cpp | |||
@@ -1,73 +1,100 @@ | |||
1 | #include <errno.h> | 1 | #include <errno.h> |
2 | #include <fcntl.h> | 2 | #include <fcntl.h> |
3 | 3 | ||
4 | #include <stdio.h> | 4 | #include <stdio.h> |
5 | #include <stdlib.h> | 5 | #include <stdlib.h> |
6 | 6 | ||
7 | #include <sys/types.h> | 7 | #include <sys/types.h> |
8 | #include <sys/mman.h> | 8 | #include <sys/mman.h> |
9 | #include <sys/stat.h> | 9 | #include <sys/stat.h> |
10 | 10 | ||
11 | #include <unistd.h> | 11 | #include <unistd.h> |
12 | 12 | ||
13 | #include <qasciidict.h> | 13 | #include <qasciidict.h> |
14 | #include <qfile.h> | 14 | #include <qfile.h> |
15 | 15 | ||
16 | #include <qtopia/global.h> | 16 | #include <qtopia/global.h> |
17 | #include <qtopia/stringutil.h> | 17 | #include <qtopia/stringutil.h> |
18 | #include <qtopia/timeconversion.h> | 18 | #include <qtopia/timeconversion.h> |
19 | 19 | ||
20 | #include "opimnotifymanager.h" | 20 | #include "opimnotifymanager.h" |
21 | #include "orecur.h" | 21 | #include "orecur.h" |
22 | #include "otimezone.h" | 22 | #include "otimezone.h" |
23 | #include "odatebookaccessbackend_xml.h" | 23 | #include "odatebookaccessbackend_xml.h" |
24 | 24 | ||
25 | namespace { | 25 | namespace { |
26 | // FROM TT again | ||
27 | char *strstrlen(const char *haystack, int hLen, const char* needle, int nLen) | ||
28 | { | ||
29 | char needleChar; | ||
30 | char haystackChar; | ||
31 | if (!needle || !haystack || !hLen || !nLen) | ||
32 | return 0; | ||
33 | |||
34 | const char* hsearch = haystack; | ||
35 | |||
36 | if ((needleChar = *needle++) != 0) { | ||
37 | nLen--; //(to make up for needle++) | ||
38 | do { | ||
39 | do { | ||
40 | if ((haystackChar = *hsearch++) == 0) | ||
41 | return (0); | ||
42 | if (hsearch >= haystack + hLen) | ||
43 | return (0); | ||
44 | } while (haystackChar != needleChar); | ||
45 | } while (strncmp(hsearch, needle, QMIN(hLen - (hsearch - haystack), nLen)) != 0); | ||
46 | hsearch--; | ||
47 | } | ||
48 | return ((char *)hsearch); | ||
49 | } | ||
50 | } | ||
51 | |||
52 | namespace { | ||
26 | time_t start, end, created, rp_end; | 53 | time_t start, end, created, rp_end; |
27 | ORecur* rec; | 54 | ORecur* rec; |
28 | ORecur* recur() { | 55 | ORecur* recur() { |
29 | if (!rec) | 56 | if (!rec) |
30 | rec = new ORecur; | 57 | rec = new ORecur; |
31 | 58 | ||
32 | return rec; | 59 | return rec; |
33 | } | 60 | } |
34 | int alarmTime; | 61 | int alarmTime; |
35 | int snd; | 62 | int snd; |
36 | enum Attribute{ | 63 | enum Attribute{ |
37 | FDescription = 0, | 64 | FDescription = 0, |
38 | FLocation, | 65 | FLocation, |
39 | FCategories, | 66 | FCategories, |
40 | FUid, | 67 | FUid, |
41 | FType, | 68 | FType, |
42 | FAlarm, | 69 | FAlarm, |
43 | FSound, | 70 | FSound, |
44 | FRType, | 71 | FRType, |
45 | FRWeekdays, | 72 | FRWeekdays, |
46 | FRPosition, | 73 | FRPosition, |
47 | FRFreq, | 74 | FRFreq, |
48 | FRHasEndDate, | 75 | FRHasEndDate, |
49 | FREndDate, | 76 | FREndDate, |
50 | FRStart, | 77 | FRStart, |
51 | FREnd, | 78 | FREnd, |
52 | FNote, | 79 | FNote, |
53 | FCreated, | 80 | FCreated, |
54 | FTimeZone, | 81 | FTimeZone, |
55 | FRecParent, | 82 | FRecParent, |
56 | FRecChildren, | 83 | FRecChildren, |
57 | FExceptions | 84 | FExceptions |
58 | }; | 85 | }; |
59 | inline void save( const OEvent& ev, QString& buf ) { | 86 | inline void save( const OEvent& ev, QString& buf ) { |
60 | buf += " description=\"" + Qtopia::escapeString(ev.description() ) + "\""; | 87 | buf += " description=\"" + Qtopia::escapeString(ev.description() ) + "\""; |
61 | if (!ev.location().isEmpty() ) | 88 | if (!ev.location().isEmpty() ) |
62 | buf += " location=\"" + Qtopia::escapeString(ev.location() ) + "\""; | 89 | buf += " location=\"" + Qtopia::escapeString(ev.location() ) + "\""; |
63 | 90 | ||
64 | buf += " categories=\""+ Qtopia::escapeString( Qtopia::Record::idsToString( ev.categories() ) ) + "\""; | 91 | buf += " categories=\""+ Qtopia::escapeString( Qtopia::Record::idsToString( ev.categories() ) ) + "\""; |
65 | buf += " uid=\"" + QString::number( ev.uid() ) + "\""; | 92 | buf += " uid=\"" + QString::number( ev.uid() ) + "\""; |
66 | 93 | ||
67 | if (ev.isAllDay() ) | 94 | if (ev.isAllDay() ) |
68 | buf += " type=\"AllDay\""; | 95 | buf += " type=\"AllDay\""; |
69 | 96 | ||
70 | if (ev.hasNotifiers() ) { | 97 | if (ev.hasNotifiers() ) { |
71 | OPimAlarm alarm = ev.notifiers().alarms()[0]; // take only the first | 98 | OPimAlarm alarm = ev.notifiers().alarms()[0]; // take only the first |
72 | int minutes = alarm.dateTime().secsTo( ev.startDateTime() ) / 60; | 99 | int minutes = alarm.dateTime().secsTo( ev.startDateTime() ) / 60; |
73 | buf += " alarm=\"" + QString::number(minutes) + "\" sound=\""; | 100 | buf += " alarm=\"" + QString::number(minutes) + "\" sound=\""; |
@@ -297,97 +324,97 @@ bool ODateBookAccessBackend_XML::loadFile() { | |||
297 | int fd = ::open( QFile::encodeName(m_name).data(), O_RDONLY ); | 324 | int fd = ::open( QFile::encodeName(m_name).data(), O_RDONLY ); |
298 | if ( fd < 0 ) return false; | 325 | if ( fd < 0 ) return false; |
299 | 326 | ||
300 | struct stat attribute; | 327 | struct stat attribute; |
301 | if ( ::fstat(fd, &attribute ) == -1 ) { | 328 | if ( ::fstat(fd, &attribute ) == -1 ) { |
302 | ::close( fd ); | 329 | ::close( fd ); |
303 | return false; | 330 | return false; |
304 | } | 331 | } |
305 | void* map_addr = ::mmap(NULL, attribute.st_size, PROT_READ, MAP_SHARED, fd, 0 ); | 332 | void* map_addr = ::mmap(NULL, attribute.st_size, PROT_READ, MAP_SHARED, fd, 0 ); |
306 | if ( map_addr == ( (caddr_t)-1) ) { | 333 | if ( map_addr == ( (caddr_t)-1) ) { |
307 | ::close( fd ); | 334 | ::close( fd ); |
308 | return false; | 335 | return false; |
309 | } | 336 | } |
310 | 337 | ||
311 | ::madvise( map_addr, attribute.st_size, MADV_SEQUENTIAL ); | 338 | ::madvise( map_addr, attribute.st_size, MADV_SEQUENTIAL ); |
312 | ::close( fd ); | 339 | ::close( fd ); |
313 | 340 | ||
314 | QAsciiDict<int> dict(FExceptions+1); | 341 | QAsciiDict<int> dict(FExceptions+1); |
315 | dict.setAutoDelete( true ); | 342 | dict.setAutoDelete( true ); |
316 | dict.insert( "description", new int(FDescription) ); | 343 | dict.insert( "description", new int(FDescription) ); |
317 | dict.insert( "location", new int(FLocation) ); | 344 | dict.insert( "location", new int(FLocation) ); |
318 | dict.insert( "categories", new int(FCategories) ); | 345 | dict.insert( "categories", new int(FCategories) ); |
319 | dict.insert( "uid", new int(FUid) ); | 346 | dict.insert( "uid", new int(FUid) ); |
320 | dict.insert( "type", new int(FType) ); | 347 | dict.insert( "type", new int(FType) ); |
321 | dict.insert( "alarm", new int(FAlarm) ); | 348 | dict.insert( "alarm", new int(FAlarm) ); |
322 | dict.insert( "sound", new int(FSound) ); | 349 | dict.insert( "sound", new int(FSound) ); |
323 | dict.insert( "rtype", new int(FRType) ); | 350 | dict.insert( "rtype", new int(FRType) ); |
324 | dict.insert( "rweekdays", new int(FRWeekdays) ); | 351 | dict.insert( "rweekdays", new int(FRWeekdays) ); |
325 | dict.insert( "rposition", new int(FRPosition) ); | 352 | dict.insert( "rposition", new int(FRPosition) ); |
326 | dict.insert( "rfreq", new int(FRFreq) ); | 353 | dict.insert( "rfreq", new int(FRFreq) ); |
327 | dict.insert( "rhasenddate", new int(FRHasEndDate) ); | 354 | dict.insert( "rhasenddate", new int(FRHasEndDate) ); |
328 | dict.insert( "enddt", new int(FREndDate) ); | 355 | dict.insert( "enddt", new int(FREndDate) ); |
329 | dict.insert( "start", new int(FRStart) ); | 356 | dict.insert( "start", new int(FRStart) ); |
330 | dict.insert( "end", new int(FREnd) ); | 357 | dict.insert( "end", new int(FREnd) ); |
331 | dict.insert( "note", new int(FNote) ); | 358 | dict.insert( "note", new int(FNote) ); |
332 | dict.insert( "created", new int(FCreated) ); | 359 | dict.insert( "created", new int(FCreated) ); |
333 | dict.insert( "recparent", new int(FRecParent) ); | 360 | dict.insert( "recparent", new int(FRecParent) ); |
334 | dict.insert( "recchildren", new int(FRecChildren) ); | 361 | dict.insert( "recchildren", new int(FRecChildren) ); |
335 | dict.insert( "exceptions", new int(FExceptions) ); | 362 | dict.insert( "exceptions", new int(FExceptions) ); |
336 | dict.insert( "timezone", new int(FTimeZone) ); | 363 | dict.insert( "timezone", new int(FTimeZone) ); |
337 | 364 | ||
338 | char* dt = (char*)map_addr; | 365 | char* dt = (char*)map_addr; |
339 | int len = attribute.st_size; | 366 | int len = attribute.st_size; |
340 | int i = 0; | 367 | int i = 0; |
341 | char* point; | 368 | char* point; |
342 | const char* collectionString = "<event "; | 369 | const char* collectionString = "<event "; |
343 | int strLen = ::strlen(collectionString); | 370 | int strLen = ::strlen(collectionString); |
344 | int *find; | 371 | int *find; |
345 | while ( dt + 1 != 0 && (( point = ::strstr( dt+i, collectionString ) ) != 0 ) ) { | 372 | while ( ( point = ::strstrlen( dt+i, len -i, collectionString, strLen ) ) != 0 ) { |
346 | i = point -dt; | 373 | i = point -dt; |
347 | i+= strLen; | 374 | i+= strLen; |
348 | 375 | ||
349 | alarmTime = -1; | 376 | alarmTime = -1; |
350 | snd = 0; // silent | 377 | snd = 0; // silent |
351 | 378 | ||
352 | OEvent ev; | 379 | OEvent ev; |
353 | rec = 0; | 380 | rec = 0; |
354 | 381 | ||
355 | while ( TRUE ) { | 382 | while ( TRUE ) { |
356 | while ( i < len && (dt[i] == ' ' || dt[i] == '\n' || dt[i] == '\r') ) | 383 | while ( i < len && (dt[i] == ' ' || dt[i] == '\n' || dt[i] == '\r') ) |
357 | ++i; | 384 | ++i; |
358 | if ( i >= len-2 || (dt[i] == '/' && dt[i+1] == '>') ) | 385 | if ( i >= len-2 || (dt[i] == '/' && dt[i+1] == '>') ) |
359 | break; | 386 | break; |
360 | 387 | ||
361 | 388 | ||
362 | // we have another attribute, read it. | 389 | // we have another attribute, read it. |
363 | int j = i; | 390 | int j = i; |
364 | while ( j < len && dt[j] != '=' ) | 391 | while ( j < len && dt[j] != '=' ) |
365 | ++j; | 392 | ++j; |
366 | QCString attr( dt+i, j-i+1); | 393 | QCString attr( dt+i, j-i+1); |
367 | 394 | ||
368 | i = ++j; // skip = | 395 | i = ++j; // skip = |
369 | 396 | ||
370 | // find the start of quotes | 397 | // find the start of quotes |
371 | while ( i < len && dt[i] != '"' ) | 398 | while ( i < len && dt[i] != '"' ) |
372 | ++i; | 399 | ++i; |
373 | j = ++i; | 400 | j = ++i; |
374 | 401 | ||
375 | bool haveUtf = FALSE; | 402 | bool haveUtf = FALSE; |
376 | bool haveEnt = FALSE; | 403 | bool haveEnt = FALSE; |
377 | while ( j < len && dt[j] != '"' ) { | 404 | while ( j < len && dt[j] != '"' ) { |
378 | if ( ((unsigned char)dt[j]) > 0x7f ) | 405 | if ( ((unsigned char)dt[j]) > 0x7f ) |
379 | haveUtf = TRUE; | 406 | haveUtf = TRUE; |
380 | if ( dt[j] == '&' ) | 407 | if ( dt[j] == '&' ) |
381 | haveEnt = TRUE; | 408 | haveEnt = TRUE; |
382 | ++j; | 409 | ++j; |
383 | } | 410 | } |
384 | if ( i == j ) { | 411 | if ( i == j ) { |
385 | // empty value | 412 | // empty value |
386 | i = j + 1; | 413 | i = j + 1; |
387 | continue; | 414 | continue; |
388 | } | 415 | } |
389 | 416 | ||
390 | QCString value( dt+i, j-i+1 ); | 417 | QCString value( dt+i, j-i+1 ); |
391 | i = j + 1; | 418 | i = j + 1; |
392 | 419 | ||
393 | QString str = (haveUtf ? QString::fromUtf8( value ) | 420 | QString str = (haveUtf ? QString::fromUtf8( value ) |
diff --git a/libopie2/opiepim/backend/otodoaccessxml.cpp b/libopie2/opiepim/backend/otodoaccessxml.cpp index 22b2469..cda300b 100644 --- a/libopie2/opiepim/backend/otodoaccessxml.cpp +++ b/libopie2/opiepim/backend/otodoaccessxml.cpp | |||
@@ -1,136 +1,164 @@ | |||
1 | #include <errno.h> | 1 | #include <errno.h> |
2 | #include <fcntl.h> | 2 | #include <fcntl.h> |
3 | 3 | ||
4 | #include <sys/mman.h> | 4 | #include <sys/mman.h> |
5 | #include <sys/stat.h> | 5 | #include <sys/stat.h> |
6 | #include <sys/types.h> | 6 | #include <sys/types.h> |
7 | 7 | ||
8 | #include <unistd.h> | 8 | #include <unistd.h> |
9 | 9 | ||
10 | 10 | ||
11 | #include <qfile.h> | 11 | #include <qfile.h> |
12 | #include <qvector.h> | 12 | #include <qvector.h> |
13 | 13 | ||
14 | #include <qpe/global.h> | 14 | #include <qpe/global.h> |
15 | #include <qpe/stringutil.h> | 15 | #include <qpe/stringutil.h> |
16 | #include <qpe/timeconversion.h> | 16 | #include <qpe/timeconversion.h> |
17 | 17 | ||
18 | #include "otodoaccessxml.h" | 18 | #include "otodoaccessxml.h" |
19 | 19 | ||
20 | namespace { | ||
21 | // FROM TT again | ||
22 | char *strstrlen(const char *haystack, int hLen, const char* needle, int nLen) | ||
23 | { | ||
24 | char needleChar; | ||
25 | char haystackChar; | ||
26 | if (!needle || !haystack || !hLen || !nLen) | ||
27 | return 0; | ||
28 | |||
29 | const char* hsearch = haystack; | ||
30 | |||
31 | if ((needleChar = *needle++) != 0) { | ||
32 | nLen--; //(to make up for needle++) | ||
33 | do { | ||
34 | do { | ||
35 | if ((haystackChar = *hsearch++) == 0) | ||
36 | return (0); | ||
37 | if (hsearch >= haystack + hLen) | ||
38 | return (0); | ||
39 | } while (haystackChar != needleChar); | ||
40 | } while (strncmp(hsearch, needle, QMIN(hLen - (hsearch - haystack), nLen)) != 0); | ||
41 | hsearch--; | ||
42 | } | ||
43 | return ((char *)hsearch); | ||
44 | } | ||
45 | } | ||
46 | |||
47 | |||
20 | OTodoAccessXML::OTodoAccessXML( const QString& appName, | 48 | OTodoAccessXML::OTodoAccessXML( const QString& appName, |
21 | const QString& fileName ) | 49 | const QString& fileName ) |
22 | : OTodoAccessBackend(), m_app( appName ), m_opened( false ), m_changed( false ) | 50 | : OTodoAccessBackend(), m_app( appName ), m_opened( false ), m_changed( false ) |
23 | { | 51 | { |
24 | if (!fileName.isEmpty() ) | 52 | if (!fileName.isEmpty() ) |
25 | m_file = fileName; | 53 | m_file = fileName; |
26 | else | 54 | else |
27 | m_file = Global::applicationFileName( "todolist", "todolist.xml" ); | 55 | m_file = Global::applicationFileName( "todolist", "todolist.xml" ); |
28 | } | 56 | } |
29 | OTodoAccessXML::~OTodoAccessXML() { | 57 | OTodoAccessXML::~OTodoAccessXML() { |
30 | 58 | ||
31 | } | 59 | } |
32 | bool OTodoAccessXML::load() { | 60 | bool OTodoAccessXML::load() { |
33 | m_opened = true; | 61 | m_opened = true; |
34 | m_changed = false; | 62 | m_changed = false; |
35 | /* initialize dict */ | 63 | /* initialize dict */ |
36 | /* | 64 | /* |
37 | * UPDATE dict if you change anything!!! | 65 | * UPDATE dict if you change anything!!! |
38 | */ | 66 | */ |
39 | QAsciiDict<int> dict(21); | 67 | QAsciiDict<int> dict(21); |
40 | dict.setAutoDelete( TRUE ); | 68 | dict.setAutoDelete( TRUE ); |
41 | dict.insert("Categories" , new int(OTodo::Category) ); | 69 | dict.insert("Categories" , new int(OTodo::Category) ); |
42 | dict.insert("Uid" , new int(OTodo::Uid) ); | 70 | dict.insert("Uid" , new int(OTodo::Uid) ); |
43 | dict.insert("HasDate" , new int(OTodo::HasDate) ); | 71 | dict.insert("HasDate" , new int(OTodo::HasDate) ); |
44 | dict.insert("Completed" , new int(OTodo::Completed) ); | 72 | dict.insert("Completed" , new int(OTodo::Completed) ); |
45 | dict.insert("Description" , new int(OTodo::Description) ); | 73 | dict.insert("Description" , new int(OTodo::Description) ); |
46 | dict.insert("Summary" , new int(OTodo::Summary) ); | 74 | dict.insert("Summary" , new int(OTodo::Summary) ); |
47 | dict.insert("Priority" , new int(OTodo::Priority) ); | 75 | dict.insert("Priority" , new int(OTodo::Priority) ); |
48 | dict.insert("DateDay" , new int(OTodo::DateDay) ); | 76 | dict.insert("DateDay" , new int(OTodo::DateDay) ); |
49 | dict.insert("DateMonth" , new int(OTodo::DateMonth) ); | 77 | dict.insert("DateMonth" , new int(OTodo::DateMonth) ); |
50 | dict.insert("DateYear" , new int(OTodo::DateYear) ); | 78 | dict.insert("DateYear" , new int(OTodo::DateYear) ); |
51 | dict.insert("Progress" , new int(OTodo::Progress) ); | 79 | dict.insert("Progress" , new int(OTodo::Progress) ); |
52 | dict.insert("Completed", new int(OTodo::Completed) ); | 80 | dict.insert("Completed", new int(OTodo::Completed) ); |
53 | dict.insert("CrossReference", new int(OTodo::CrossReference) ); | 81 | dict.insert("CrossReference", new int(OTodo::CrossReference) ); |
54 | dict.insert("State", new int(OTodo::State) ); | 82 | dict.insert("State", new int(OTodo::State) ); |
55 | dict.insert("Recurrence", new int(OTodo::Recurrence) ); | 83 | dict.insert("Recurrence", new int(OTodo::Recurrence) ); |
56 | dict.insert("Alarms", new int(OTodo::Alarms) ); | 84 | dict.insert("Alarms", new int(OTodo::Alarms) ); |
57 | dict.insert("Reminders", new int(OTodo::Reminders) ); | 85 | dict.insert("Reminders", new int(OTodo::Reminders) ); |
58 | dict.insert("Notifiers", new int(OTodo::Notifiers) ); | 86 | dict.insert("Notifiers", new int(OTodo::Notifiers) ); |
59 | dict.insert("Maintainer", new int(OTodo::Maintainer) ); | 87 | dict.insert("Maintainer", new int(OTodo::Maintainer) ); |
60 | 88 | ||
61 | // here the custom XML parser from TT it's GPL | 89 | // here the custom XML parser from TT it's GPL |
62 | // but we want to push OpiePIM... to TT..... | 90 | // but we want to push OpiePIM... to TT..... |
63 | // mmap part from zecke :) | 91 | // mmap part from zecke :) |
64 | int fd = ::open( QFile::encodeName(m_file).data(), O_RDONLY ); | 92 | int fd = ::open( QFile::encodeName(m_file).data(), O_RDONLY ); |
65 | struct stat attribut; | 93 | struct stat attribut; |
66 | if ( fd < 0 ) return false; | 94 | if ( fd < 0 ) return false; |
67 | 95 | ||
68 | if ( fstat(fd, &attribut ) == -1 ) { | 96 | if ( fstat(fd, &attribut ) == -1 ) { |
69 | ::close( fd ); | 97 | ::close( fd ); |
70 | return false; | 98 | return false; |
71 | } | 99 | } |
72 | void* map_addr = ::mmap(NULL, attribut.st_size, PROT_READ, MAP_SHARED, fd, 0 ); | 100 | void* map_addr = ::mmap(NULL, attribut.st_size, PROT_READ, MAP_SHARED, fd, 0 ); |
73 | if ( map_addr == ( (caddr_t)-1) ) { | 101 | if ( map_addr == ( (caddr_t)-1) ) { |
74 | ::close(fd ); | 102 | ::close(fd ); |
75 | return false; | 103 | return false; |
76 | } | 104 | } |
77 | /* advise the kernel who we want to read it */ | 105 | /* advise the kernel who we want to read it */ |
78 | ::madvise( map_addr, attribut.st_size, MADV_SEQUENTIAL ); | 106 | ::madvise( map_addr, attribut.st_size, MADV_SEQUENTIAL ); |
79 | /* we do not the file any more */ | 107 | /* we do not the file any more */ |
80 | ::close( fd ); | 108 | ::close( fd ); |
81 | 109 | ||
82 | char* dt = (char*)map_addr; | 110 | char* dt = (char*)map_addr; |
83 | int len = attribut.st_size; | 111 | int len = attribut.st_size; |
84 | int i = 0; | 112 | int i = 0; |
85 | char *point; | 113 | char *point; |
86 | const char* collectionString = "<Task "; | 114 | const char* collectionString = "<Task "; |
87 | int strLen = strlen(collectionString); | 115 | int strLen = strlen(collectionString); |
88 | while ( dt+i != 0 && ( point = strstr( dt+i, collectionString ) ) != 0l ) { | 116 | while ( ( point = strstrlen( dt+i, len -i, collectionString, strLen ) ) != 0l ) { |
89 | i = point -dt; | 117 | i = point -dt; |
90 | i+= strLen; | 118 | i+= strLen; |
91 | qWarning("Found a start at %d %d", i, (point-dt) ); | 119 | qWarning("Found a start at %d %d", i, (point-dt) ); |
92 | 120 | ||
93 | OTodo ev; | 121 | OTodo ev; |
94 | m_year = m_month = m_day = 0; | 122 | m_year = m_month = m_day = 0; |
95 | 123 | ||
96 | while ( TRUE ) { | 124 | while ( TRUE ) { |
97 | while ( i < len && (dt[i] == ' ' || dt[i] == '\n' || dt[i] == '\r') ) | 125 | while ( i < len && (dt[i] == ' ' || dt[i] == '\n' || dt[i] == '\r') ) |
98 | ++i; | 126 | ++i; |
99 | if ( i >= len-2 || (dt[i] == '/' && dt[i+1] == '>') ) | 127 | if ( i >= len-2 || (dt[i] == '/' && dt[i+1] == '>') ) |
100 | break; | 128 | break; |
101 | 129 | ||
102 | // we have another attribute, read it. | 130 | // we have another attribute, read it. |
103 | int j = i; | 131 | int j = i; |
104 | while ( j < len && dt[j] != '=' ) | 132 | while ( j < len && dt[j] != '=' ) |
105 | ++j; | 133 | ++j; |
106 | QCString attr( dt+i, j-i+1); | 134 | QCString attr( dt+i, j-i+1); |
107 | 135 | ||
108 | i = ++j; // skip = | 136 | i = ++j; // skip = |
109 | 137 | ||
110 | // find the start of quotes | 138 | // find the start of quotes |
111 | while ( i < len && dt[i] != '"' ) | 139 | while ( i < len && dt[i] != '"' ) |
112 | ++i; | 140 | ++i; |
113 | j = ++i; | 141 | j = ++i; |
114 | 142 | ||
115 | bool haveUtf = FALSE; | 143 | bool haveUtf = FALSE; |
116 | bool haveEnt = FALSE; | 144 | bool haveEnt = FALSE; |
117 | while ( j < len && dt[j] != '"' ) { | 145 | while ( j < len && dt[j] != '"' ) { |
118 | if ( ((unsigned char)dt[j]) > 0x7f ) | 146 | if ( ((unsigned char)dt[j]) > 0x7f ) |
119 | haveUtf = TRUE; | 147 | haveUtf = TRUE; |
120 | if ( dt[j] == '&' ) | 148 | if ( dt[j] == '&' ) |
121 | haveEnt = TRUE; | 149 | haveEnt = TRUE; |
122 | ++j; | 150 | ++j; |
123 | } | 151 | } |
124 | if ( i == j ) { | 152 | if ( i == j ) { |
125 | // empty value | 153 | // empty value |
126 | i = j + 1; | 154 | i = j + 1; |
127 | continue; | 155 | continue; |
128 | } | 156 | } |
129 | 157 | ||
130 | QCString value( dt+i, j-i+1 ); | 158 | QCString value( dt+i, j-i+1 ); |
131 | i = j + 1; | 159 | i = j + 1; |
132 | 160 | ||
133 | QString str = (haveUtf ? QString::fromUtf8( value ) | 161 | QString str = (haveUtf ? QString::fromUtf8( value ) |
134 | : QString::fromLatin1( value ) ); | 162 | : QString::fromLatin1( value ) ); |
135 | if ( haveEnt ) | 163 | if ( haveEnt ) |
136 | str = Qtopia::plainString( str ); | 164 | str = Qtopia::plainString( str ); |