[haiku-commits] BRANCH axeld-github.imap - in src: add-ons/mail_daemon/inbound_protocols/imap/imap_lib tests/add-ons/mail/imap

  • From: axeld-github.imap <community@xxxxxxxxxxxx>
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Wed, 17 Apr 2013 22:30:37 +0200 (CEST)

added 1 changeset to branch 'refs/remotes/axeld-github/imap'
old head: ce277462a563387065533e5ce790b4a1a32a04dd
new head: 94631a592c79e8c1ad3cec6a94500544fb6834da
overview: https://github.com/axeld/haiku/compare/ce27746...94631a5

----------------------------------------------------------------------------

94631a5: imap: Implemented encoding RFC3501 strings.
  
  * Was completely missing so far.
  * Fixed bug in decoding that handled the "&-" sequence incorrectly.
  * Added small test application that should easily be convertible to
    a unit test.

                                   [ Axel Dörfler <axeld@xxxxxxxxxxxxxxxx> ]

----------------------------------------------------------------------------

Commit:      94631a592c79e8c1ad3cec6a94500544fb6834da
Author:      Axel Dörfler <axeld@xxxxxxxxxxxxxxxx>
Date:        Wed Apr 17 20:25:33 2013 UTC

----------------------------------------------------------------------------

4 files changed, 105 insertions(+), 4 deletions(-)
.../inbound_protocols/imap/imap_lib/Response.cpp | 59 +++++++++++++++++++-
.../inbound_protocols/imap/imap_lib/Response.h   |  4 +-
src/tests/add-ons/mail/imap/Jamfile              |  7 +++
.../add-ons/mail/imap/rfc3501_encoding_test.cpp  | 39 +++++++++++++

----------------------------------------------------------------------------

diff --git 
a/src/add-ons/mail_daemon/inbound_protocols/imap/imap_lib/Response.cpp 
b/src/add-ons/mail_daemon/inbound_protocols/imap/imap_lib/Response.cpp
index 101e6ff..d27b4c4 100644
--- a/src/add-ons/mail_daemon/inbound_protocols/imap/imap_lib/Response.cpp
+++ b/src/add-ons/mail_daemon/inbound_protocols/imap/imap_lib/Response.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright 2011-2012, Axel Dörfler, axeld@xxxxxxxxxxxxxxxx.
+ * Copyright 2011-2013, Axel Dörfler, axeld@xxxxxxxxxxxxxxxx.
  * Distributed under the terms of the MIT License.
  */
 
@@ -8,6 +8,8 @@
 
 #include <stdlib.h>
 
+#include <UnicodeChar.h>
+
 
 #define TRACE_IMAP
 #ifdef TRACE_IMAP
@@ -53,8 +55,41 @@ RFC3501Encoding::~RFC3501Encoding()
 BString
 RFC3501Encoding::Encode(const BString& clearText) const
 {
-       // TODO!
-       return clearText;
+       const char* clear = clearText.String();
+       bool shifted = false;
+       int32 bitsToWrite = 0;
+       int32 sextet = 0;
+       BString buffer;
+
+       while (true) {
+               uint32 c = BUnicodeChar::FromUTF8(&clear);
+               if (c == 0)
+                       break;
+
+               if (!shifted && c == '&')
+                       buffer += "&-";
+               else if (c >= 0x20 && c <= 0x7e) {
+                       _Unshift(buffer, bitsToWrite, sextet, shifted);
+                       buffer += c;
+               } else {
+                       // Enter shifted mode, encode in base64
+                       if (!shifted) {
+                               buffer += '&';
+                               shifted = true;
+                       }
+
+                       bitsToWrite += 16;
+                       while (bitsToWrite >= 6) {
+                               bitsToWrite -= 6;
+                               buffer += kBase64Alphabet[(sextet + (c >> 
bitsToWrite)) & 0x3f];
+                               sextet = 0;
+                       }
+                       sextet = (c << (6 - bitsToWrite)) & 0x3f;
+               }
+       }
+
+       _Unshift(buffer, bitsToWrite, sextet, shifted);
+       return buffer;
 }
 
 
@@ -69,6 +104,7 @@ RFC3501Encoding::Decode(const BString& encodedText) const
                        if (i < end - 1 && encodedText.ByteAt(i + 1) == '-') {
                                // just add an ampersand
                                buffer += '&';
+                               i++;
                        } else {
                                // base64 encoded chunk
                                uint32 value = 0;
@@ -134,6 +170,23 @@ RFC3501Encoding::_ToUTF8(BString& string, uint32 c) const
 }
 
 
