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.
This commit is contained in:
parent
229c777323
commit
9234fd439e
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2011-2012, Axel Dörfler, axeld@pinc-software.de.
|
||||
* Copyright 2011-2013, Axel Dörfler, axeld@pinc-software.de.
|
||||
* 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 -
|
||||
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2011, Axel Dörfler, axeld@pinc-software.de.
|
||||
* Copyright 2011-2013, Axel Dörfler, axeld@pinc-software.de.
|
||||
* 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;
|
||||
};
|
||||
|
||||
|
||||
|
@ -33,6 +33,13 @@ SimpleTest imap_tester :
|
||||
: be [ TargetLibstdc++ ] [ TargetLibsupc++ ] 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 ] ;
|
||||
|
39
src/tests/add-ons/mail/imap/rfc3501_encoding_test.cpp
Normal file
39
src/tests/add-ons/mail/imap/rfc3501_encoding_test.cpp
Normal file
@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright 2013, Axel Dörfler, axeld@pinc-software.de.
|
||||
* 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);
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user