
MIME++ Change Log
=================

Version 1.3.3 -- 10 February 2001

* Added more examples

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

Version 1.3.2 -- 8 July 2000

* Changes to parser for multipart messages to match the boundary more
  strictly.  Fixes a problem with certain badly formed multipart messages
  from Qualcomm's Eudora

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

Version 1.3.1 -- 12 June 2000

* DwText::operator= rewritten (bug fix)

* DwMediaType::CreateBoundary() adds constant to serial number to avoid
  seeding the random number generator with zero.  (semi-bug fix)

* Fixed bug in DwMailbox which caused the full name to drop a space
  when encoded and non-encoded words were both present

* Function q_decode() changed to pass through 8-bit characters (old
  behavior: 8-bit characters, which are illegal in encoded text, were
  ignored)

* DwDateTime::SetValues() sets the is-modified flag (bug fix)

* In DwAddressList::Assemble(), if an address in the list is invalid,
  it is included in the assembled string.  Similarly, in
  DwMailboxList::Assemble(), if a mailbox in the list is invalid, it
  is included in the assembled string.  (Old behavior: invalid
  addresses were not included)

* In DwAddressList::Parse(), if an address is invalid, it is added to
  the list.  Similarly, in DwMailboxList::Parse(), if a mailbox is
  invalid, it is added to the list.  (Old behavior: invalid addresses
  were not added to the list.)

* Added 'const' to DwMailbox::GetFullName()

* Various bug fixes connected with setting the parent of added child
  objects

* Fixed memory leak in DwBoyerMoore class

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

Version 1.3 -- 29 April 2000

* Content-transfer-encoding utility functions moved from util library to
  core library

* New functions DwBEncode(), DwQEncode(), and DwQDecode() added to support
  encoding and decoding of non-ASCII text in header fields

* New class DwEncodedWord added

* Eliminated use of isspace() and related functions from <ctype.h>.  The
  functions are not suitable for use in MIME++ if the locale is not the
  C locale.  Affects field.cpp, string.cpp, token.cpp, uuencode.cpp.

* New functions in DwMailbox to set and get full name as non-ASCII string

* New system-dependent function DwGetHostByName(), which is thread-safe.
  This function replaces gethostbyname(), which is not thread-safe on
  all Unix OSes.

* (Unix) Uses static mutex initializer

* Changes to DwText to handle encoded words and non-ASCII text (RFC 2047)

* DwMessageComponent::FromString() clears is-modified flag.  I believe
  this is the correct behavior, but *could* conceivably break some
  existing code.

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

Version 1.2.4 -- 21 Feb 2000

* Fixed a bug in DwPopClient::GetMultiListResponse() and
  DwNntpClient::PGetTextResponse().  When there was a period at the
  beginning of a line, the pointer was advanced but the line length
  was not decremented.

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

Version 1.2.3 -- 26 Aug 1999

* DwInitialize() returns a boolean value.  If the return value is false,
  then the library must not be used.

* In Win32, DwInitialize() is called from DllMain() when the DLL is loaded.
  If you are in Win32 but not using a DLL, you must call DwInitialize()
  before using the library, in order to initialize a CRITICAL_SECTION.
  In Unix, DwInitialize() is not used, but it might be a good idea to
  call it, in case this changes in the future.

* DwMediaType::CreateBoundary had a bug where it would create identical
  boundaries for nested body parts.  The fixed version always creates
  a unique boundary.

* DwMsgId::CreateDefault() always creates a unique message ID.  The old
  version would create the same ID if called twice within the same second.

* The parser in DwEntity, which looks for the end of the headers and
  the beginning of the body, will handle most messages where the blank
  line separating headers and body is missing.  A line that is not part
  of a wrapped header field, and which does not contain a colon (':'),
  is considered to be the first line of the body.

* Added DwNextInteger() to system.cpp.  In a multithreaded environment,
  this function provides serialized access to a counter shared by all
  threads.

* The static integer counter, which was used in DwString and in
  DwMessageComponent to assign object IDs have been removed.  The
  ObjectId() functions just return the "this" pointer cast to an integer.
  [This changed was required to make the library multithread-safe.
  Keeping the counter would have required serializing all access to it,
  which would have be too inefficient.]

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

Version 1.2.2 -- 5 Jun 1999

* Y2K fix (sort of).  As of 1989, all dates used in Internet email are
required to use 4 digit years (RFC 1123).  The date handling code in MIME++ has
always used only four digit years, and has always taken a four digit year for
granted.  With this fix, if it receives a two digit year between 0 and 50, it
is assumed to refer to a year in the 2000s.  If it receives a two digit year
between 51 and 99, it is assumed to refer to a year in the 1900s.

* Fixed a bug where the parent object wasn't set when some objects were
copied.

* Fixed a bug that caused a segmentation violation when a date was parsed that
ended with an open parenthesis.

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

