* Cleanup - this is very ugly code, and the API is also not really good; we
really should get rid of the current mail kit some day. * Fixed another memory leak I stumpled upon. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@38245 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
+254
-153
@@ -1,34 +1,34 @@
|
|||||||
/* BMailAttachment - classes which handle mail attachments
|
/*
|
||||||
**
|
* Copyright 2001 Dr. Zoidberg Enterprises. All rights reserved.
|
||||||
** Copyright 2001 Dr. Zoidberg Enterprises. All rights reserved.
|
*/
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#include <DataIO.h>
|
/*! Classes which handle mail attachments */
|
||||||
#include <String.h>
|
|
||||||
#include <File.h>
|
|
||||||
#include <Entry.h>
|
#include <MailAttachment.h>
|
||||||
#include <Mime.h>
|
|
||||||
#include <ByteOrder.h>
|
|
||||||
#include <NodeInfo.h>
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include <ByteOrder.h>
|
||||||
|
#include <DataIO.h>
|
||||||
|
#include <Entry.h>
|
||||||
|
#include <File.h>
|
||||||
|
#include <Mime.h>
|
||||||
|
#include <NodeInfo.h>
|
||||||
|
#include <String.h>
|
||||||
|
|
||||||
#include <AutoDeleter.h>
|
#include <AutoDeleter.h>
|
||||||
|
|
||||||
class _EXPORT BSimpleMailAttachment;
|
|
||||||
class _EXPORT BAttributedMailAttachment;
|
|
||||||
class _EXPORT BMailAttachment;
|
|
||||||
|
|
||||||
#include <MailAttachment.h>
|
|
||||||
#include <mail_encoding.h>
|
#include <mail_encoding.h>
|
||||||
#include <NodeMessage.h>
|
#include <NodeMessage.h>
|
||||||
|
|
||||||
//--------------BSimpleMailAttachment-No attributes or awareness of the file system at large-----
|
|
||||||
|
|
||||||
|
/*! No attributes or awareness of the file system at large
|
||||||
|
*/
|
||||||
BSimpleMailAttachment::BSimpleMailAttachment()
|
BSimpleMailAttachment::BSimpleMailAttachment()
|
||||||
: BMailAttachment(),
|
:
|
||||||
fStatus(B_NO_INIT),
|
fStatus(B_NO_INIT),
|
||||||
_data(NULL),
|
_data(NULL),
|
||||||
_raw_data(NULL),
|
_raw_data(NULL),
|
||||||
@@ -37,8 +37,10 @@ BSimpleMailAttachment::BSimpleMailAttachment()
|
|||||||
Initialize(base64);
|
Initialize(base64);
|
||||||
}
|
}
|
||||||
|
|
||||||
BSimpleMailAttachment::BSimpleMailAttachment(BPositionIO *data, mail_encoding encoding)
|
|
||||||
: BMailAttachment(),
|
BSimpleMailAttachment::BSimpleMailAttachment(BPositionIO *data,
|
||||||
|
mail_encoding encoding)
|
||||||
|
:
|
||||||
_data(data),
|
_data(data),
|
||||||
_raw_data(NULL),
|
_raw_data(NULL),
|
||||||
_we_own_data(false)
|
_we_own_data(false)
|
||||||
@@ -48,8 +50,10 @@ BSimpleMailAttachment::BSimpleMailAttachment(BPositionIO *data, mail_encoding en
|
|||||||
Initialize(encoding);
|
Initialize(encoding);
|
||||||
}
|
}
|
||||||
|
|
||||||
BSimpleMailAttachment::BSimpleMailAttachment(const void *data, size_t length, mail_encoding encoding)
|
|
||||||
: BMailAttachment(),
|
BSimpleMailAttachment::BSimpleMailAttachment(const void *data, size_t length,
|
||||||
|
mail_encoding encoding)
|
||||||
|
:
|
||||||
_data(new BMemoryIO(data,length)),
|
_data(new BMemoryIO(data,length)),
|
||||||
_raw_data(NULL),
|
_raw_data(NULL),
|
||||||
_we_own_data(true)
|
_we_own_data(true)
|
||||||
@@ -59,18 +63,20 @@ BSimpleMailAttachment::BSimpleMailAttachment(const void *data, size_t length, ma
|
|||||||
Initialize(encoding);
|
Initialize(encoding);
|
||||||
}
|
}
|
||||||
|
|
||||||
BSimpleMailAttachment::BSimpleMailAttachment(BFile *file, bool delete_when_done)
|
|
||||||
: BMailAttachment(),
|
BSimpleMailAttachment::BSimpleMailAttachment(BFile *file, bool deleteWhenDone)
|
||||||
|
:
|
||||||
_data(NULL),
|
_data(NULL),
|
||||||
_raw_data(NULL),
|
_raw_data(NULL),
|
||||||
_we_own_data(false)
|
_we_own_data(false)
|
||||||
{
|
{
|
||||||
Initialize(base64);
|
Initialize(base64);
|
||||||
SetTo(file,delete_when_done);
|
SetTo(file, deleteWhenDone);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
BSimpleMailAttachment::BSimpleMailAttachment(entry_ref *ref)
|
BSimpleMailAttachment::BSimpleMailAttachment(entry_ref *ref)
|
||||||
: BMailAttachment(),
|
:
|
||||||
_data(NULL),
|
_data(NULL),
|
||||||
_raw_data(NULL),
|
_raw_data(NULL),
|
||||||
_we_own_data(false)
|
_we_own_data(false)
|
||||||
@@ -79,19 +85,24 @@ BSimpleMailAttachment::BSimpleMailAttachment(entry_ref *ref)
|
|||||||
SetTo(ref);
|
SetTo(ref);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
BSimpleMailAttachment::~BSimpleMailAttachment()
|
BSimpleMailAttachment::~BSimpleMailAttachment()
|
||||||
{
|
{
|
||||||
if (_we_own_data)
|
if (_we_own_data)
|
||||||
delete _data;
|
delete _data;
|
||||||
}
|
}
|
||||||
|
|
||||||
void BSimpleMailAttachment::Initialize(mail_encoding encoding)
|
|
||||||
|
void
|
||||||
|
BSimpleMailAttachment::Initialize(mail_encoding encoding)
|
||||||
{
|
{
|
||||||
SetEncoding(encoding);
|
SetEncoding(encoding);
|
||||||
SetHeaderField("Content-Disposition","BMailAttachment");
|
SetHeaderField("Content-Disposition","BMailAttachment");
|
||||||
}
|
}
|
||||||
|
|
||||||
status_t BSimpleMailAttachment::SetTo(BFile *file, bool delete_file_when_done)
|
|
||||||
|
status_t
|
||||||
|
BSimpleMailAttachment::SetTo(BFile *file, bool deleteFileWhenDone)
|
||||||
{
|
{
|
||||||
char type[B_MIME_TYPE_LENGTH] = "application/octet-stream";
|
char type[B_MIME_TYPE_LENGTH] = "application/octet-stream";
|
||||||
|
|
||||||
@@ -99,11 +110,11 @@ status_t BSimpleMailAttachment::SetTo(BFile *file, bool delete_file_when_done)
|
|||||||
if (nodeInfo.InitCheck() == B_OK)
|
if (nodeInfo.InitCheck() == B_OK)
|
||||||
nodeInfo.GetType(type);
|
nodeInfo.GetType(type);
|
||||||
|
|
||||||
SetHeaderField("Content-Type",type);
|
SetHeaderField("Content-Type", type);
|
||||||
//---No way to get file name (see SetTo(entry_ref *))
|
// TODO: No way to get file name (see SetTo(entry_ref *))
|
||||||
//SetFileName(ref->name);
|
//SetFileName(ref->name);
|
||||||
|
|
||||||
if (delete_file_when_done)
|
if (deleteFileWhenDone)
|
||||||
SetDecodedDataAndDeleteWhenDone(file);
|
SetDecodedDataAndDeleteWhenDone(file);
|
||||||
else
|
else
|
||||||
SetDecodedData(file);
|
SetDecodedData(file);
|
||||||
@@ -111,71 +122,76 @@ status_t BSimpleMailAttachment::SetTo(BFile *file, bool delete_file_when_done)
|
|||||||
return fStatus = B_OK;
|
return fStatus = B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
status_t BSimpleMailAttachment::SetTo(entry_ref *ref)
|
|
||||||
{
|
|
||||||
BFile *file = new BFile(ref,B_READ_ONLY);
|
|
||||||
|
|
||||||
if ((fStatus = file->InitCheck()) < B_OK)
|
status_t
|
||||||
{
|
BSimpleMailAttachment::SetTo(entry_ref *ref)
|
||||||
|
{
|
||||||
|
BFile *file = new BFile(ref, B_READ_ONLY);
|
||||||
|
if ((fStatus = file->InitCheck()) < B_OK) {
|
||||||
delete file;
|
delete file;
|
||||||
return fStatus;
|
return fStatus;
|
||||||
}
|
}
|
||||||
if (SetTo(file,true) < B_OK)
|
|
||||||
// fStatus is set by SetTo()
|
if (SetTo(file, true) != B_OK)
|
||||||
return fStatus;
|
return fStatus;
|
||||||
|
|
||||||
SetFileName(ref->name);
|
SetFileName(ref->name);
|
||||||
return fStatus = B_OK;
|
return fStatus = B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
status_t BSimpleMailAttachment::InitCheck()
|
|
||||||
|
status_t
|
||||||
|
BSimpleMailAttachment::InitCheck()
|
||||||
{
|
{
|
||||||
return fStatus;
|
return fStatus;
|
||||||
}
|
}
|
||||||
|
|
||||||
status_t BSimpleMailAttachment::FileName(char *text) {
|
|
||||||
BMessage content_type;
|
|
||||||
HeaderField("Content-Type",&content_type);
|
|
||||||
|
|
||||||
const char *fileName = content_type.FindString("name");
|
status_t
|
||||||
|
BSimpleMailAttachment::FileName(char *text)
|
||||||
|
{
|
||||||
|
BMessage contentType;
|
||||||
|
HeaderField("Content-Type", &contentType);
|
||||||
|
|
||||||
|
const char *fileName = contentType.FindString("name");
|
||||||
if (!fileName)
|
if (!fileName)
|
||||||
fileName = content_type.FindString("filename");
|
fileName = contentType.FindString("filename");
|
||||||
if (!fileName)
|
if (!fileName) {
|
||||||
{
|
contentType.MakeEmpty();
|
||||||
content_type.MakeEmpty();
|
HeaderField("Content-Disposition", &contentType);
|
||||||
HeaderField("Content-Disposition",&content_type);
|
fileName = contentType.FindString("name");
|
||||||
fileName = content_type.FindString("name");
|
|
||||||
}
|
}
|
||||||
if (!fileName)
|
if (!fileName)
|
||||||
fileName = content_type.FindString("filename");
|
fileName = contentType.FindString("filename");
|
||||||
if (!fileName)
|
if (!fileName) {
|
||||||
{
|
contentType.MakeEmpty();
|
||||||
content_type.MakeEmpty();
|
HeaderField("Content-Location", &contentType);
|
||||||
HeaderField("Content-Location",&content_type);
|
fileName = contentType.FindString("unlabeled");
|
||||||
fileName = content_type.FindString("unlabeled");
|
|
||||||
}
|
}
|
||||||
if (!fileName)
|
if (!fileName)
|
||||||
return B_NAME_NOT_FOUND;
|
return B_NAME_NOT_FOUND;
|
||||||
|
|
||||||
strncpy(text,fileName,B_FILE_NAME_LENGTH);
|
strncpy(text, fileName, B_FILE_NAME_LENGTH);
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void BSimpleMailAttachment::SetFileName(const char *name) {
|
void
|
||||||
BMessage content_type;
|
BSimpleMailAttachment::SetFileName(const char *name)
|
||||||
|
{
|
||||||
|
BMessage contentType;
|
||||||
|
HeaderField("Content-Type", &contentType);
|
||||||
|
|
||||||
HeaderField("Content-Type",&content_type);
|
if (contentType.ReplaceString("name", name) != B_OK)
|
||||||
|
contentType.AddString("name", name);
|
||||||
if (content_type.ReplaceString("name",name) != B_OK)
|
|
||||||
content_type.AddString("name",name);
|
|
||||||
|
|
||||||
// Request that the file name header be encoded in UTF-8 if it has weird
|
// Request that the file name header be encoded in UTF-8 if it has weird
|
||||||
// characters. If it is just a plain name, the header will appear normal.
|
// characters. If it is just a plain name, the header will appear normal.
|
||||||
if (content_type.ReplaceInt32(kHeaderCharsetString, B_MAIL_UTF8_CONVERSION) != B_OK)
|
if (contentType.ReplaceInt32(kHeaderCharsetString, B_MAIL_UTF8_CONVERSION)
|
||||||
content_type.AddInt32(kHeaderCharsetString, B_MAIL_UTF8_CONVERSION);
|
!= B_OK)
|
||||||
|
contentType.AddInt32(kHeaderCharsetString, B_MAIL_UTF8_CONVERSION);
|
||||||
|
|
||||||
SetHeaderField ("Content-Type", &content_type);
|
SetHeaderField ("Content-Type", &contentType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -193,8 +209,8 @@ BSimpleMailAttachment::GetDecodedData(BPositionIO *data)
|
|||||||
ssize_t length;
|
ssize_t length;
|
||||||
_data->Seek(0,SEEK_SET);
|
_data->Seek(0,SEEK_SET);
|
||||||
|
|
||||||
while ((length = _data->Read(buffer,sizeof(buffer))) > 0)
|
while ((length = _data->Read(buffer, sizeof(buffer))) > 0)
|
||||||
data->Write(buffer,length);
|
data->Write(buffer, length);
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
@@ -204,11 +220,13 @@ BPositionIO *
|
|||||||
BSimpleMailAttachment::GetDecodedData()
|
BSimpleMailAttachment::GetDecodedData()
|
||||||
{
|
{
|
||||||
ParseNow();
|
ParseNow();
|
||||||
|
|
||||||
return _data;
|
return _data;
|
||||||
}
|
}
|
||||||
|
|
||||||
status_t BSimpleMailAttachment::SetDecodedDataAndDeleteWhenDone(BPositionIO *data) {
|
|
||||||
|
status_t
|
||||||
|
BSimpleMailAttachment::SetDecodedDataAndDeleteWhenDone(BPositionIO *data)
|
||||||
|
{
|
||||||
_raw_data = NULL;
|
_raw_data = NULL;
|
||||||
|
|
||||||
if (_we_own_data)
|
if (_we_own_data)
|
||||||
@@ -220,7 +238,10 @@ status_t BSimpleMailAttachment::SetDecodedDataAndDeleteWhenDone(BPositionIO *dat
|
|||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
status_t BSimpleMailAttachment::SetDecodedData(BPositionIO *data) {
|
|
||||||
|
status_t
|
||||||
|
BSimpleMailAttachment::SetDecodedData(BPositionIO *data)
|
||||||
|
{
|
||||||
_raw_data = NULL;
|
_raw_data = NULL;
|
||||||
|
|
||||||
if (_we_own_data)
|
if (_we_own_data)
|
||||||
@@ -232,7 +253,10 @@ status_t BSimpleMailAttachment::SetDecodedData(BPositionIO *data) {
|
|||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
status_t BSimpleMailAttachment::SetDecodedData(const void *data, size_t length) {
|
|
||||||
|
status_t
|
||||||
|
BSimpleMailAttachment::SetDecodedData(const void *data, size_t length)
|
||||||
|
{
|
||||||
_raw_data = NULL;
|
_raw_data = NULL;
|
||||||
|
|
||||||
if (_we_own_data)
|
if (_we_own_data)
|
||||||
@@ -244,7 +268,10 @@ status_t BSimpleMailAttachment::SetDecodedData(const void *data, size_t length)
|
|||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
void BSimpleMailAttachment::SetEncoding(mail_encoding encoding) {
|
|
||||||
|
void
|
||||||
|
BSimpleMailAttachment::SetEncoding(mail_encoding encoding)
|
||||||
|
{
|
||||||
_encoding = encoding;
|
_encoding = encoding;
|
||||||
|
|
||||||
const char *cte = NULL; //--Content Transfer Encoding
|
const char *cte = NULL; //--Content Transfer Encoding
|
||||||
@@ -270,20 +297,27 @@ void BSimpleMailAttachment::SetEncoding(mail_encoding encoding) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
SetHeaderField("Content-Transfer-Encoding",cte);
|
SetHeaderField("Content-Transfer-Encoding", cte);
|
||||||
}
|
}
|
||||||
|
|
||||||
mail_encoding BSimpleMailAttachment::Encoding() {
|
|
||||||
|
mail_encoding
|
||||||
|
BSimpleMailAttachment::Encoding()
|
||||||
|
{
|
||||||
return _encoding;
|
return _encoding;
|
||||||
}
|
}
|
||||||
|
|
||||||
status_t BSimpleMailAttachment::SetToRFC822(BPositionIO *data, size_t length, bool parse_now) {
|
|
||||||
|
status_t
|
||||||
|
BSimpleMailAttachment::SetToRFC822(BPositionIO *data, size_t length,
|
||||||
|
bool parseNow)
|
||||||
|
{
|
||||||
//---------Massive memory squandering!---ALERT!----------
|
//---------Massive memory squandering!---ALERT!----------
|
||||||
if (_we_own_data)
|
if (_we_own_data)
|
||||||
delete _data;
|
delete _data;
|
||||||
|
|
||||||
off_t position = data->Position();
|
off_t position = data->Position();
|
||||||
BMailComponent::SetToRFC822(data,length,parse_now);
|
BMailComponent::SetToRFC822(data, length, parseNow);
|
||||||
|
|
||||||
// this actually happens...
|
// this actually happens...
|
||||||
if (data->Position() - position > length)
|
if (data->Position() - position > length)
|
||||||
@@ -309,25 +343,33 @@ status_t BSimpleMailAttachment::SetToRFC822(BPositionIO *data, size_t length, bo
|
|||||||
else
|
else
|
||||||
_encoding = no_encoding;
|
_encoding = no_encoding;
|
||||||
|
|
||||||
if (parse_now)
|
if (parseNow)
|
||||||
ParseNow();
|
ParseNow();
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
void BSimpleMailAttachment::ParseNow() {
|
|
||||||
|
void
|
||||||
|
BSimpleMailAttachment::ParseNow()
|
||||||
|
{
|
||||||
if (_raw_data == NULL || _raw_length == 0)
|
if (_raw_data == NULL || _raw_length == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
_raw_data->Seek(_raw_offset,SEEK_SET);
|
_raw_data->Seek(_raw_offset, SEEK_SET);
|
||||||
|
|
||||||
char *src = (char *)malloc(_raw_length);
|
char *src = (char *)malloc(_raw_length);
|
||||||
|
if (src == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
size_t size = _raw_length;
|
size_t size = _raw_length;
|
||||||
|
|
||||||
size = _raw_data->Read(src,_raw_length);
|
size = _raw_data->Read(src, _raw_length);
|
||||||
|
|
||||||
BMallocIO *buffer = new BMallocIO;
|
BMallocIO *buffer = new BMallocIO;
|
||||||
buffer->SetSize(size); //-------8bit is *always* more efficient than an encoding, so the buffer will *never* be larger than before
|
buffer->SetSize(size);
|
||||||
|
// 8bit is *always* more efficient than an encoding, so the buffer
|
||||||
|
// will *never* be larger than before
|
||||||
|
|
||||||
size = decode(_encoding,(char *)(buffer->Buffer()),src,size,0);
|
size = decode(_encoding,(char *)(buffer->Buffer()),src,size,0);
|
||||||
free(src);
|
free(src);
|
||||||
@@ -342,13 +384,15 @@ void BSimpleMailAttachment::ParseNow() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
status_t BSimpleMailAttachment::RenderToRFC822(BPositionIO *render_to) {
|
|
||||||
ParseNow();
|
|
||||||
BMailComponent::RenderToRFC822(render_to);
|
|
||||||
//---------Massive memory squandering!---ALERT!----------
|
|
||||||
// now with error checks, dumb :-) -- axeld.
|
|
||||||
|
|
||||||
_data->Seek(0,SEEK_END);
|
status_t
|
||||||
|
BSimpleMailAttachment::RenderToRFC822(BPositionIO *renderTo)
|
||||||
|
{
|
||||||
|
ParseNow();
|
||||||
|
BMailComponent::RenderToRFC822(renderTo);
|
||||||
|
//---------Massive memory squandering!---ALERT!----------
|
||||||
|
|
||||||
|
_data->Seek(0, SEEK_END);
|
||||||
off_t size = _data->Position();
|
off_t size = _data->Position();
|
||||||
char *src = (char *)malloc(size);
|
char *src = (char *)malloc(size);
|
||||||
if (src == NULL)
|
if (src == NULL)
|
||||||
@@ -356,16 +400,16 @@ status_t BSimpleMailAttachment::RenderToRFC822(BPositionIO *render_to) {
|
|||||||
|
|
||||||
MemoryDeleter sourceDeleter(src);
|
MemoryDeleter sourceDeleter(src);
|
||||||
|
|
||||||
_data->Seek(0,SEEK_SET);
|
_data->Seek(0, SEEK_SET);
|
||||||
|
|
||||||
ssize_t read = _data->Read(src,size);
|
ssize_t read = _data->Read(src, size);
|
||||||
if (read < B_OK)
|
if (read < B_OK)
|
||||||
return read;
|
return read;
|
||||||
|
|
||||||
// The encoded text will never be more than twice as large with any
|
// The encoded text will never be more than twice as large with any
|
||||||
// conceivable encoding. But just in case, there's a function call which
|
// conceivable encoding. But just in case, there's a function call which
|
||||||
// will tell us how much space is needed.
|
// will tell us how much space is needed.
|
||||||
ssize_t destSize = max_encoded_length(_encoding,read);
|
ssize_t destSize = max_encoded_length(_encoding, read);
|
||||||
if (destSize < B_OK) // Invalid encodings like uuencode rejected here.
|
if (destSize < B_OK) // Invalid encodings like uuencode rejected here.
|
||||||
return destSize;
|
return destSize;
|
||||||
char *dest = (char *)malloc(destSize);
|
char *dest = (char *)malloc(destSize);
|
||||||
@@ -379,18 +423,19 @@ status_t BSimpleMailAttachment::RenderToRFC822(BPositionIO *render_to) {
|
|||||||
return destSize;
|
return destSize;
|
||||||
|
|
||||||
if (destSize > 0)
|
if (destSize > 0)
|
||||||
read = render_to->Write(dest,destSize);
|
read = renderTo->Write(dest, destSize);
|
||||||
|
|
||||||
return (read > 0) ? B_OK : read;
|
return read > 0 ? B_OK : read;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//-------BAttributedMailAttachment--Awareness of bfs, sends attributes--
|
|
||||||
// #pragma mark -
|
// #pragma mark -
|
||||||
|
|
||||||
|
|
||||||
|
/*! Supports and sends attributes.
|
||||||
|
*/
|
||||||
BAttributedMailAttachment::BAttributedMailAttachment()
|
BAttributedMailAttachment::BAttributedMailAttachment()
|
||||||
: BMailAttachment(),
|
:
|
||||||
fContainer(NULL),
|
fContainer(NULL),
|
||||||
fStatus(B_NO_INIT),
|
fStatus(B_NO_INIT),
|
||||||
_data(NULL),
|
_data(NULL),
|
||||||
@@ -398,17 +443,20 @@ BAttributedMailAttachment::BAttributedMailAttachment()
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
BAttributedMailAttachment::BAttributedMailAttachment(BFile *file, bool delete_when_done)
|
|
||||||
: BMailAttachment(),
|
BAttributedMailAttachment::BAttributedMailAttachment(BFile *file,
|
||||||
|
bool deleteWhenDone)
|
||||||
|
:
|
||||||
fContainer(NULL),
|
fContainer(NULL),
|
||||||
_data(NULL),
|
_data(NULL),
|
||||||
_attributes_attach(NULL)
|
_attributes_attach(NULL)
|
||||||
{
|
{
|
||||||
SetTo(file,delete_when_done);
|
SetTo(file, deleteWhenDone);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
BAttributedMailAttachment::BAttributedMailAttachment(entry_ref *ref)
|
BAttributedMailAttachment::BAttributedMailAttachment(entry_ref *ref)
|
||||||
: BMailAttachment(),
|
:
|
||||||
fContainer(NULL),
|
fContainer(NULL),
|
||||||
_data(NULL),
|
_data(NULL),
|
||||||
_attributes_attach(NULL)
|
_attributes_attach(NULL)
|
||||||
@@ -416,13 +464,16 @@ BAttributedMailAttachment::BAttributedMailAttachment(entry_ref *ref)
|
|||||||
SetTo(ref);
|
SetTo(ref);
|
||||||
}
|
}
|
||||||
|
|
||||||
BAttributedMailAttachment::~BAttributedMailAttachment() {
|
|
||||||
|
BAttributedMailAttachment::~BAttributedMailAttachment()
|
||||||
|
{
|
||||||
// Our SimpleAttachments are deleted by fContainer
|
// Our SimpleAttachments are deleted by fContainer
|
||||||
delete fContainer;
|
delete fContainer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t BAttributedMailAttachment::Initialize()
|
status_t
|
||||||
|
BAttributedMailAttachment::Initialize()
|
||||||
{
|
{
|
||||||
// _data & _attributes_attach will be deleted by the container
|
// _data & _attributes_attach will be deleted by the container
|
||||||
delete fContainer;
|
delete fContainer;
|
||||||
@@ -434,21 +485,23 @@ status_t BAttributedMailAttachment::Initialize()
|
|||||||
|
|
||||||
_attributes_attach = new BSimpleMailAttachment();
|
_attributes_attach = new BSimpleMailAttachment();
|
||||||
_attributes.MakeEmpty();
|
_attributes.MakeEmpty();
|
||||||
_attributes_attach->SetHeaderField("Content-Type","application/x-be_attribute; name=\"BeOS Attributes\"");
|
_attributes_attach->SetHeaderField("Content-Type",
|
||||||
|
"application/x-be_attribute; name=\"BeOS Attributes\"");
|
||||||
fContainer->AddComponent(_attributes_attach);
|
fContainer->AddComponent(_attributes_attach);
|
||||||
|
|
||||||
fContainer->SetHeaderField("Content-Type","multipart/x-bfile");
|
fContainer->SetHeaderField("Content-Type", "multipart/x-bfile");
|
||||||
fContainer->SetHeaderField("Content-Disposition","BMailAttachment");
|
fContainer->SetHeaderField("Content-Disposition", "BMailAttachment");
|
||||||
|
|
||||||
// also set the header fields of this component, in case someone asks
|
// also set the header fields of this component, in case someone asks
|
||||||
SetHeaderField("Content-Type","multipart/x-bfile");
|
SetHeaderField("Content-Type", "multipart/x-bfile");
|
||||||
SetHeaderField("Content-Disposition","BMailAttachment");
|
SetHeaderField("Content-Disposition", "BMailAttachment");
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t BAttributedMailAttachment::SetTo(BFile *file, bool delete_file_when_done)
|
status_t
|
||||||
|
BAttributedMailAttachment::SetTo(BFile *file, bool deleteFileWhenDone)
|
||||||
{
|
{
|
||||||
if (file == NULL)
|
if (file == NULL)
|
||||||
return fStatus = B_BAD_VALUE;
|
return fStatus = B_BAD_VALUE;
|
||||||
@@ -458,21 +511,24 @@ status_t BAttributedMailAttachment::SetTo(BFile *file, bool delete_file_when_don
|
|||||||
|
|
||||||
_attributes << *file;
|
_attributes << *file;
|
||||||
|
|
||||||
if ((fStatus = _data->SetTo(file,delete_file_when_done)) < B_OK)
|
if ((fStatus = _data->SetTo(file, deleteFileWhenDone)) < B_OK)
|
||||||
return fStatus;
|
return fStatus;
|
||||||
|
|
||||||
// Set boundary
|
// Set boundary
|
||||||
|
|
||||||
//---Also, we have the make up the boundary out of whole cloth
|
// Also, we have the make up the boundary out of whole cloth
|
||||||
//------This is likely to give a completely random string---
|
// This is likely to give a completely random string
|
||||||
BString boundary;
|
BString boundary;
|
||||||
boundary << "BFile--" << (int32(file) ^ time(NULL)) << "-" << ~((int32)file ^ (int32)&fStatus ^ (int32)&_attributes) << "--";
|
boundary << "BFile--" << (int32(file) ^ time(NULL)) << "-"
|
||||||
|
<< ~((int32)file ^ (int32)&fStatus ^ (int32)&_attributes) << "--";
|
||||||
fContainer->SetBoundary(boundary.String());
|
fContainer->SetBoundary(boundary.String());
|
||||||
|
|
||||||
return fStatus = B_OK;
|
return fStatus = B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
status_t BAttributedMailAttachment::SetTo(entry_ref *ref)
|
|
||||||
|
status_t
|
||||||
|
BAttributedMailAttachment::SetTo(entry_ref *ref)
|
||||||
{
|
{
|
||||||
if (ref == NULL)
|
if (ref == NULL)
|
||||||
return fStatus = B_BAD_VALUE;
|
return fStatus = B_BAD_VALUE;
|
||||||
@@ -491,36 +547,42 @@ status_t BAttributedMailAttachment::SetTo(entry_ref *ref)
|
|||||||
|
|
||||||
// Set boundary
|
// Set boundary
|
||||||
|
|
||||||
//------This is likely to give a completely random string---
|
// This is likely to give a completely random string
|
||||||
BString boundary;
|
BString boundary;
|
||||||
char buffer[512];
|
char buffer[512];
|
||||||
strcpy(buffer, ref->name);
|
strcpy(buffer, ref->name);
|
||||||
for (int32 i = strlen(buffer);i-- > 0;)
|
for (int32 i = strlen(buffer); i-- > 0;) {
|
||||||
{
|
|
||||||
if (buffer[i] & 0x80)
|
if (buffer[i] & 0x80)
|
||||||
buffer[i] = 'x';
|
buffer[i] = 'x';
|
||||||
else if (buffer[i] == ' ' || buffer[i] == ':')
|
else if (buffer[i] == ' ' || buffer[i] == ':')
|
||||||
buffer[i] = '_';
|
buffer[i] = '_';
|
||||||
}
|
}
|
||||||
buffer[32] = '\0';
|
buffer[32] = '\0';
|
||||||
boundary << "BFile-" << buffer << "--" << ((int32)_data ^ time(NULL)) << "-" << ~((int32)_data ^ (int32)&buffer ^ (int32)&_attributes) << "--";
|
boundary << "BFile-" << buffer << "--" << ((int32)_data ^ time(NULL))
|
||||||
|
<< "-" << ~((int32)_data ^ (int32)&buffer ^ (int32)&_attributes)
|
||||||
|
<< "--";
|
||||||
fContainer->SetBoundary(boundary.String());
|
fContainer->SetBoundary(boundary.String());
|
||||||
|
|
||||||
return fStatus = B_OK;
|
return fStatus = B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
status_t BAttributedMailAttachment::InitCheck()
|
|
||||||
|
status_t
|
||||||
|
BAttributedMailAttachment::InitCheck()
|
||||||
{
|
{
|
||||||
return fStatus;
|
return fStatus;
|
||||||
}
|
}
|
||||||
|
|
||||||
void BAttributedMailAttachment::SaveToDisk(BEntry *entry) {
|
|
||||||
|
void
|
||||||
|
BAttributedMailAttachment::SaveToDisk(BEntry *entry)
|
||||||
|
{
|
||||||
BString path = "/tmp/";
|
BString path = "/tmp/";
|
||||||
char name[255] = "";
|
char name[255] = "";
|
||||||
_data->FileName(name);
|
_data->FileName(name);
|
||||||
path << name;
|
path << name;
|
||||||
|
|
||||||
BFile file(path.String(),B_READ_WRITE | B_CREATE_FILE);
|
BFile file(path.String(), B_READ_WRITE | B_CREATE_FILE);
|
||||||
(BNode&)file << _attributes;
|
(BNode&)file << _attributes;
|
||||||
_data->GetDecodedData(&file);
|
_data->GetDecodedData(&file);
|
||||||
file.Sync();
|
file.Sync();
|
||||||
@@ -528,25 +590,40 @@ void BAttributedMailAttachment::SaveToDisk(BEntry *entry) {
|
|||||||
entry->SetTo(path.String());
|
entry->SetTo(path.String());
|
||||||
}
|
}
|
||||||
|
|
||||||
void BAttributedMailAttachment::SetEncoding(mail_encoding encoding) {
|
|
||||||
|
void
|
||||||
|
BAttributedMailAttachment::SetEncoding(mail_encoding encoding)
|
||||||
|
{
|
||||||
_data->SetEncoding(encoding);
|
_data->SetEncoding(encoding);
|
||||||
if (_attributes_attach != NULL)
|
if (_attributes_attach != NULL)
|
||||||
_attributes_attach->SetEncoding(encoding);
|
_attributes_attach->SetEncoding(encoding);
|
||||||
}
|
}
|
||||||
|
|
||||||
mail_encoding BAttributedMailAttachment::Encoding() {
|
|
||||||
|
mail_encoding
|
||||||
|
BAttributedMailAttachment::Encoding()
|
||||||
|
{
|
||||||
return _data->Encoding();
|
return _data->Encoding();
|
||||||
}
|
}
|
||||||
|
|
||||||
status_t BAttributedMailAttachment::FileName(char *name) {
|
|
||||||
|
status_t
|
||||||
|
BAttributedMailAttachment::FileName(char *name)
|
||||||
|
{
|
||||||
return _data->FileName(name);
|
return _data->FileName(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BAttributedMailAttachment::SetFileName(const char *name) {
|
|
||||||
|
void
|
||||||
|
BAttributedMailAttachment::SetFileName(const char *name)
|
||||||
|
{
|
||||||
_data->SetFileName(name);
|
_data->SetFileName(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
status_t BAttributedMailAttachment::GetDecodedData(BPositionIO *data) {
|
|
||||||
|
status_t
|
||||||
|
BAttributedMailAttachment::GetDecodedData(BPositionIO *data)
|
||||||
|
{
|
||||||
BNode *node = dynamic_cast<BNode *>(data);
|
BNode *node = dynamic_cast<BNode *>(data);
|
||||||
if (node != NULL)
|
if (node != NULL)
|
||||||
*node << _attributes;
|
*node << _attributes;
|
||||||
@@ -555,7 +632,10 @@ status_t BAttributedMailAttachment::GetDecodedData(BPositionIO *data) {
|
|||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
status_t BAttributedMailAttachment::SetDecodedData(BPositionIO *data) {
|
|
||||||
|
status_t
|
||||||
|
BAttributedMailAttachment::SetDecodedData(BPositionIO *data)
|
||||||
|
{
|
||||||
BNode *node = dynamic_cast<BNode *>(data);
|
BNode *node = dynamic_cast<BNode *>(data);
|
||||||
if (node != NULL)
|
if (node != NULL)
|
||||||
_attributes << *node;
|
_attributes << *node;
|
||||||
@@ -564,39 +644,52 @@ status_t BAttributedMailAttachment::SetDecodedData(BPositionIO *data) {
|
|||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
status_t BAttributedMailAttachment::SetToRFC822(BPositionIO *data, size_t length, bool parse_now)
|
|
||||||
|
status_t
|
||||||
|
BAttributedMailAttachment::SetToRFC822(BPositionIO *data, size_t length,
|
||||||
|
bool parseNow)
|
||||||
{
|
{
|
||||||
status_t err = Initialize();
|
status_t err = Initialize();
|
||||||
if (err < B_OK)
|
if (err < B_OK)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
err = fContainer->SetToRFC822(data,length,parse_now);
|
err = fContainer->SetToRFC822(data, length, parseNow);
|
||||||
if (err < B_OK)
|
if (err < B_OK)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
BMimeType type;
|
BMimeType type;
|
||||||
fContainer->MIMEType(&type);
|
fContainer->MIMEType(&type);
|
||||||
if (strcmp(type.Type(),"multipart/x-bfile") != 0)
|
if (strcmp(type.Type(), "multipart/x-bfile") != 0)
|
||||||
return B_BAD_TYPE;
|
return B_BAD_TYPE;
|
||||||
|
|
||||||
// get data and attributes
|
// get data and attributes
|
||||||
if ((_data = dynamic_cast<BSimpleMailAttachment *>(fContainer->GetComponent(0))) == NULL)
|
if ((_data = dynamic_cast<BSimpleMailAttachment *>(
|
||||||
|
fContainer->GetComponent(0))) == NULL)
|
||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
if (parse_now)
|
|
||||||
_data->GetDecodedData(); // Force it to make a copy of the data. Needed for forwarding messages hack.
|
|
||||||
|
|
||||||
if ((_attributes_attach = dynamic_cast<BSimpleMailAttachment *>(fContainer->GetComponent(1))) == NULL
|
if (parseNow) {
|
||||||
|
// Force it to make a copy of the data. Needed for forwarding
|
||||||
|
// messages hack.
|
||||||
|
_data->GetDecodedData();
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((_attributes_attach = dynamic_cast<BSimpleMailAttachment *>(
|
||||||
|
fContainer->GetComponent(1))) == NULL
|
||||||
|| _attributes_attach->GetDecodedData() == NULL)
|
|| _attributes_attach->GetDecodedData() == NULL)
|
||||||
return B_OK;
|
return B_OK;
|
||||||
|
|
||||||
// Convert the attribute binary attachment into a convenient easy to use BMessage.
|
// Convert the attribute binary attachment into a convenient easy to use
|
||||||
|
// BMessage.
|
||||||
|
|
||||||
int32 len = ((BMallocIO *)(_attributes_attach->GetDecodedData()))->BufferLength();
|
int32 len
|
||||||
|
= ((BMallocIO *)(_attributes_attach->GetDecodedData()))->BufferLength();
|
||||||
char *start = (char *)malloc(len);
|
char *start = (char *)malloc(len);
|
||||||
if (start == NULL)
|
if (start == NULL)
|
||||||
return B_NO_MEMORY;
|
return B_NO_MEMORY;
|
||||||
|
|
||||||
if (_attributes_attach->GetDecodedData()->ReadAt(0,start,len) < len)
|
MemoryDeleter deleter(start);
|
||||||
|
|
||||||
|
if (_attributes_attach->GetDecodedData()->ReadAt(0, start, len) < len)
|
||||||
return B_IO_ERROR;
|
return B_IO_ERROR;
|
||||||
|
|
||||||
int32 index = 0;
|
int32 index = 0;
|
||||||
@@ -618,56 +711,64 @@ status_t BAttributedMailAttachment::SetToRFC822(BPositionIO *data, size_t length
|
|||||||
_attributes.AddData(name, code, &start[index], buf_length);
|
_attributes.AddData(name, code, &start[index], buf_length);
|
||||||
index += buf_length;
|
index += buf_length;
|
||||||
}
|
}
|
||||||
free(start);
|
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
status_t BAttributedMailAttachment::RenderToRFC822(BPositionIO *render_to) {
|
|
||||||
|
status_t
|
||||||
|
BAttributedMailAttachment::RenderToRFC822(BPositionIO *renderTo)
|
||||||
|
{
|
||||||
BMallocIO *io = new BMallocIO;
|
BMallocIO *io = new BMallocIO;
|
||||||
|
|
||||||
#if defined(HAIKU_TARGET_PLATFORM_DANO)
|
#if defined(HAIKU_TARGET_PLATFORM_DANO)
|
||||||
const
|
const
|
||||||
#endif
|
#endif
|
||||||
char *name;
|
char *name;
|
||||||
type_code type, swap_typed;
|
type_code type;
|
||||||
for (int32 i = 0; _attributes.GetInfo(B_ANY_TYPE,i,&name,&type) == B_OK; i++) {
|
for (int32 i = 0; _attributes.GetInfo(B_ANY_TYPE, i, &name, &type) == B_OK;
|
||||||
|
i++) {
|
||||||
const void *data;
|
const void *data;
|
||||||
ssize_t dataLen;
|
ssize_t dataLen;
|
||||||
_attributes.FindData(name,type,&data,&dataLen);
|
_attributes.FindData(name, type, &data, &dataLen);
|
||||||
io->Write(name,strlen(name) + 1);
|
io->Write(name, strlen(name) + 1);
|
||||||
swap_typed = B_HOST_TO_BENDIAN_INT32(type);
|
|
||||||
io->Write(&swap_typed,sizeof(type_code));
|
type_code swappedType = B_HOST_TO_BENDIAN_INT32(type);
|
||||||
|
io->Write(&swappedType, sizeof(type_code));
|
||||||
|
|
||||||
int64 length, swapped;
|
int64 length, swapped;
|
||||||
length = dataLen;
|
length = dataLen;
|
||||||
swapped = B_HOST_TO_BENDIAN_INT64(length);
|
swapped = B_HOST_TO_BENDIAN_INT64(length);
|
||||||
io->Write(&swapped,sizeof(int64));
|
io->Write(&swapped,sizeof(int64));
|
||||||
|
|
||||||
void *allocd = malloc(dataLen);
|
void *buffer = malloc(dataLen);
|
||||||
if (allocd == NULL) {
|
if (buffer == NULL) {
|
||||||
delete io;
|
delete io;
|
||||||
return B_NO_MEMORY;
|
return B_NO_MEMORY;
|
||||||
}
|
}
|
||||||
memcpy(allocd,data,dataLen);
|
memcpy(buffer, data, dataLen);
|
||||||
swap_data(type, allocd, dataLen, B_SWAP_HOST_TO_BENDIAN);
|
swap_data(type, buffer, dataLen, B_SWAP_HOST_TO_BENDIAN);
|
||||||
io->Write(allocd,dataLen);
|
io->Write(buffer, dataLen);
|
||||||
free(allocd);
|
free(buffer);
|
||||||
}
|
}
|
||||||
if (_attributes_attach == NULL)
|
if (_attributes_attach == NULL)
|
||||||
_attributes_attach = new BSimpleMailAttachment;
|
_attributes_attach = new BSimpleMailAttachment;
|
||||||
|
|
||||||
_attributes_attach->SetDecodedDataAndDeleteWhenDone(io);
|
_attributes_attach->SetDecodedDataAndDeleteWhenDone(io);
|
||||||
|
|
||||||
return fContainer->RenderToRFC822(render_to);
|
return fContainer->RenderToRFC822(renderTo);
|
||||||
}
|
}
|
||||||
|
|
||||||
status_t BAttributedMailAttachment::MIMEType(BMimeType *mime) {
|
|
||||||
|
status_t
|
||||||
|
BAttributedMailAttachment::MIMEType(BMimeType *mime)
|
||||||
|
{
|
||||||
return _data->MIMEType(mime);
|
return _data->MIMEType(mime);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// The reserved function stubs
|
// #pragma mark - The reserved function stubs
|
||||||
// #pragma mark -
|
|
||||||
|
|
||||||
void BMailAttachment::_ReservedAttachment1() {}
|
void BMailAttachment::_ReservedAttachment1() {}
|
||||||
void BMailAttachment::_ReservedAttachment2() {}
|
void BMailAttachment::_ReservedAttachment2() {}
|
||||||
|
|||||||
Reference in New Issue
Block a user