
All items with #) are implemented, but those with *) not yet.

Mail::Message     design version 1.113
-------------

Targets
*) replace MIME::Entity, Mail::Internet and MIME::Parser to speed-up
   low-level mail processing.
   Why replace existing modules?
   1) they do not use C on the lowest level.  Rewrite of parts of them
      would be more work than reimplementation of all.
   2) certainly MIME::Entity is not smart enough, not defining enough
      simple objects.
   3) they are not conveniently supporting delay-loading.
   4) they ofter use old-fashioned perl.
   The reimplementation will be done with a close look at the
   well documented code in the two existing modules.
*) extend features of Mail::Folder::FastReader.
*) eventually speed-up all mail-processing Perl-modules.
*) handle Mbox-like folders.
*) handle one file (one message) in MH-like folders.
*) support for delay-loading (saves time and memory)

Parts
*) Mail::Box and grepmail (via Mail::Box?) maintain overview over the
   mail-folders.
*) Mail::Message                  Basic messages as stored in a file.
                                  contains some stuff from Mail::Box::Message
*) Mail::Message::Part            isa Mail::Message
*) Mail::Box::Parser              Contains inlined C for simple character
                                  processing on headers and bodiess.
*) Mail::Box
*) Mail::Message::Head            comparible to Mail::Head
*) Mail::Message::Head::Field     one line from header.
*) Mail::Message::Body
*) Mail::Message::Body::NotParsed isa Mail::Message::Body
*) Mail::Message::Body::Lines     isa Mail::Message::Body
*) Mail::Message::Body::Scalar    isa Mail::Message::Body
*) Mail::Message::Body::File      isa Mail::Message::Body
*) Mail::Message::Body::Multipart isa Mail::Message::Body
*) Mail::Message::Compose         adds reply(), create(), and such to
                                  Mail::Message.

= Mail::Box additions

Keeps track on:
   - debug-level
   - class of message-objects
   - default class of head-objects       [Mail::Message::Head]
   - default class of body-objects       [Mail::Message::Body::Lines]
   - default class of multiparts-objects [Mail::Message::Body::Multipart]

#) log warnings and errors

#) report warnings and errors