+//!    Exit base64, or "shifted" mode.
+void
+RFC3501Encoding::_Unshift(BString& buffer, int32& bitsToWrite, int32& sextet,
+       bool& shifted) const
+{
+       if (!shifted)
+               return;
+
+       if (bitsToWrite != 0)
+               buffer += kBase64Alphabet[sextet];
+       buffer += '-';
+       sextet = 0;
+       bitsToWrite = 0;
+       shifted = false;
+}
+
+
 // #pragma mark -
 
 
diff --git a/src/add-ons/mail_daemon/inbound_protocols/imap/imap_lib/Response.h 
b/src/add-ons/mail_daemon/inbound_protocols/imap/imap_lib/Response.h
index 87c0059..7460cf4 100644
--- a/src/add-ons/mail_daemon/inbound_protocols/imap/imap_lib/Response.h
+++ b/src/add-ons/mail_daemon/inbound_protocols/imap/imap_lib/Response.h
@@ -1,5 +1,5 @@
 /*
- * Copyright 2011, Axel Dörfler, axeld@xxxxxxxxxxxxxxxx.
+ * Copyright 2011-2013, Axel Dörfler, axeld@xxxxxxxxxxxxxxxx.
  * Distributed under the terms of the MIT License.
  */
 #ifndef RESPONSE_H
@@ -30,6 +30,8 @@ public:
 
 private:
                        void                            _ToUTF8(BString& 
string, uint32 c) const;
+                       void                            _Unshift(BString& 
string, int32& bitsToWrite,
+                                                                       int32& 
sextet, bool& shifted) const;
 };
 
 
diff --git a/src/tests/add-ons/mail/imap/Jamfile 
b/src/tests/add-ons/mail/imap/Jamfile
index 7eecdc8..75a0916 100644
--- a/src/tests/add-ons/mail/imap/Jamfile
+++ b/src/tests/add-ons/mail/imap/Jamfile
@@ -33,6 +33,13 @@ SimpleTest imap_tester :
        : be $(TARGET_LIBSTDC++) $(TARGET_LIBSUPC++) bnetapi mail
 ;
 
+SimpleTest rfc3501_encoding_test :
+       rfc3501_encoding_test.cpp
+       $(libSources)
+
+       : be $(TARGET_LIBSTDC++) $(TARGET_LIBSUPC++) bnetapi
+;
+
 SEARCH on [ FGristFiles $(libSources) ]
        = [ FDirName $(HAIKU_TOP) src add-ons mail_daemon inbound_protocols imap
                imap_lib ] ;
diff --git a/src/tests/add-ons/mail/imap/rfc3501_encoding_test.cpp 
b/src/tests/add-ons/mail/imap/rfc3501_encoding_test.cpp
new file mode 100644
index 0000000..cf5f085
--- /dev/null
+++ b/src/tests/add-ons/mail/imap/rfc3501_encoding_test.cpp
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2013, Axel Dörfler, axeld@xxxxxxxxxxxxxxxx.
+ * Distributed under the terms of the MIT License.
+ */
+
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "Response.h"
+
+
+void
+assertEquals(const char* expected, const char* result)
+{
+       if (strcmp(expected, result) != 0) {
+               printf("Expected \"%s\", got \"%s\"\n", expected, result);
+               exit(EXIT_FAILURE);
+       }
+}
+
+
+int
+main()
+{
+       const char* samples[] = {
+               "Gelöscht", "Gel&APY-scht",
+               "&äöß", "&-&AOQA9gDf-"
+       };
+
+       IMAP::RFC3501Encoding encoding;
+
+       for (size_t i = 0; i < sizeof(samples) / sizeof(samples[0]); i += 2) {
+               BString encoded = encoding.Encode(samples[i]);
+               assertEquals(samples[i + 1], encoded);
+               BString decoded = encoding.Decode(encoded);
+               assertEquals(samples[i], decoded);
+       }
+}


Other related posts:

  • » [haiku-commits] BRANCH axeld-github.imap - in src: add-ons/mail_daemon/inbound_protocols/imap/imap_lib tests/add-ons/mail/imap - axeld-github . imap