summaryrefslogtreecommitdiff
path: root/libopie2/opiepim/backend/otodoaccessxml.cpp
Unidiff
Diffstat (limited to 'libopie2/opiepim/backend/otodoaccessxml.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r--libopie2/opiepim/backend/otodoaccessxml.cpp30
1 files changed, 29 insertions, 1 deletions
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
20namespace {
21 // FROM TT again
22char *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
20OTodoAccessXML::OTodoAccessXML( const QString& appName, 48OTodoAccessXML::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}
29OTodoAccessXML::~OTodoAccessXML() { 57OTodoAccessXML::~OTodoAccessXML() {
30 58
31} 59}
32bool OTodoAccessXML::load() { 60bool 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 );