*) my Mail::Message::Head $head = $folder->readHead()
   - return Mail::Message::Head object
   - lines already `unfolded'
   - newlines removed from the end.

*) my $body = $folder->readBody(want => 'Mail::Message::BodyLines'
      , size => $msg->head->get('Content-Length'));
   $msg->body($body);
   - returns any Mail::Message::Body based on flag.
   - calls Mail::Box::Parser for right type.
   - while reading the body, various trics are used to try determining
     where a message ends.  If there is a size in the message-header,
     it should be checked.

*) $msg->sourceCopy($newfile)
   - Copy the message as located in the original folder file into a different
     file.
   - This is much faster than printing the message from structures.
   - The copy will be exact (so even no header-line order changes and such)

*) $msg->writeToFile($newfile, encode => 'BASE64')
   - Write message from perl-structures into file.
   - calls $msg->head->write and $msg->body->write.
   - ability to encode body (see Mail::Message::Body)


= Mail::Box::Parser

Manages a C-pointer to a structure which handles the file-reading.
Keeps track on:
   - filename
   - filehandle
   - fold headerline
   - current linenumber
   - dos-mode (\r\n at end line, while on UNIX)
   - open status

*) my $fh = Mail::Box::Parser->open(...)
   various options on the file are set.  Called by Mail::Box->open

*) $fh->close
   when the application calls close(), but the application might try
   to use it later which shouldn't result in a core-dump.
   - set open status to 'close'
   Called by Mail::Box->close

*) $fh->DESTROY
   perl's DESTROY removes the folder-object
   - free allocated memory.
   Called by Mail::Box->DESTROY

*) my Mail::Message $msg = $fh->read()
   Simplified access to folder to get one message.  It calls getHead and
   getBody.  About the same as:
      my $msg = new Mail::Message(file => $fh);
      $msg->readHead;
      $msg->readBody;
      return $msg;


= Methods in Mail::Message

#) You may supply a Mail::Message::Head and/or ::Body at instantiation.

*) print $msg->fromLine;
   $msg->fromline('From me in 2001');
   get/set from-line for Mbox-like folders
   This knowledge could be expected in Mail::Box::Mbox::Message, but
   it is found by the Mail::Box::Parser which constructs the Mail::Message.
   The parser has no knowledge about the actual folder-type.

#) my Mail::Message::Head $head = $msg->head;
   Get the headers of this message

#) my Mail::Message::Body $body = $msg->body;
   Get the body of this message

*) $msg->encode(type)  or $part->encode(type)

*) $msg->decode        or $part->decode

*) $msg->signature

= Mail::Message::Body
  extended by Mail::Message::Body::NotParsed
              Mail::Message::Body::Lines
              Mail::Message::Body::Scalar
              Mail::Message::Body::File
              Mail::Message::Body::Multipart

*) $body->nrlines

*) my $file_offset = $body->begin;

*) my $bytesize = $body->size;

*) if($body->isMultipart)
   same as if($body isa 'Mail::Message::Body::Multipart')

*) my Mail::Message::Body $body = Mail::Message::Body::get($fh)
   To be overruled by each sub-class.

*) $body->addPart(@parts);
   Auto-multiparts message

Conversions:

*) $body->write(FILE)
   results in a move when already BodyFile object
   - supports encoding and decoding
   - automatically updates Content-Length field

*) my $whole = $body->string
   use overload '""' => 'string';
   No work for BodyBlock, otherwise conversion.

*) my @lines = $body->lines
   my $lines = $body->lines;   # returns [$body->lines]
   use overload '@{}' => 'lines';
   No work for BodyLines, otherwise conversion.


= Mail::Message::Part isa Mail::Message

A part of a message is a message in itself, but is not by itself
extendible into a folder-part.

*) my $nr = $part->partnr;
   - All parts shall be sequentially numbered within the message,
     even when the multipart is nested.

But I'm sure more functionality is required here, for instance to
support that attachments reside outside the folder-file to improve
speed in opening the folder.


= Mail::Message::Body::NotParsed isa Mail::Message::Body
  but will autoload on any method performed on the body.

Does not convert body from file to memory-structures, but only collects
info to read it later.

*) my $realbody = $body->load
   returns a real subclass of Mail::Message::Body.


= Mail::Message::Body::Scalar isa Mail::Message::Body

Reads the whole message body into one scalar.


= Mail::Message::Body::Lines isa Mail::Message::Body

Reads the whole message body into a list of scalars, each containing
one line.  In dosmode, a \r is stripped from the end of each line,
but the \n will stay there.


= Mail::Message::Body::Multipart isa Mail::Message::Body

Each part is a Mail::Message (-subclass) by itself.

*) print $body->separator || 'no sep yet';
   $body->separator(time . "--$me--$$");
   Get/set part boundary.

*) print $body->preamble      ->string
   Get/set preamble.  Should be empty, but not always is.
   Returns a Mail::Message::Body instance

*) print $body->epilogue      ->string
   Get/set epiloque.  Returns a Mail::Message::Body instance.

*) my @parts = $body->parts()
   get/set all parts

*) my $part = $body->part(42)
   get/set one part   (set to undef means removal, just as
   $body->part(42)->delete)

*) $body->addPart(-1, @parts)
   $body->addPart(@parts)
   Add parts before the specified place, or at the end.


= Mail::Message::Head

Header-fields are used case-insensitive.  

*) my Mail::Message::Head $header       = $msg->head;

*) my Mail::Message::Head::Field $mime  = $msg->head->get('Subject')
   my Mail::Message::Head::Field @mime  = $head->get('Received')
   return the content of the header-field WITHOUT trailing newline

*) my @fields = $head->fields;
   ordered list of read headers.  The order is used when write a message
   to a file, while the data is stored in an (unordered) hash with
   lowercased field-names.

*) my Mail::Message::Head::Field $set = $header->set('Field', contents)
   $header->set($mime);
   $header->set(@mime);
   removes old values (when present).  Adds name to end in field-order,
   when new.

*) my Mail::Message::Head::Field @set = $head->add('Received', contents)
   $head->add($mime);
   $head->add(@mime);
   Adds after header-lines with the same name.  Returns all.


= Mail::Message::Head::Field

One line from the header.  This module will supply some methods to
simplify understanding the headerlines, but not as far as Mail::Field
has implemented.

*) my $mime = Mail::Message::Head::Field->new(
      Content-Type => 'text/plain', charset => 'US-ASCII');
   my $mime = Mail::Message::Head::Field->new(
       'Content-Type: text/plain; charset=US-ASCII');
   my $mime = Mail::Message::Head::Field->new(
       Content-Type => 'text/plain; charset=US-ASCII');

*) my $name    = $mime->field;
   => content-type           [lowercased]

*) my $content = $mime->content;
   => 'text/plain; charset=US-ASCII'

*) my $value   = $mime->value;
   => 'text/plain'

*) my $charset = $mime->option('charset');
   => US-ASCII

*) my %options = $mime->options;

*) print $mime->toString;
   => Content-Type: text/plain; charset=US-ASCII

= package Mail::Message::Compose

Adds methods to Mail::Message, which enables simple create of messages
and replying to messages.  Most functionality of MIME::Entity can go
here.

This module is loaded by AUTOLOAD in Mail::Message::Parsed.

*) my Mail::Message $reply = $msg->reply;

*) my Mail::Message $new = $msg->create(head => ...);
                         [build() in MIME::Entity]

*) $msg->removeSignature [remove_sig() in MIME::Entity]

*) $msg->clone           [dup() in MIME::Entity]

*)                       [smtpsend() in Mail::Internet]