Version 1.2.1 -- 18 Mar 1999

* Fixed bug that occurred when using DwString::rfind() on a zero-length string

* Fixed bug in DwPopClient::Uidl(int)

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

Version 1.2 -- 10 Dec 1998

* Added new class DwStamp for representing field-body of Received field

* Uses reentrant version of rand()

* DwMsgId::CreateDefault() changed -- made reentrant

* Removed TakeBuffer(), ReleaseBuffer(), CopyTo(), and RefCount() from
  DwString.

* Changes to DwString to resolve problems that could arise in multithreaded
  environment

* Win32 version uses Win32 API function GetTimeZoneInformation()
  instead of standard C library functions localtime() and gmtime() to
  get time zone

* Fixed bug in DwPopClient -- Uidl(int) calls GetSingleLineReponse()
  instead of GetMultiLineResponse()

* Fixed bug where some DwFieldBody objects where not correctly marked
  as modified when required (DwAddressList, DwBody, DwMailboxList,
  DwMediaType, DwDispositionType)

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

Version 1.1.1 -- 20 May 1998

* The code to convert between strings and enums for media types and subtypes
  was updated to convert the new enums added in version 1.1.

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

Version 1.1 -- 1 May 1998

* The single library is now split into three libraries:
     mimepp_core    - the basic classes for MIME components
	 mimepp_util    - utilities (base64, quoted-printable, and so on)
	 mimepp_net     - SMTP, POP, NNTP
  The primary reason for splitting into three is portability: the core and
  util libraries should be relatively easy to port to other systems, while
  the net library requires the network functions to be ported.

* The library now depends on "portability functions". If you need to port
  the core library to a new platform, just implement the portability
  functions on that platform, and the rest of the library should work. (More
  work would be required to port the net library.) These functions are
  declared in the file system.h. The Unix implementation is in sys_un.cpp;
  the Windows implementation is in sys_nt.cpp.

* Supports ANSI iostreams and cfront-compatible iostreams. Note that these
  two iostreams libraries are not compatible, and you must compile for one
  or the other. The selected library is determined by a "#define" in the
  file config.h.

* Changed the interface for managing lists. The earlier versions used
  intrusive linked lists and supported iteration but not random access.
  The new interface is consistent among all lists, uses dynamically resized
  arrays internally, and supports random access. The affected classes are
  these:
      Containers: DwAddressList, DwBody, DwDispositionType, DwHeaders,
	              DwMailboxList, DwMediaType
      Items:      DwAddress, DwBodyPart, DwField, DwHeaders, DwParameter

* Throws an exception if an index is out of bounds. Added new classes
  DwException and DwBoundsException. A "#define" in config.h allows this
  feature to be disabled.

* There are very few, if any, inline functions.

* The library is more forgiving if there is no final boundary in a multipart
  entity.

* Added member functions to DwBody to access the preamble and epilogue
  of a multipart body.

* Changes to DwDateTime
  - improved interface
  - improved implementation
  - can add the time zone name as a comment string, will recognize the
    time zone name in a final comment
  - all system dependencies are handled in the new portability functions

* More enumerated values for registered IANA values, including MIME media
  types and subtypes. The enums are declared in enum.h.

* Supports Winsock 2. Set the right "#define" in config.h to select Winsock
  1.1 or Winsock 2.

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

Version 1.0 -- 1 Sep 1997

* Convenience member functions added to DwMediaType to access the name
  parameter

* Added configuration option to typedef DwBool to bool

* Compiles as a DLL under Borland C++ 5.0 (as well as VC++ 4 and 5).  I am
  not completely convinced that I got the correct command line switches for
  BCC32.  If you use Borland, you might want to double check the makefile.

* Will handle multipart boundary parameters from nonstandard MIME
  implementations that quote the boundary parameters with single quotes.
  (This is in violation of the MIME++ standard.)

* Fixed a bug where CRLF would be included in the full name part of a
  mailbox if the name was quoted and split across two lines

* DwBinhex class for performing conversion to and from Binhex 4.0 format
  for Macintosh files.

* Much of the documentation has been rewritten or brought up to date.

* Minor changes to DwUuencode.

* The deprecated member functions in DwString are no longer available.

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

26 Jul 1997

* New classes in this release:
  DwUuencode       - for uuencode and uudecode operations
  DwBoyerMoore     - for BoyerMoore algorithm in string searches
  DwProtocolClient - Base class for SMTP, NNTP, and POP protocol classes
  DwSmtpClient     - Implements client side of SMTP session
  DwNntpClient     - Implements client side of NNTP session
  DwPopClient      - Implements client side of POP session

* Full support for Win32 with MS Visual C++ 4 or 5, and Borland C++.

* DwHeader renamed to DwHeaders to eliminate confusion, since people usually
  use the term header to refer to a single header field.

* Compiles as a DLL under Visual C++ (default option)

