summaryrefslogtreecommitdiff
authorjgf <jgf>2003-12-18 02:43:07 (UTC)
committer jgf <jgf>2003-12-18 02:43:07 (UTC)
commitd7fed5a555f51008db8b96e8b978c3830c59be77 (patch) (unidiff)
tree9f3a8aa82909ef80cf1c42431abc20d3ac585436
parent77e353da0c33bbfabf1b919e25008d62581bf164 (diff)
downloadopie-d7fed5a555f51008db8b96e8b978c3830c59be77.zip
opie-d7fed5a555f51008db8b96e8b978c3830c59be77.tar.gz
opie-d7fed5a555f51008db8b96e8b978c3830c59be77.tar.bz2
decoding of imap folder names
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--noncore/net/mail/defines.h11
-rw-r--r--noncore/net/mail/libmailwrapper/mailwrapper.cpp107
-rw-r--r--noncore/net/mail/libmailwrapper/mailwrapper.h2
-rw-r--r--noncore/net/mail/mailwrapper.cpp107
-rw-r--r--noncore/net/mail/mailwrapper.h2
5 files changed, 201 insertions, 28 deletions
diff --git a/noncore/net/mail/defines.h b/noncore/net/mail/defines.h
index 9036658..d9cdab0 100644
--- a/noncore/net/mail/defines.h
+++ b/noncore/net/mail/defines.h
@@ -37,4 +37,15 @@
37#define NNTP_PORT "119" 37#define NNTP_PORT "119"
38#define NNTP_SSL_PORT "563" 38#define NNTP_SSL_PORT "563"
39 39
40/* used for decoding imapfoldername */
41#define UNDEFINED 64
42#define MAXLINE 76
43#define UTF16MASK 0x03FFUL
44#define UTF16SHIFT 10
45#define UTF16BASE 0x10000UL
46#define UTF16HIGHSTART 0xD800UL
47#define UTF16HIGHEND 0xDBFFUL
48#define UTF16LOSTART 0xDC00UL
49#define UTF16LOEND 0xDFFFUL
50
40#endif 51#endif
diff --git a/noncore/net/mail/libmailwrapper/mailwrapper.cpp b/noncore/net/mail/libmailwrapper/mailwrapper.cpp
index 858283f..75c06f9 100644
--- a/noncore/net/mail/libmailwrapper/mailwrapper.cpp
+++ b/noncore/net/mail/libmailwrapper/mailwrapper.cpp
@@ -21,20 +21,6 @@ Folder::Folder(const QString&tmp_name, const QString&sep )
21{ 21{
22 name = tmp_name; 22 name = tmp_name;
23 nameDisplay = name; 23 nameDisplay = name;
24
25 for ( int pos = nameDisplay.find( '&' ); pos != -1;
26 pos = nameDisplay.find( '&' ) ) {
27 int end = nameDisplay.find( '-' );
28 if ( end == -1 || end <= pos ) break;
29 QString str64 = nameDisplay.mid( pos + 1, end - pos - 1 );
30 // TODO: do real base64 decoding here !
31 if ( str64.compare( "APw" ) == 0 ) {
32 nameDisplay = nameDisplay.replace( pos, end - pos + 1, "ue" );
33 } else if ( str64.compare( "APY" ) == 0 ) {
34 nameDisplay = nameDisplay.replace( pos, end - pos + 1, "oe" );
35 }
36 }
37 qDebug( "folder " + name + " - displayed as " + nameDisplay );
38 separator = sep; 24 separator = sep;
39} 25}
40 26
@@ -46,6 +32,10 @@ const QString& Folder::Separator()const
46IMAPFolder::IMAPFolder(const QString&name,const QString&sep, bool select,const QString&prefix ) 32IMAPFolder::IMAPFolder(const QString&name,const QString&sep, bool select,const QString&prefix )
47 : Folder( name,sep ),m_MaySelect(select) 33 : Folder( name,sep ),m_MaySelect(select)
48{ 34{
35 // Decode IMAP foldername
36 nameDisplay = IMAPFolder::decodeFolderName( name );
37 qDebug( "folder " + name + " - displayed as " + nameDisplay );
38
49 if (prefix.length()>0) { 39 if (prefix.length()>0) {
50 if (nameDisplay.startsWith(prefix) && nameDisplay.length()>prefix.length()) { 40 if (nameDisplay.startsWith(prefix) && nameDisplay.length()>prefix.length()) {
51 nameDisplay=nameDisplay.right(nameDisplay.length()-prefix.length()); 41 nameDisplay=nameDisplay.right(nameDisplay.length()-prefix.length());
@@ -53,6 +43,95 @@ IMAPFolder::IMAPFolder(const QString&name,const QString&sep, bool select,const Q
53 } 43 }
54} 44}
55 45
46static unsigned char base64chars[] =
47 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+,";
48
49/**
50 * Decodes base64 encoded parts of the imapfolder name
51 * Code taken from kde cvs: kdebase/kioslave/imap4/rfcdecoder.cc
52 */
53QString IMAPFolder::decodeFolderName( const QString &name )
54{
55 unsigned char c, i, bitcount;
56 unsigned long ucs4, utf16, bitbuf;
57 unsigned char base64[256], utf8[6];
58 unsigned long srcPtr = 0;
59 QCString dst;
60 QCString src = name.ascii();
61
62 /* initialize modified base64 decoding table */
63 memset(base64, UNDEFINED, sizeof(base64));
64 for (i = 0; i < sizeof(base64chars); ++i) {
65 base64[(int)base64chars[i]] = i;
66 }
67
68 /* loop until end of string */
69 while (srcPtr < src.length ()) {
70 c = src[srcPtr++];
71 /* deal with literal characters and &- */
72 if (c != '&' || src[srcPtr] == '-') {
73 /* encode literally */
74 dst += c;
75 /* skip over the '-' if this is an &- sequence */
76 if (c == '&')
77 srcPtr++;
78 } else {
79 /* convert modified UTF-7 -> UTF-16 -> UCS-4 -> UTF-8 -> HEX */
80 bitbuf = 0;
81 bitcount = 0;
82 ucs4 = 0;
83 while ((c = base64[(unsigned char) src[srcPtr]]) != UNDEFINED) {
84 ++srcPtr;
85 bitbuf = (bitbuf << 6) | c;
86 bitcount += 6;
87 /* enough bits for a UTF-16 character? */
88 if (bitcount >= 16) {
89 bitcount -= 16;
90 utf16 = (bitcount ? bitbuf >> bitcount : bitbuf) & 0xffff;
91 /* convert UTF16 to UCS4 */
92 if (utf16 >= UTF16HIGHSTART && utf16 <= UTF16HIGHEND) {
93 ucs4 = (utf16 - UTF16HIGHSTART) << UTF16SHIFT;
94 continue;
95 } else if (utf16 >= UTF16LOSTART && utf16 <= UTF16LOEND) {
96 ucs4 += utf16 - UTF16LOSTART + UTF16BASE;
97 } else {
98 ucs4 = utf16;
99 }
100 /* convert UTF-16 range of UCS4 to UTF-8 */
101 if (ucs4 <= 0x7fUL) {
102 utf8[0] = ucs4;
103 i = 1;
104 } else if (ucs4 <= 0x7ffUL) {
105 utf8[0] = 0xc0 | (ucs4 >> 6);
106 utf8[1] = 0x80 | (ucs4 & 0x3f);
107 i = 2;
108 } else if (ucs4 <= 0xffffUL) {
109 utf8[0] = 0xe0 | (ucs4 >> 12);
110 utf8[1] = 0x80 | ((ucs4 >> 6) & 0x3f);
111 utf8[2] = 0x80 | (ucs4 & 0x3f);
112 i = 3;
113 } else {
114 utf8[0] = 0xf0 | (ucs4 >> 18);
115 utf8[1] = 0x80 | ((ucs4 >> 12) & 0x3f);
116 utf8[2] = 0x80 | ((ucs4 >> 6) & 0x3f);
117 utf8[3] = 0x80 | (ucs4 & 0x3f);
118 i = 4;
119 }
120 /* copy it */
121 for (c = 0; c < i; ++c) {
122 dst += utf8[c];
123 }
124 }
125 }
126 /* skip over trailing '-' in modified UTF-7 encoding */
127 if (src[srcPtr] == '-')
128 ++srcPtr;
129 }
130 }
131
132 return QString::fromUtf8( dst.data() );
133}
134
56MailWrapper::MailWrapper( Settings *s ) 135MailWrapper::MailWrapper( Settings *s )
57 : QObject() 136 : QObject()
58{ 137{
diff --git a/noncore/net/mail/libmailwrapper/mailwrapper.h b/noncore/net/mail/libmailwrapper/mailwrapper.h
index d78f8e9..02fe4b7 100644
--- a/noncore/net/mail/libmailwrapper/mailwrapper.h
+++ b/noncore/net/mail/libmailwrapper/mailwrapper.h
@@ -88,7 +88,9 @@ class IMAPFolder : public Folder
88 IMAPFolder(const QString&name, const QString&sep, bool select=true,const QString&prefix="" ); 88 IMAPFolder(const QString&name, const QString&sep, bool select=true,const QString&prefix="" );
89 virtual bool may_select()const{return m_MaySelect;} 89 virtual bool may_select()const{return m_MaySelect;}
90 private: 90 private:
91 static QString decodeFolderName( const QString &name );
91 bool m_MaySelect; 92 bool m_MaySelect;
93
92}; 94};
93 95
94class MailWrapper : public QObject 96class MailWrapper : public QObject
diff --git a/noncore/net/mail/mailwrapper.cpp b/noncore/net/mail/mailwrapper.cpp
index 858283f..75c06f9 100644
--- a/noncore/net/mail/mailwrapper.cpp
+++ b/noncore/net/mail/mailwrapper.cpp
@@ -21,20 +21,6 @@ Folder::Folder(const QString&tmp_name, const QString&sep )
21{ 21{
22 name = tmp_name; 22 name = tmp_name;
23 nameDisplay = name; 23 nameDisplay = name;
24
25 for ( int pos = nameDisplay.find( '&' ); pos != -1;
26 pos = nameDisplay.find( '&' ) ) {
27 int end = nameDisplay.find( '-' );
28 if ( end == -1 || end <= pos ) break;
29 QString str64 = nameDisplay.mid( pos + 1, end - pos - 1 );
30 // TODO: do real base64 decoding here !
31 if ( str64.compare( "APw" ) == 0 ) {
32 nameDisplay = nameDisplay.replace( pos, end - pos + 1, "ue" );
33 } else if ( str64.compare( "APY" ) == 0 ) {
34 nameDisplay = nameDisplay.replace( pos, end - pos + 1, "oe" );
35 }
36 }
37 qDebug( "folder " + name + " - displayed as " + nameDisplay );
38 separator = sep; 24 separator = sep;
39} 25}
40 26
@@ -46,6 +32,10 @@ const QString& Folder::Separator()const
46IMAPFolder::IMAPFolder(const QString&name,const QString&sep, bool select,const QString&prefix ) 32IMAPFolder::IMAPFolder(const QString&name,const QString&sep, bool select,const QString&prefix )
47 : Folder( name,sep ),m_MaySelect(select) 33 : Folder( name,sep ),m_MaySelect(select)
48{ 34{
35 // Decode IMAP foldername
36 nameDisplay = IMAPFolder::decodeFolderName( name );
37 qDebug( "folder " + name + " - displayed as " + nameDisplay );
38
49 if (prefix.length()>0) { 39 if (prefix.length()>0) {
50 if (nameDisplay.startsWith(prefix) && nameDisplay.length()>prefix.length()) { 40 if (nameDisplay.startsWith(prefix) && nameDisplay.length()>prefix.length()) {
51 nameDisplay=nameDisplay.right(nameDisplay.length()-prefix.length()); 41 nameDisplay=nameDisplay.right(nameDisplay.length()-prefix.length());
@@ -53,6 +43,95 @@ IMAPFolder::IMAPFolder(const QString&name,const QString&sep, bool select,const Q
53 } 43 }
54} 44}
55 45
46static unsigned char base64chars[] =
47 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+,";
48
49/**
50 * Decodes base64 encoded parts of the imapfolder name
51 * Code taken from kde cvs: kdebase/kioslave/imap4/rfcdecoder.cc
52 */
53QString IMAPFolder::decodeFolderName( const QString &name )
54{
55 unsigned char c, i, bitcount;
56 unsigned long ucs4, utf16, bitbuf;
57 unsigned char base64[256], utf8[6];
58 unsigned long srcPtr = 0;
59 QCString dst;
60 QCString src = name.ascii();
61
62 /* initialize modified base64 decoding table */
63 memset(base64, UNDEFINED, sizeof(base64));
64 for (i = 0; i < sizeof(base64chars); ++i) {
65 base64[(int)base64chars[i]] = i;
66 }
67
68 /* loop until end of string */
69 while (srcPtr < src.length ()) {
70 c = src[srcPtr++];
71 /* deal with literal characters and &- */
72 if (c != '&' || src[srcPtr] == '-') {
73 /* encode literally */
74 dst += c;
75 /* skip over the '-' if this is an &- sequence */
76 if (c == '&')
77 srcPtr++;
78 } else {
79 /* convert modified UTF-7 -> UTF-16 -> UCS-4 -> UTF-8 -> HEX */
80 bitbuf = 0;
81 bitcount = 0;
82 ucs4 = 0;
83 while ((c = base64[(unsigned char) src[srcPtr]]) != UNDEFINED) {
84 ++srcPtr;
85 bitbuf = (bitbuf << 6) | c;
86 bitcount += 6;
87 /* enough bits for a UTF-16 character? */
88 if (bitcount >= 16) {
89 bitcount -= 16;
90 utf16 = (bitcount ? bitbuf >> bitcount : bitbuf) & 0xffff;
91 /* convert UTF16 to UCS4 */
92 if (utf16 >= UTF16HIGHSTART && utf16 <= UTF16HIGHEND) {
93 ucs4 = (utf16 - UTF16HIGHSTART) << UTF16SHIFT;
94 continue;
95 } else if (utf16 >= UTF16LOSTART && utf16 <= UTF16LOEND) {
96 ucs4 += utf16 - UTF16LOSTART + UTF16BASE;
97 } else {
98 ucs4 = utf16;
99 }
100 /* convert UTF-16 range of UCS4 to UTF-8 */
101 if (ucs4 <= 0x7fUL) {
102 utf8[0] = ucs4;
103 i = 1;
104 } else if (ucs4 <= 0x7ffUL) {
105 utf8[0] = 0xc0 | (ucs4 >> 6);
106 utf8[1] = 0x80 | (ucs4 & 0x3f);
107 i = 2;
108 } else if (ucs4 <= 0xffffUL) {
109 utf8[0] = 0xe0 | (ucs4 >> 12);
110 utf8[1] = 0x80 | ((ucs4 >> 6) & 0x3f);
111 utf8[2] = 0x80 | (ucs4 & 0x3f);
112 i = 3;
113 } else {
114 utf8[0] = 0xf0 | (ucs4 >> 18);
115 utf8[1] = 0x80 | ((ucs4 >> 12) & 0x3f);
116 utf8[2] = 0x80 | ((ucs4 >> 6) & 0x3f);
117 utf8[3] = 0x80 | (ucs4 & 0x3f);
118 i = 4;
119 }
120 /* copy it */
121 for (c = 0; c < i; ++c) {
122 dst += utf8[c];
123 }
124 }
125 }
126 /* skip over trailing '-' in modified UTF-7 encoding */
127 if (src[srcPtr] == '-')
128 ++srcPtr;
129 }
130 }
131
132 return QString::fromUtf8( dst.data() );
133}
134
56MailWrapper::MailWrapper( Settings *s ) 135MailWrapper::MailWrapper( Settings *s )
57 : QObject() 136 : QObject()
58{ 137{
diff --git a/noncore/net/mail/mailwrapper.h b/noncore/net/mail/mailwrapper.h
index d78f8e9..02fe4b7 100644
--- a/noncore/net/mail/mailwrapper.h
+++ b/noncore/net/mail/mailwrapper.h
@@ -88,7 +88,9 @@ class IMAPFolder : public Folder
88 IMAPFolder(const QString&name, const QString&sep, bool select=true,const QString&prefix="" ); 88 IMAPFolder(const QString&name, const QString&sep, bool select=true,const QString&prefix="" );
89 virtual bool may_select()const{return m_MaySelect;} 89 virtual bool may_select()const{return m_MaySelect;}
90 private: 90 private:
91 static QString decodeFolderName( const QString &name );
91 bool m_MaySelect; 92 bool m_MaySelect;
93
92}; 94};
93 95
94class MailWrapper : public QObject 96class MailWrapper : public QObject