* There is a config.h file for establishing configuration options at
  compile time. This is safer than requiring you to specify options as
  defines in a makefile.

* Support for namespaces. Alternatively, global enums are encapsulated
  in a class declaration.

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

29 Mar 1997

* The class DwString has been rewritten almost from scratch and is much
  closer to the specification for the ANSI string class.  Eventually, it
  should be possible to typedef DwString to the ANSI string class, thereby
  making MIME++ entirely compatible with the standard C++ library.  (I did
  actually do this successfully a few weeks ago, but I have not tried it
  again since the new DwString was completed.)  Most of the old member
  functions are now obsolete.  You can still compile them if you define
  the right macro (see the makefile).

* The implementations of many classes were changed to permit them to be
  used with the new DwString class.  (They should also work with the
  ANSI string class, if DwString is typedef-ed.)

* The documentation is more complete.  Utility functions for content
  transfer encoding, end-of-line marker conversion, etc. are now included
  in the HTML documentation.  New <FONT> tags in HTML 3.2 are used to
  add color.  The idea is not so much to make the man pages look snazzy;
  I chose colors to make them more readable.

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

6 Feb 1997

* Added new class DwDispositionType, which represents a disposition-type
  as described in RFC-1806.
  
* Changed the name of DwContentType to DwMediaType, which conforms to usage
  in RFC-2068 (HTTP) and is not incompatible with RFC-2045 and RFC-2046.

* Changed the name of DwContentTransferEncoding to DwMechanism, which
  conforms to the BNF term "mechanism" in RFC-2045.

Jan 28, 1997

* Added utility functions for doing end-of-line marker conversions:

    int DwToCrLfEol(const DwString& aSrcStr, DwString& aDestStr);
    int DwToLfEol(const DwString& aSrcStr, DwString& aDestStr);
    int DwToCrEol(const DwString& aSrcStr, DwString& aDestStr);
    int DwToLocalEol(const DwString& aSrcStr, DwString& aDestStr);

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

25 Jan 1997

* Parsers for entities (entity.cc) and bodies (body.cc) changed to handle
  CR LF end-of-line (DOS and MIME) in addition to LF end-of-line (UNIX
  and C).

* Changed multipart body parser to correctly parse boundaries that have
  white space at end of line (transport-padding, in the BNF of RFC-2046).
  With this change, any line that starts with the dash-boundary will be
  recognized as a boundary, even if the extraneous characters are not
  white space (transport-padding).  This should be okay because the MIME
  spec says that the boundary should not appear in the entity.

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

14 Jan 1997

* The library may be compiled as a production version, a development
  version, or a debug version.  The production version tries to recover
  from errors whenever possible: this could mean just returning silently
  from a function with a bad argument value.  The development version has
  assert statements enabled to detect bad argument values or other
  exceptional conditions.  It will dump core so that you can examine
  the state after termination by using a debugger.  The debug version is
  intended to be used when you know a bug exists and you have to find it.
  In the debug version, virtually all classes have a CheckInvariants()
  member function that will abort if one of the invariants in an object
  is violated.  The development version and production version are
  link compatible -- you don't have to recompile your source, just relink
  with the library.  The debug version is not guaranteed to be link
  compatible.
 
* Added a mechanism to detect objects that are deleted more than once.

* Some bugs were fixed.

* Rewrote the makefile, which now includes an 'install' target to copy files
  to /usr/local/include/mimepp and /usr/local/lib.

* Removed the 'dw' prefix from most of the files.  The include files are
  installed into a mimepp directory.  The include preprocessor lines in
  the source code have the directory prefixed
  (e.g. #include <mimepp/mimepp.h>).

* Created a mimepp.h file that includes all header files required for using
  the library.  You can just put #include <mimepp/mimepp.h> at the top of
  your source code.

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

17 Nov 1996

* DwMessageComponent has new protected data member mClassName and new
  member function ClassName().

* DwContentType has new convenience member function CreateBoundary(), which
  applies to multipart entities only.

* DwMessageId is now DwMsgId, which conforms to the RFC-822 BNF grammar.

* Lots of changes to DwHeader.

  + DwHeader::Interpret() is gone.  It's been replaced by
    DwField::CreateFieldBody().

  + Access to all RFC-822, RFC-1036, and RFC-1521 header fields via
    member functions (DwHeader::To(), DwHeader::From(), ...).

  + New member functions to test for the presence of standard header fields.
    (DwHeader::HasTo(), DwHeader::HasFrom(), ...).

  + Various other changes to DwHeader's interface, mostly dealing with
    adding or removing fields.  (Advanced functions.)

* Added member function CreateFieldBody() to DwField.

* Improvements to the wrapper classes used in the examples.

* New wrapper class MessageWithAttachments, used in Example 5 (exampl05.cc).

* The documentation now includes a tutorial.

* All *.h files have been extensively commented.  These files will serve
  as a poor man's reference manual until the real reference manual is
  completed.
