mimelib1-1.1.4/0000755000175000017500000000000011207320664012615 5ustar resivoresivomimelib1-1.1.4/Makefile.am0000644000175000017500000000007511175345261014657 0ustar resivoresivoSUBDIRS = mimelib messages: AUTOMAKE_OPTIONS = foreign 1.4 mimelib1-1.1.4/configure.in0000644000175000017500000000200511207320664015123 0ustar resivoresivo# -*- Autoconf -*- # Process this file with autoconf to produce a configure script. AC_PREREQ([2.63]) AC_INIT(libmimelib, 1.1.4) AC_CONFIG_SRCDIR([mimelib/protocol.cpp]) AM_INIT_AUTOMAKE AC_CONFIG_HEADERS([config.h]) # Checks for programs. AC_PROG_CXX AC_PROG_AWK AC_PROG_CC AC_PROG_CPP AC_PROG_INSTALL AC_PROG_LN_S AC_PROG_MAKE_SET AC_LIBTOOL_DLOPEN AM_PROG_LIBTOOL AC_SUBST(LIBTOOL_DEPS) # Checks for libraries. # Checks for header files. AC_CHECK_HEADERS([arpa/inet.h limits.h netdb.h netinet/in.h stddef.h stdlib.h string.h strings.h sys/socket.h sys/time.h unistd.h]) # Checks for typedefs, structures, and compiler characteristics. AC_C_CONST AC_C_INLINE AC_TYPE_SIZE_T # Checks for library functions. AC_CHECK_FUNCS([gethostbyname gethostname getpagesize inet_ntoa localtime_r memmove memset munmap select socket strerror strtol]) AC_OUTPUT([Makefile mimelib/Makefile mimelib/mimelib/Makefile mimelib/tests/Makefile]) mimelib1-1.1.4/mimelib/0000755000175000017500000000000011207320612014224 5ustar resivoresivomimelib1-1.1.4/mimelib/attach.h0000644000175000017500000000344711175345261015664 0ustar resivoresivo//============================================================================= // File: attach.h // Contents: Declarations for MessageWithAttachments // Maintainer: Doug Sauder // WWW: http://www.fwb.gulf.net/~dwsauder/mimepp.html // // Copyright (c) 1996, 1997 Douglas W. Sauder // All rights reserved. // // IN NO EVENT SHALL DOUGLAS W. SAUDER BE LIABLE TO ANY PARTY FOR DIRECT, // INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF // THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF DOUGLAS W. SAUDER // HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // DOUGLAS W. SAUDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT // NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A // PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" // BASIS, AND DOUGLAS W. SAUDER HAS NO OBLIGATION TO PROVIDE MAINTENANCE, // SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. // //============================================================================= #ifndef ATTACH_H #define ATTACH_H #include "multipar.h" class DwString; class MessageWithAttachments : public MultipartMessage { public: MessageWithAttachments(); virtual ~MessageWithAttachments(); void SetText(const DwString& aStr); int NumberOfAttachments() const; void Attach7bitFile(const char* aFilename, int aType=DwMime::kTypeText, int aSubtype=DwMime::kSubtypePlain); void Attach8bitFile(const char* aFilename, int aType=DwMime::kTypeText, int aSubtype=DwMime::kSubtypePlain); void AttachBinaryFile(const char* aFilename, int aType=DwMime::kTypeApplication, int aSubtype=DwMime::kSubtypeOctetStream); protected: int PutFileInString(const char* aFilename, DwString& str); }; #endif mimelib1-1.1.4/mimelib/Changes0000644000175000017500000001600211175345261015531 0ustar resivoresivo MIME++ Change Log ================= September 1, 1997 o Convenience member functions added to DwMediaType to access the name parameter o Added configuration option to typedef DwBool to bool o 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. o 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.) o 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 o DwBinhex class for performing conversion to and from Binhex 4.0 format for Macintosh files. o Much of the documentation has been rewritten or brought up to date. o Minor changes to DwUuencode. o The deprecated member functions in DwString are no longer available. July 26, 1997 o 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 o Full support for Win32 with MS Visual C++ 4 or 5, and Borland C++. o DwHeader renamed to DwHeaders to eliminate confusion, since people usually use the term header to refer to a single header field. o Compiles as a DLL under Visual C++ (default option) o 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. o Support for namespaces. Alternatively, global enums are encapsulated in a class declaration. Mar 29, 1997 o 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). o 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.) o 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 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. Feb 6, 1997 o Added new class DwDispositionType, which represents a disposition-type as described in RFC-1806. o 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. o Changed the name of DwContentTransferEncoding to DwMechanism, which conforms to the BNF term "mechanism" in RFC-2045. Jan 28, 1997 o 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); Jan 25, 1997 o 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). o 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. Jan 14, 1997 o 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. o Added a mechanism to detect objects that are deleted more than once. o Some bugs were fixed. o Rewrote the makefile, which now includes an 'install' target to copy files to /usr/local/include/mimepp and /usr/local/lib. o 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 ). o Created a mimepp.h file that includes all header files required for using the library. You can just put #include at the top of your source code. Nov 17, 1996 o DwMessageComponent has new protected data member mClassName and new member function ClassName(). o DwContentType has new convenience member function CreateBoundary(), which applies to multipart entities only. o DwMessageId is now DwMsgId, which conforms to the RFC-822 BNF grammar. o 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.) o Added member function CreateFieldBody() to DwField. o Improvements to the wrapper classes used in the examples. o New wrapper class MessageWithAttachments, used in Example 5 (exampl05.cc). o The documentation now includes a tutorial. o 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. mimelib1-1.1.4/mimelib/uuencode.cpp0000644000175000017500000002432611207317105016551 0ustar resivoresivo//============================================================================= // File: uuencode.cpp // Contents: Definitions for DwUuencode // Maintainer: Doug Sauder // WWW: http://www.fwb.gulf.net/~dwsauder/mimepp.html // // Copyright (c) 1996, 1997 Douglas W. Sauder // All rights reserved. // // IN NO EVENT SHALL DOUGLAS W. SAUDER BE LIABLE TO ANY PARTY FOR DIRECT, // INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF // THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF DOUGLAS W. SAUDER // HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // DOUGLAS W. SAUDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT // NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A // PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" // BASIS, AND DOUGLAS W. SAUDER HAS NO OBLIGATION TO PROVIDE MAINTENANCE, // SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. // //============================================================================= #define DW_IMPLEMENTATION #include #include #include #include #include #if defined(DW_TESTING_UUENCODE) #include #include #include #include #endif DwUuencode::DwUuencode() { memset(mFileName, 0, sizeof(mFileName)); mMode = 0644; } DwUuencode::~DwUuencode() { } void DwUuencode::SetFileName(const char* aName) { size_t n = sizeof(mFileName); strncpy(mFileName, aName, n); mFileName[n-1] = 0; // Superfluous } const char* DwUuencode::FileName() const { return mFileName; } void DwUuencode::SetFileMode(DwUint16 aMode) { mMode = aMode; } DwUint16 DwUuencode::FileMode() const { return mMode; } void DwUuencode::SetBinaryChars(const DwString& aStr) { mBinaryChars = aStr; } const DwString& DwUuencode::BinaryChars() const { return mBinaryChars; } void DwUuencode::SetAsciiChars(const DwString& aStr) { mAsciiChars = aStr; } const DwString& DwUuencode::AsciiChars() const { return mAsciiChars; } #define ENC(c) ((char) ((c) ? ((c) & 0x3F) + ' ' : 96 )) void DwUuencode::Encode() { // Get input buffer size_t binLen = mBinaryChars.length(); const char* binBuf = mBinaryChars.data(); size_t binPos = 0; // Allocate buffer for binary chars size_t ascSize = (binLen+2)/3*4 + ((binLen+44)/45+1)*(strlen(DW_EOL)+1) + strlen(mFileName) + 13 + 2*strlen(DW_EOL) + 100; DwString ascStr(ascSize, (char)0); char* ascBuf = (char*)ascStr.data(); size_t ascPos = 0; // Write the "begin" line snprintf(ascBuf, ascSize, "begin %o %s" DW_EOL, mMode, mFileName); ascPos = strlen(ascBuf); // Encode the binary chars while (ascPos < ascSize) { int numBinChars = binLen - binPos; numBinChars = (numBinChars <= 45) ? numBinChars : 45; ascBuf[ascPos++] = ENC(numBinChars); if (numBinChars == 0) { strcpy(&ascBuf[ascPos], DW_EOL); ascPos += strlen(DW_EOL); break; } int bin, asc; int binCharsDone = 0; while (binCharsDone <= numBinChars - 3) { bin = binBuf[binPos++]; asc = (bin & 0xFC) >> 2; ascBuf[ascPos++] = ENC(asc); asc = (bin & 0x03) << 4; bin = binBuf[binPos++]; asc |= (bin & 0xF0) >> 4; ascBuf[ascPos++] = ENC(asc); asc = (bin & 0x0F) << 2; bin = binBuf[binPos++]; asc |= (bin & 0xC0) >> 6; ascBuf[ascPos++] = ENC(asc); asc = bin & 0x3F; ascBuf[ascPos++] = ENC(asc); binCharsDone += 3; } if (binCharsDone < numBinChars) { int binCharsLeft = numBinChars - binCharsDone; switch (binCharsLeft) { case 1: bin = binBuf[binPos++]; asc = (bin & 0xFC) >> 2; ascBuf[ascPos++] = ENC(asc); asc = (bin & 0x03) << 4; ascBuf[ascPos++] = ENC(asc); ascBuf[ascPos++] = 96; ascBuf[ascPos++] = 96; break; case 2: bin = binBuf[binPos++]; asc = (bin & 0xFC) >> 2; ascBuf[ascPos++] = ENC(asc); asc = (bin & 0x03) << 4; bin = binBuf[binPos++]; asc |= (bin & 0xF0) >> 4; ascBuf[ascPos++] = ENC(asc); asc = (bin & 0x0F) << 2; ascBuf[ascPos++] = ENC(asc); ascBuf[ascPos++] = 96; break; default: break; } } strcpy(&ascBuf[ascPos], DW_EOL); ascPos += strlen(DW_EOL); } // Write the "end" line strcpy(&ascBuf[ascPos], "end" DW_EOL); ascPos += 3 + strlen(DW_EOL); ascBuf[ascPos] = 0; mAsciiChars.assign(ascStr, 0, ascPos); } #define DEC(c) (((c) - ' ') & 0x3F) int DwUuencode::Decode() { int retVal = -1; // Get input buffer size_t ascLen = mAsciiChars.length(); const char* ascBuf = mAsciiChars.data(); size_t ascPos = 0; // Allocate destination buffer size_t binSize = (ascLen+3)/4*3; mBinaryChars.reserve(binSize); // Look for "begin " at beginning of buffer if (ascPos + 6 <= ascLen && strncmp(&ascBuf[ascPos], "begin ", 6) == 0) { ascPos += 6; } else { // Find "\nbegin " or "\rbegin " while (ascPos < ascLen) { int ch = ascBuf[ascPos++] & 0xff; switch (ch) { case '\n': case '\r': if (ascPos + 6 <= ascLen && strncmp(&ascBuf[ascPos], "begin ", 6) == 0) { ascPos += 6; goto LOOP_EXIT_1; } break; default: break; } } } LOOP_EXIT_1: // Get mode mMode = 0; while (ascPos < ascLen && isdigit(ascBuf[ascPos])) { mMode <<= 3; mMode += (DwUint16) (ascBuf[ascPos++] - '0'); } // Get file name while (ascPos < ascLen && (ascBuf[ascPos] == ' ' || ascBuf[ascPos] == '\t')) { ++ascPos; } size_t p1 = 0; while (ascPos < ascLen && p1 < sizeof(mFileName)-1 && !isspace(ascBuf[ascPos])) { mFileName[p1++] = ascBuf[ascPos++]; } mFileName[p1] = 0; // Advance to beginning of next line while (ascPos < ascLen) { int ch = ascBuf[ascPos++]; switch (ch) { case '\n': goto LOOP_EXIT_2; case '\r': if (ascPos < ascLen && ascBuf[ascPos] == '\n') { ++ascPos; } goto LOOP_EXIT_2; default: break; } } LOOP_EXIT_2: // Decode chars while (ascPos < ascLen) { int asc, bin; // Get number of binary chars in this line asc = ascBuf[ascPos++] & 0xff; size_t numBinChars = DEC(asc); if (numBinChars == 0) { break; } // Decode this line size_t binCharsEaten = 0; while (binCharsEaten <= numBinChars - 3 && ascPos <= ascLen - 4) { asc = ascBuf[ascPos++] & 0xff; bin = (DEC(asc) & 0x3F) << 2; asc = ascBuf[ascPos++] & 0xff; bin |= (DEC(asc) & 0x30) >> 4; mBinaryChars.append((size_t) 1, (char) bin); bin = (DEC(asc) & 0x0F) << 4; asc = ascBuf[ascPos++] & 0xff; bin |= (DEC(asc) & 0x3C) >> 2; mBinaryChars.append((size_t) 1, (char) bin); bin = (DEC(asc) & 0x03) << 6; asc = ascBuf[ascPos++] & 0xff; bin |= (DEC(asc) & 0x3F); mBinaryChars.append((size_t) 1, (char) bin); binCharsEaten += 3; } // Special case if number of binary chars is not divisible by 3 if (binCharsEaten < numBinChars) { int binCharsLeft = numBinChars - binCharsEaten; switch (binCharsLeft) { case 2: if (ascPos >= ascLen) break; asc = ascBuf[ascPos++] & 0xff; bin = (DEC(asc) & 0x3F) << 2; if (ascPos >= ascLen) break; asc = ascBuf[ascPos++] & 0xff; bin |= (DEC(asc) & 0x30) >> 4; mBinaryChars.append((size_t) 1, (char) bin); bin = (DEC(asc) & 0x0F) << 4; if (ascPos >= ascLen) break; asc = ascBuf[ascPos++] & 0xff; bin |= (DEC(asc) & 0x3C) >> 2; mBinaryChars.append((size_t) 1, (char) bin); break; case 1: if (ascPos >= ascLen) break; asc = ascBuf[ascPos++] & 0xff; bin = (DEC(asc) & 0x3F) << 2; if (ascPos >= ascLen) break; asc = ascBuf[ascPos++] & 0xff; bin |= (DEC(asc) & 0x30) >> 4; mBinaryChars.append((size_t) 1, (char) bin); break; default: break; } } // Advance to beginning of next line while (ascPos < ascLen) { int ch = ascBuf[ascPos++]; switch (ch) { case '\n': goto LOOP_EXIT_3; case '\r': if (ascPos < ascLen && ascBuf[ascPos] == '\n') { ++ascPos; } goto LOOP_EXIT_3; default: break; } } LOOP_EXIT_3: ; } while (ascPos < ascLen) { int ch = ascBuf[ascPos++]; switch (ch) { case '\n': goto LOOP_EXIT_4; case '\r': if (ascPos < ascLen && ascBuf[ascPos] == '\n') { ++ascPos; } goto LOOP_EXIT_4; default: break; } } LOOP_EXIT_4: if (ascPos + 3 <= ascLen && strncmp(&ascBuf[ascPos], "end", 3) == 0) { retVal = 0; } return retVal; } #if defined(DW_TESTING_UUENCODE) // Test harness for DwUudecode int main(int argc, char** argv) { srand(time(0)); DwString binStr; binStr.reserve(5000); char ch; int i; for (i=0; i < 4000; ++i) { ch = rand()/(double)RAND_MAX*256; binStr += (char) ch; } for ( ; i < 4100; ++i) { binStr += (char) 0; } DwUuencode uu; uu.SetFileName("Testfile.dat"); uu.SetMode(0600); uu.SetBinaryChars(binStr); uu.Encode(); DwString asciiStr = uu.AsciiChars(); // std::ofstream out("test.out", ios::out|ios::binary); std::ofstream out("test.out", ios::out); out << asciiStr; DwUuencode uu1; uu1.SetAsciiChars(uu.AsciiChars()); uu1.Decode(); size_t n = uu1.BinaryChars().length(); const char* b1 = binStr.data(); const char* b2 = uu1.BinaryChars().data(); int bad = 0; for (i=0; i < n; ++i) { if (b1[i] != b2[i]) { cout << "Binary chars not equal at position " << i << "\n"; bad = 1; break; } } if (! bad) { cout << "A-okay\n"; } return 0; } #endif mimelib1-1.1.4/mimelib/bodypart.cpp0000644000175000017500000000764411175345261016602 0ustar resivoresivo//============================================================================= // File: bodypart.cpp // Contents: Definitions for DwBodyPart // Maintainer: Doug Sauder // WWW: http://www.fwb.gulf.net/~dwsauder/mimepp.html // // Copyright (c) 1996, 1997 Douglas W. Sauder // All rights reserved. // // IN NO EVENT SHALL DOUGLAS W. SAUDER BE LIABLE TO ANY PARTY FOR DIRECT, // INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF // THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF DOUGLAS W. SAUDER // HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // DOUGLAS W. SAUDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT // NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A // PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" // BASIS, AND DOUGLAS W. SAUDER HAS NO OBLIGATION TO PROVIDE MAINTENANCE, // SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. // //============================================================================= #define DW_IMPLEMENTATION #include #include #include #include #include #include #include #include #include #include #include #include #include const char* const DwBodyPart::sClassName = "DwBodyPart"; DwBodyPart* (*DwBodyPart::sNewBodyPart)(const DwString&, DwMessageComponent*) = 0; DwBodyPart* DwBodyPart::NewBodyPart(const DwString& aStr, DwMessageComponent* aParent) { if (sNewBodyPart) { DwBodyPart* newPart = sNewBodyPart(aStr, aParent); //if( newPart ) // newPart->mNext = 0; return newPart; } else { return new DwBodyPart(aStr, aParent); } } DwBodyPart::DwBodyPart() { mNext = 0; mClassId = kCidBodyPart; mClassName = sClassName; } DwBodyPart::DwBodyPart(const DwBodyPart& aPart) : DwEntity(aPart) { mNext = 0; mClassId = kCidBodyPart; mClassName = sClassName; } DwBodyPart::DwBodyPart(const DwEntity& aPart) : DwEntity(aPart) { mNext = 0; mClassId = kCidBodyPart; mClassName = sClassName; } DwBodyPart::DwBodyPart(const DwString& aStr, DwMessageComponent* aParent) : DwEntity(aStr, aParent) { mNext = 0; mClassId = kCidBodyPart; mClassName = sClassName; } DwBodyPart::~DwBodyPart() { // fprintf( stderr, "\ndeleted a DwBodyPart\n"); } const DwBodyPart& DwBodyPart::operator = (const DwBodyPart& aPart) { if (this == &aPart) return *this; DwEntity::operator = (aPart); mNext = aPart.Next(); return *this; } DwBodyPart* DwBodyPart::Next() const { return (DwBodyPart*) mNext; } void DwBodyPart::SetNext(const DwBodyPart* aPart) { mNext = aPart; } DwMessageComponent* DwBodyPart::Clone() const { return new DwBodyPart(*this); } #if defined(DW_DEBUG_VERSION) void DwBodyPart::PrintDebugInfo(std::ostream& aStrm, int aDepth) const { aStrm << "----------- Debug info for DwBodyPart class -----------\n"; _PrintDebugInfo(aStrm); int depth = aDepth - 1; depth = (depth >= 0) ? depth : 0; if (aDepth == 0 || depth > 0) { mHeaders->PrintDebugInfo(aStrm, depth); mBody->PrintDebugInfo(aStrm, depth); } } #else void DwBodyPart::PrintDebugInfo(std::ostream&, int) const {} #endif // defined(DW_DEBUG_VERSION) #if defined(DW_DEBUG_VERSION) void DwBodyPart::_PrintDebugInfo(std::ostream& aStrm) const { DwEntity::_PrintDebugInfo(aStrm); aStrm << "Next body part: "; if (mNext) { aStrm << mNext->ObjectId() << '\n'; } else { aStrm << "(none)\n"; } } #else void DwBodyPart::_PrintDebugInfo(std::ostream& ) const {} #endif // defined(DW_DEBUG_VERSION) void DwBodyPart::CheckInvariants() const { #if defined(DW_DEBUG_VERSION) DwEntity::CheckInvariants(); #endif // defined(DW_DEBUG_VERSION) } mimelib1-1.1.4/mimelib/datetime.cpp0000644000175000017500000003045311175345261016544 0ustar resivoresivo//============================================================================= // File: datetime.cpp // Contents: Definitions for DwDateTime // Maintainer: Doug Sauder // WWW: http://www.fwb.gulf.net/~dwsauder/mimepp.html // // Copyright (c) 1996, 1997 Douglas W. Sauder // All rights reserved. // // IN NO EVENT SHALL DOUGLAS W. SAUDER BE LIABLE TO ANY PARTY FOR DIRECT, // INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF // THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF DOUGLAS W. SAUDER // HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // DOUGLAS W. SAUDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT // NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A // PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" // BASIS, AND DOUGLAS W. SAUDER HAS NO OBLIGATION TO PROVIDE MAINTENANCE, // SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. // //============================================================================= #define DW_IMPLEMENTATION #include #include #include #include #include #include #include #include #include static char lWeekDay[7][4] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"}; static char lMonth[12][4] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}; extern "C" int ParseRfc822Date(const char *str, struct tm *tms, int *z); extern "C" int ParseDate(const char *str, struct tm *tms, int *z); static DwInt32 ymd_to_jdnl(int year, int mon, int day, int julian); static void jdnl_to_ymd(DwInt32 jdn, int *year, int *mon, int *day, int julian); static DwUint32 my_inv_gmtime(struct tm* ptms); const char* const DwDateTime::sClassName = "DwDateTime"; int DwDateTime::sDefaultZone = 0; int DwDateTime::sIsDefaultZoneSet = 0; DwDateTime* (*DwDateTime::sNewDateTime)(const DwString&, DwMessageComponent*) = 0; DwDateTime* DwDateTime::NewDateTime(const DwString& aStr, DwMessageComponent* aParent) { if (sNewDateTime) { return sNewDateTime(aStr, aParent); } else { return new DwDateTime(aStr, aParent); } } void DwDateTime::SetDefaultZone(int aZone) { sDefaultZone = aZone; sIsDefaultZoneSet = 1; } DwDateTime::DwDateTime() { Init(); mIsModified = 1; } DwDateTime::DwDateTime(const DwDateTime& aDateTime) : DwFieldBody(aDateTime) { mYear = aDateTime.mYear; mMonth = aDateTime.mMonth; mDay = aDateTime.mDay; mHour = aDateTime.mHour; mMinute = aDateTime.mMinute; mSecond = aDateTime.mSecond; mZone = aDateTime.mZone; } DwDateTime::DwDateTime(const DwString& aStr, DwMessageComponent* aParent) : DwFieldBody(aStr, aParent) { Init(); mIsModified = 0; } void DwDateTime::Init() { mClassId = kCidDateTime; mClassName = DwDateTime::sClassName; // Check if default time zone is set if (sIsDefaultZoneSet == 0) { // Use calls to gmtime() and localtime() to get the time difference // between local time and UTC (GMT) time. time_t t_now = time((time_t*) 0); #if defined(HAVE_GMTIME_R) struct tm utc; gmtime_r(&t_now, &utc); struct tm local; localtime_r(&t_now, &local); #else struct tm utc = *gmtime(&t_now); struct tm local = *localtime(&t_now); #endif DwUint32 t_local = my_inv_gmtime(&local); DwUint32 t_utc = my_inv_gmtime(&utc); sDefaultZone = (int) (t_local - t_utc)/60; sIsDefaultZoneSet = 1; } // Set the time zone from the default time zone mZone = sDefaultZone; // Get the current calendar time time_t t_now = time((time_t*) 0); // Set year, month, day, hour, minute, and second from calendar time _FromCalendarTime(t_now); } DwDateTime::~DwDateTime() { } const DwDateTime& DwDateTime::operator = (const DwDateTime& aDateTime) { if (this == &aDateTime) return *this; DwFieldBody::operator = (aDateTime); mYear = aDateTime.mYear; mMonth = aDateTime.mMonth; mDay = aDateTime.mDay; mHour = aDateTime.mHour; mMinute = aDateTime.mMinute; mSecond = aDateTime.mSecond; mZone = aDateTime.mZone; return *this; } DwUint32 DwDateTime::AsUnixTime() const { struct tm tt; tt.tm_year = mYear - 1900; tt.tm_mon = mMonth - 1; tt.tm_mday = mDay; tt.tm_hour = mHour; tt.tm_min = mMinute; tt.tm_sec = mSecond; DwUint32 t = my_inv_gmtime(&tt); t = (t == (DwUint32) -1) ? 0 : t; t -= mZone*60; return t; } void DwDateTime::FromUnixTime(DwUint32 aTime) { _FromUnixTime(aTime); SetModified(); } void DwDateTime::_FromUnixTime(DwUint32 aTime) { time_t t = aTime + mZone*60; #if defined(HAVE_GMTIME_R) struct tm tt; gmtime_r(&t, &tt); #else struct tm tt = *gmtime(&t); #endif mYear = tt.tm_year + 1900; mMonth = tt.tm_mon + 1; mDay = tt.tm_mday; mHour = tt.tm_hour; mMinute = tt.tm_min; mSecond = tt.tm_sec; } void DwDateTime::FromCalendarTime(time_t aTime) { _FromCalendarTime(aTime); SetModified(); } void DwDateTime::_FromCalendarTime(time_t aTime) { // Note: the broken-down time is the only portable representation. // ANSI does not even require that time_t be an integer type; it could // be a double. And, it doesn't even have to be in seconds. // Get the broken-down time. #if defined(HAVE_GMTIME_R) struct tm tms_utc; gmtime_r(&aTime, &tms_utc); #else struct tm tms_utc = *gmtime(&aTime); #endif // Convert to UNIX time, using portable routine DwUint32 t_unix = my_inv_gmtime(&tms_utc); // Set from the UNIX time _FromUnixTime(t_unix); } DwInt32 DwDateTime::DateAsJulianDayNum() const { DwInt32 jdn = ymd_to_jdnl(mYear, mMonth, mDay, -1); return jdn; } void DwDateTime::DateFromJulianDayNum(DwInt32 aJdn) { jdnl_to_ymd(aJdn, &mYear, &mMonth, &mDay, -1); SetModified(); } DwInt32 DwDateTime::TimeAsSecsPastMidnight() const { DwInt32 n = mHour; n *= 60; n += mMinute; n *= 60; n += mSecond; return n; } void DwDateTime::TimeFromSecsPastMidnight(DwInt32 aSecs) { mSecond = (int) (aSecs % 60); aSecs /= 60; mMinute = (int) (aSecs % 60); aSecs /= 60; mHour = (int) (aSecs % 24); SetModified(); } void DwDateTime::Parse() { mIsModified = 0; char buffer[80]; char *str; int mustDelete; // Allocate memory from heap only in rare instances where the buffer // is too small. if (mString.length() >= 80) { mustDelete = 1; str = new char [mString.length()+1]; } else { mustDelete = 0; str = buffer; } strncpy(str, mString.data(), mString.length()); str[mString.length()] = 0; str[79] = 0; struct tm tms; int zone; int err = ParseRfc822Date(str, &tms, &zone); if ( err == -1 ) // try another format err = ParseDate(str, &tms, &zone); if (!err) { mYear = tms.tm_year + 1900; mMonth = tms.tm_mon+1; mDay = tms.tm_mday; mHour = tms.tm_hour; mMinute = tms.tm_min; mSecond = tms.tm_sec; mZone = zone; } else /* if (err) */ { mYear = 1970; mMonth = 1; mDay = 1; mHour = 0; mMinute = 0; mSecond = 0; mZone = 0; } if (mustDelete) { delete[] str; } } void DwDateTime::Assemble() { if (!mIsModified) return; // Find the day of the week DwInt32 jdn = DateAsJulianDayNum(); int dow = (int) ((jdn+1)%7); char sgn = (mZone < 0) ? '-' : '+'; int z = (mZone < 0) ? -mZone : mZone; char buffer[80]; snprintf(buffer, sizeof(buffer), "%s, %d %s %4d %02d:%02d:%02d %c%02d%02d", lWeekDay[dow], mDay, lMonth[(mMonth-1)%12], mYear, mHour, mMinute, mSecond, sgn, z/60%24, z%60); mString = buffer; mIsModified = 0; } DwMessageComponent* DwDateTime::Clone() const { return new DwDateTime(*this); } #if defined (DW_DEBUG_VERSION) void DwDateTime::PrintDebugInfo(std::ostream& aStrm, int /*aDepth*/) const { aStrm << "---------------- Debug info for DwDateTime class ---------------\n"; _PrintDebugInfo(aStrm); } #else void DwDateTime::PrintDebugInfo(std::ostream& , int) const {} #endif // defined (DW_DEBUG_VERSION) #if defined (DW_DEBUG_VERSION) void DwDateTime::_PrintDebugInfo(std::ostream& aStrm) const { DwFieldBody::_PrintDebugInfo(aStrm); aStrm << "Date: " << mYear << '-' << mMonth << '-' << mDay << ' ' << mHour << ':' << mMinute << ':' << mSecond << ' ' << mZone << '\n'; } #else void DwDateTime::_PrintDebugInfo(std::ostream& ) const {} #endif // defined (DW_DEBUG_VERSION) void DwDateTime::CheckInvariants() const { #if defined (DW_DEBUG_VERSION) DwFieldBody::CheckInvariants(); assert(mYear >= 0); assert(1 <= mMonth && mMonth <= 12); assert(1 <= mDay && mDay <= 31); assert(0 <= mHour && mHour < 24); assert(0 <= mMinute && mMinute < 60); assert(0 <= mSecond && mSecond < 60); assert(-12*60 <= mZone && mZone <= 12*60); #endif // defined (DW_DEBUG_VERSION) } #ifdef PAPAL /* Pope Gregory XIII's decree */ #define LASTJULDATE 15821004L /* last day to use Julian calendar */ #define LASTJULJDN 2299160L /* jdn of same */ #else /* British-American usage */ #define LASTJULDATE 17520902L /* last day to use Julian calendar */ #define LASTJULJDN 2361221L /* jdn of same */ #endif static DwInt32 ymd_to_jdnl(int year, int mon, int day, int julian) { DwInt32 jdn; if (julian < 0) /* set Julian flag if auto set */ julian = (((year * 100L) + mon) * 100 + day <= LASTJULDATE); if (year < 0) /* adjust BC year */ year++; if (julian) jdn = 367L * year - 7 * (year + 5001L + (mon - 9) / 7) / 4 + 275 * mon / 9 + day + 1729777L; else jdn = (DwInt32)(day - 32075) + 1461L * (year + 4800L + (mon - 14) / 12) / 4 + 367 * (mon - 2 - (mon - 14) / 12 * 12) / 12 - 3 * ((year + 4900L + (mon - 14) / 12) / 100) / 4; return jdn; } static void jdnl_to_ymd(DwInt32 jdn, int *year, int *mon, int *day, int julian) { DwInt32 x, z, m, d, y; DwInt32 daysPer400Years = 146097L; DwInt32 fudgedDaysPer4000Years = 1460970L + 31; if (julian < 0) /* set Julian flag if auto set */ julian = (jdn <= LASTJULJDN); x = jdn + 68569L; if (julian) { x += 38; daysPer400Years = 146100L; fudgedDaysPer4000Years = 1461000L + 1; } z = 4 * x / daysPer400Years; x = x - (daysPer400Years * z + 3) / 4; y = 4000 * (x + 1) / fudgedDaysPer4000Years; x = x - 1461 * y / 4 + 31; m = 80 * x / 2447; d = x - 2447 * m / 80; x = m / 11; m = m + 2 - 12 * x; y = 100 * (z - 49) + y + x; *year = (int)y; *mon = (int)m; *day = (int)d; if (*year <= 0) /* adjust BC years */ (*year)--; } #define JDN_JAN_1_1970 2440588L /* * Converts broken-down time to time in seconds since 1 Jan 1970 00:00. * Pays no attention to time zone or daylight savings time. Another way * to think about this function is that it is the inverse of gmtime(). * One word of caution: the values in the broken down time must be * correct. * * This function is different from mktime() in three ways: * 1. mktime() accepts a broken-down local time and converts it to a scalar * UTC time. Thus, mktime() takes time zone and daylight savings time * information into account when computing the scalar time. (This makes * mktime() highly non-portable). * 2. mktime() will adjust for non-standard values, such as a tm_mday member * that is out of range. This function does no such conversion. * 3. mktime() sets the struct fields tm_yday, tm_wday, and tm_isdst to * their correct values on output. This function does not. */ static DwUint32 my_inv_gmtime(struct tm* ptms) { DwInt32 jdn; DwUint32 t; jdn = ymd_to_jdnl(ptms->tm_year+1900, ptms->tm_mon+1, ptms->tm_mday, -1); t = jdn - JDN_JAN_1_1970; /* days */ t = 24*t + ptms->tm_hour; /* hours */ t = 60*t + ptms->tm_min; /* minutes */ t = 60*t + ptms->tm_sec; /* seconds */ return t; } mimelib1-1.1.4/mimelib/tests/0000755000175000017500000000000011175345261015401 5ustar resivoresivomimelib1-1.1.4/mimelib/tests/test_boyermor.cpp0000644000175000017500000000464611175345261021014 0ustar resivoresivo#include #include #include #include using std::cerr; using std::cout; using std::endl; static const char * _haystack = "haystackNeedleHaystackneedlehaYstackneeDlehaystack"; int main( int argc, char * argv[] ) { if ( argc == 3 ) { // manual test DwString needle( argv[1] ); DwString haystack( argv[2] ); DwBoyerMoore csbm( needle ); // case-sensitive DwBoyerMoore cisbm( needle ); // case-insensitive cout << "Case-sensitive search found "; for ( size_t idx = 0 ; ( idx = csbm.FindIn( haystack, idx ) ) != DwString::npos ; ++idx ) cout << (int)idx << " "; cout << endl; cout << "Case-insensitive search found "; for ( size_t idx = 0 ; ( idx = cisbm.FindIn( haystack, idx, false ) ) != DwString::npos ; ++idx ) cout << (int)idx << " "; cout << endl; exit( 0 ); } else if ( argc == 1 ) { // automated test DwString haystack( _haystack ); DwBoyerMoore needle_cs( "needle" ); DwBoyerMoore needle_cis( "needle" ); DwBoyerMoore Needle_cs( "Needle" ); DwBoyerMoore Needle_cis( "Needle" ); DwBoyerMoore neeDle_cs( "neeDle" ); DwBoyerMoore neeDle_cis( "neeDle" ); assert( needle_cs.FindIn( haystack, 0 ) == 22 ); assert( needle_cs.FindIn( haystack, 23 ) == DwString::npos ); assert( needle_cis.FindIn( haystack, 0, false ) == 8 ); assert( needle_cis.FindIn( haystack, 9, false ) == 22 ); assert( needle_cis.FindIn( haystack, 23, false ) == 36 ); assert( needle_cis.FindIn( haystack, 37, false ) == DwString::npos ); assert( Needle_cs.FindIn( haystack, 0 ) == 8 ); assert( Needle_cs.FindIn( haystack, 9 ) == DwString::npos ); assert( Needle_cis.FindIn( haystack, 0, false ) == 8 ); assert( Needle_cis.FindIn( haystack, 9, false ) == 22 ); assert( Needle_cis.FindIn( haystack, 23, false ) == 36 ); assert( Needle_cis.FindIn( haystack, 37, false ) == DwString::npos ); assert( neeDle_cs.FindIn( haystack, 0 ) == 36 ); assert( neeDle_cs.FindIn( haystack, 37 ) == DwString::npos ); assert( neeDle_cis.FindIn( haystack, 0, false ) == 8 ); assert( neeDle_cis.FindIn( haystack, 9, false ) == 22 ); assert( neeDle_cis.FindIn( haystack, 23, false ) == 36 ); assert( neeDle_cis.FindIn( haystack, 37, false ) == DwString::npos ); } else { cerr << "usage: test_boyermor [ ]" << endl; exit( 1 ); } return 0; } mimelib1-1.1.4/mimelib/tests/exampl02.cpp0000644000175000017500000000511411175345261017536 0ustar resivoresivo//============================================================================= // File: exampl02.cpp // Contents: Source code for Example 2 -- Parsing a simple message // Maintainer: Doug Sauder // WWW: http://www.fwb.gulf.net/~dwsauder/mimepp.html // // Copyright (c) 1996, 1997 Douglas W. Sauder // All rights reserved. // // IN NO EVENT SHALL DOUGLAS W. SAUDER BE LIABLE TO ANY PARTY FOR DIRECT, // INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF // THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF DOUGLAS W. SAUDER // HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // DOUGLAS W. SAUDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT // NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A // PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" // BASIS, AND DOUGLAS W. SAUDER HAS NO OBLIGATION TO PROVIDE MAINTENANCE, // SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. // //============================================================================= #include #include #include #include "basicmsg.h" #include int main() { // Initialize the library DwInitialize(); // Read message from file DwString messageStr = ""; DwString line; std::ifstream istrm("exampl02.txt"); while (DwTrue) { getline(istrm, line); if (istrm.eof()) { break; } messageStr += line + DW_EOL; } istrm.close(); // Create a DwMessage and parse it. The DwMessage should be created on // the free store, since it will be added to the BasicMessage. DwMessage* msg = DwMessage::NewMessage(messageStr, 0); msg->Parse(); // Create a Message and add the DwMessage to it BasicMessage message(msg); // Open file stream for output std::ofstream ostrm("exampl02.out"); // Print the header fields ostrm << "Type -> " << message.TypeStr() << std::endl; ostrm << "Subtype -> " << message.SubtypeStr() << std::endl; ostrm << "Content-Transfer-Encoding -> " << message.CteStr() << std::endl; ostrm << "Date -> " << message.DateStr() << std::endl; ostrm << "From -> " << message.From() << std::endl; ostrm << "To -> " << message.To() << std::endl; ostrm << "Cc -> " << message.Cc() << std::endl; ostrm << "Bcc -> " << message.Bcc() << std::endl; ostrm << "Subject -> " << message.Subject() << std::endl; // Print the body ostrm << "\nBody ->" << std::endl; ostrm << message.Body() << std::endl; return 0; } mimelib1-1.1.4/mimelib/tests/exampl05.cpp0000644000175000017500000000413711175345261017545 0ustar resivoresivo//============================================================================= // File: exampl05.cpp // Contents: Source code for Example 5 -- Creating a message with // Maintainer: Doug Sauder // WWW: http://www.fwb.gulf.net/~dwsauder/mimepp.html // // Copyright (c) 1996, 1997 Douglas W. Sauder // All rights reserved. // // IN NO EVENT SHALL DOUGLAS W. SAUDER BE LIABLE TO ANY PARTY FOR DIRECT, // INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF // THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF DOUGLAS W. SAUDER // HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // DOUGLAS W. SAUDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT // NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A // PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" // BASIS, AND DOUGLAS W. SAUDER HAS NO OBLIGATION TO PROVIDE MAINTENANCE, // SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. // //============================================================================= #include #include #include #include #include "attach.h" int main() { // Initialize the library DwInitialize(); // Create a MessageWithAttachements MessageWithAttachments msg; // Create MIME-Version and Message-id header fields msg.SetAutomaticFields(); // Set header fields DwUint32 t = (DwUint32) time(NULL); msg.SetDate(t); msg.SetFrom("Emily Postnews "); msg.SetTo("verbose@noisy"); msg.SetCc("forgetful@myvax"); msg.SetBcc("eager@beaver.dam"); msg.SetSubject("Re: How long should my signature be?"); // Add text DwString text = "Read the attached files\n"; msg.SetText(text); // Add 7bit attachment msg.Attach7bitFile("exampl05.txt"); // Add 8bit attachment msg.Attach8bitFile("exampl05.txt"); // Add binary attachment msg.AttachBinaryFile("exampl05.txt"); // Write it to a file std::ofstream ostrm("exampl05.out"); ostrm << msg.AsString(); return 0; } mimelib1-1.1.4/mimelib/tests/INSTALL0000644000175000017500000000262511175345261016437 0ustar resivoresivoSorry, there's no autoconf script available yet. However, there are comments in the makefile to help you out, and there are not a lot of changes to make. There are different options available, some of which are platform dependent. For example, under Win32 you can compile the library as a .LIB or as a .DLL. To change any of the defaults, edit the file ./mimepp/config.h. It's probably a good idea to take a look at that file anyway. There are several makefiles available. Makefile.unx is a makefile for a generic UNIX system. Makefile.vc is a makefile for Visual C++ 4 or 5. Makefile.bc is a makefile for Borland C++ 5. If you are using the library on a non-UNIX system, such as Windows 3.1 or Macintosh, you will probably need to change msgid.cpp. The function DwMsgId::CreateDefault() needs to get the host name and the process ID to create a msg-id. I put some conditional compilation macros in to support Winsock, but I have not tested it under Windows 3.1. If you do not know how to get your host name, you can set the static member DwMsgId::sHostName before using the library functions. On a UNIX system: Typing 'make -f makefile.unx' will make the library libmimepp.a and the example programs exampl01, exampl02, exampl03, exampl04, exampl05; typing 'make lib' will make just the library. Finally, type 'make install ' to copy the include files to /usr/local/include/mimepp and the library to /usr/local/lib. mimelib1-1.1.4/mimelib/tests/exampl01.txt0000644000175000017500000000271011175345261017571 0ustar resivoresivo> Dear Miss Postnews: > > How long should my signature be? > > -- verbose@noisy Dear Verbose: Please try and make your signature as long as you can. It's much more important than your article, of course, so try and have more lines of signature than actual text. Try and include a large graphic made of ASCII characters, plus lots of cute quotes and slogans. People will never tire of reading these pearls of wisdom again and again, and you will soon become personally associated with the joy each reader feels at seeing yet another delightful repeat of your signature. Be sure as well to include a complete map of USENET with each signature, to show how anybody can get mail to you from any site in the world. Be sure to include ARPA gateways as well. Also tell people on your own site how to mail to you. Give independent addresses for Internet, UUCP, BITNET, Arpanet and CSNET, even if they're all the same. Aside from your reply address, include your full name, company and organization. It's just common courtesy -- after all, in some newsreaders people have to type an *entire* keystroke to go back to the top of your article to see this information in the header. By all means include your phone number and street address in every single article. People are always responding to usenet articles with phone calls and letters. It would be silly to go to the extra trouble of including this information only in articles that need a response by conventional channels! Em mimelib1-1.1.4/mimelib/tests/exampl03.txt0000644000175000017500000000214211175345261017572 0ustar resivoresivo> Dear Ms. Postnews: > > I couldn't get mail through to somebody on another site. What should I do? > > -- eager@beaver.dam Dear Eager: No problem, just post your message to a group that a lot of people read. Say, "This is for John Smith. I couldn't get mail through so I'm posting it. All others please ignore." This way tens of thousands of people will spend a few seconds scanning over and ignoring your article, using up over 16 man-hours of their collective time, but you will be saved the terrible trouble of checking through usenet maps or looking for alternate routes. Just think, if you couldn't distribute your message to 9000 other computers, you might actually have to (gasp) call directory assistance for 60 cents, or even phone the person. This can cost as much as a few DOLLARS (!) for a 5 minute call! And certainly it's better to spend 10 to 20 dollars of other people's money distributing the message than for you to have to waste $9 on an overnight letter, or even 29 cents on a stamp! Don't forget. The world will end if your message doesn't get through, so post it as many places as you can. Em mimelib1-1.1.4/mimelib/tests/exampl02.txt0000644000175000017500000000171511175345261017576 0ustar resivoresivoMIME-Version: 1.0 Message-Id: <97082402002000.00107@kaybee> Date: Sun, 24 Aug 1997 02:00:20 -0500 Content-Type: Text/Plain Content-Transfer-Encoding: 7bit From: Emily Postnews To: verbose@noisy Cc: forgetful@myvax Bcc: eager@beaver.dam Subject: Re: Forgot my signature! > Dear Emily > > Today I posted an article and forgot to include my signature. What should I > do? > > -- forgetful@myvax Dear Forgetful: Rush to your terminal right away and post an article that says, "Oops, I forgot to post my signature with that last article. Here it is." Since most people will have forgotten your earlier article, (particularly since it dared to be so boring as to not have a nice, juicy signature) this will remind them of it. Besides, people care much more about the signature anyway. See the previous letter for more important details. Also, be sure to include your signature TWICE in each article. That way you're sure people will read it. Em mimelib1-1.1.4/mimelib/tests/Makefile.am0000644000175000017500000000033211175345261017433 0ustar resivoresivoAM_CPPFLAGS = -I$(top_srcdir)/mimelib/mimelib test_boyermor_SOURCES = test_boyermor.cpp test_boyermor_LDADD = $(top_srcdir)/mimelib/libmimelib.la $(LIBSOCKET) check_PROGRAMS = test_boyermor TESTS=$(check_PROGRAMS) mimelib1-1.1.4/mimelib/tests/exampl01.cpp0000644000175000017500000000424611175345261017542 0ustar resivoresivo//============================================================================= // File: exampl01.cpp // Contents: Source code for Example 1 -- Creating a simple message // Maintainer: Doug Sauder // WWW: http://www.fwb.gulf.net/~dwsauder/mimepp.html // // Copyright (c) 1996, 1997 Douglas W. Sauder // All rights reserved. // // IN NO EVENT SHALL DOUGLAS W. SAUDER BE LIABLE TO ANY PARTY FOR DIRECT, // INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF // THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF DOUGLAS W. SAUDER // HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // DOUGLAS W. SAUDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT // NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A // PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" // BASIS, AND DOUGLAS W. SAUDER HAS NO OBLIGATION TO PROVIDE MAINTENANCE, // SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. // //============================================================================= #include #include #include #include #include "basicmsg.h" int main() { // Initialize the library DwInitialize(); // Get a buffer of data from a text file DwString buffer = ""; DwString line; std::ifstream istrm("exampl01.txt"); while (DwTrue) { getline(istrm, line); if (istrm.eof()) { break; } buffer += line + DW_EOL; } istrm.close(); // Create a message BasicMessage msg; // Create MIME-Version and Message-id header fields msg.SetAutomaticFields(); // Set header fields msg.SetDate(time(NULL)); msg.SetTypeStr("Text"); msg.SetSubtypeStr("Plain"); msg.SetCteStr("7bit"); msg.SetFrom("Emily Postnews "); msg.SetTo("verbose@noisy"); msg.SetCc("forgetful@myvax"); msg.SetBcc("eager@beaver.dam"); msg.SetSubject("Re: How long should my signature be?"); // Set body msg.SetBody(buffer); // Write it to a file std::ofstream ostrm("exampl01.out"); ostrm << msg.AsString(); return 0; } mimelib1-1.1.4/mimelib/tests/exampl05.txt0000644000175000017500000000271011175345261017575 0ustar resivoresivo> Dear Miss Postnews: > > How long should my signature be? > > -- verbose@noisy Dear Verbose: Please try and make your signature as long as you can. It's much more important than your article, of course, so try and have more lines of signature than actual text. Try and include a large graphic made of ASCII characters, plus lots of cute quotes and slogans. People will never tire of reading these pearls of wisdom again and again, and you will soon become personally associated with the joy each reader feels at seeing yet another delightful repeat of your signature. Be sure as well to include a complete map of USENET with each signature, to show how anybody can get mail to you from any site in the world. Be sure to include ARPA gateways as well. Also tell people on your own site how to mail to you. Give independent addresses for Internet, UUCP, BITNET, Arpanet and CSNET, even if they're all the same. Aside from your reply address, include your full name, company and organization. It's just common courtesy -- after all, in some newsreaders people have to type an *entire* keystroke to go back to the top of your article to see this information in the header. By all means include your phone number and street address in every single article. People are always responding to usenet articles with phone calls and letters. It would be silly to go to the extra trouble of including this information only in articles that need a response by conventional channels! Em mimelib1-1.1.4/mimelib/tests/exampl04.cpp0000644000175000017500000000762411175345261017550 0ustar resivoresivo//============================================================================= // File: exampl04.cpp // Contents: Source code for Example 4 -- Parsing a multipart message // Maintainer: Doug Sauder // WWW: http://www.fwb.gulf.net/~dwsauder/mimepp.html // // Copyright (c) 1996, 1997 Douglas W. Sauder // All rights reserved. // // IN NO EVENT SHALL DOUGLAS W. SAUDER BE LIABLE TO ANY PARTY FOR DIRECT, // INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF // THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF DOUGLAS W. SAUDER // HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // DOUGLAS W. SAUDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT // NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A // PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" // BASIS, AND DOUGLAS W. SAUDER HAS NO OBLIGATION TO PROVIDE MAINTENANCE, // SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. // //============================================================================= #include #include #include #include "multipar.h" int main() { // Initialize the library DwInitialize(); // Read message from file DwString messageStr = ""; DwString line; std::ifstream istrm("exampl04.txt"); while (DwTrue) { getline(istrm, line); if (istrm.eof()) { break; } messageStr += line + DW_EOL; } istrm.close(); // Create a DwMessage and parse it. The DwMessage should be created on // the free store, since it will be added to the MultipartMessage. DwMessage* msg = DwMessage::NewMessage(messageStr, 0); msg->Parse(); // Make sure it is a multipart message // If is not a multipart message, we could create a BasicMessage instead, // but we won't do that in this example. if (msg->Headers().ContentType().Type() != DwMime::kTypeMultipart) { std::cerr << "Not a multipart message\n"; return 0; } // Create a MultipartMessage MultipartMessage multipart(msg); // Open file stream for output std::ofstream ostrm("exampl04.out"); // Print the header fields ostrm << "Type -> " << multipart.TypeStr() << std::endl; ostrm << "Subtype -> " << multipart.SubtypeStr() << std::endl; ostrm << "Date -> " << multipart.DateStr() << std::endl; ostrm << "From -> " << multipart.From() << std::endl; ostrm << "To -> " << multipart.To() << std::endl; ostrm << "Cc -> " << multipart.Cc() << std::endl; ostrm << "Bcc -> " << multipart.Bcc() << std::endl; ostrm << "Subject -> " << multipart.Subject() << std::endl; // Read the body parts and print them MultipartBodyPart part; DwString body; int numParts = multipart.NumberOfParts(); for (int idx=0; idx < numParts; ++idx) { multipart.BodyPart(idx, part); ostrm << "\nBody part number " << idx << std::endl; ostrm << "Type -> " << part.TypeStr() << std::endl; ostrm << "Subtype -> " << part.SubtypeStr() << std::endl; ostrm << "Content transfer encoding -> " << part.ContentTransferEncodingStr() << std::endl; ostrm << "Content description -> " << part.ContentDescription() << std::endl; int cte = part.ContentTransferEncoding(); if (cte == DwMime::kCteBase64) { DwDecodeBase64(part.Body(), body); ostrm << "Body (decoded) ->" << std::endl << body << std::endl; } else if (cte == DwMime::kCteQuotedPrintable) { DwDecodeQuotedPrintable(part.Body(), body); ostrm << "Body (decoded) ->" << std::endl << body << std::endl; } else { body = part.Body(); ostrm << "Body ->" << std::endl << body << std::endl; } } return 0; } mimelib1-1.1.4/mimelib/tests/exampl04.txt0000644000175000017500000000633111175345261017577 0ustar resivoresivoMIME-Version: 1.0 Message-Id: <97082402123500.00119@kaybee> Content-Type: Multipart/Mixed; boundary="Boundary-=_pHqghUmeaYlNlfdXfircvsCxgGBw" Date: Sun, 24 Aug 1997 02:12:35 -0500 From: Emily Postnews To: verbose@noisy Cc: forgetful@myvax Bcc: eager@beaver.dam Subject: Getting email through --Boundary-=_pHqghUmeaYlNlfdXfircvsCxgGBw Content-Type: Text/Plain Content-Transfer-Encoding: 7bit Content-Description: text, unencoded > Dear Ms. Postnews: > > I couldn't get mail through to somebody on another site. What should I do? > > -- eager@beaver.dam Dear Eager: No problem, just post your message to a group that a lot of people read. Say, "This is for John Smith. I couldn't get mail through so I'm posting it. All others please ignore." This way tens of thousands of people will spend a few seconds scanning over and ignoring your article, using up over 16 man-hours of their collective time, but you will be saved the terrible trouble of checking through usenet maps or looking for alternate routes. Just think, if you couldn't distribute your message to 9000 other computers, you might actually have to (gasp) call directory assistance for 60 cents, or even phone the person. This can cost as much as a few DOLLARS (!) for a 5 minute call! And certainly it's better to spend 10 to 20 dollars of other people's money distributing the message than for you to have to waste $9 on an overnight letter, or even 29 cents on a stamp! Don't forget. The world will end if your message doesn't get through, so post it as many places as you can. Em --Boundary-=_pHqghUmeaYlNlfdXfircvsCxgGBw Content-Type: Text/Plain Content-Transfer-Encoding: base64 Content-Description: text, base64 encoded PiBEZWFyIE1zLiBQb3N0bmV3czoKPgo+IEkgY291bGRuJ3QgZ2V0IG1haWwgdGhyb3VnaCB0byBz b21lYm9keSBvbiBhbm90aGVyIHNpdGUuIFdoYXQgc2hvdWxkIEkgZG8/Cj4KPiAtLSBlYWdlckBi ZWF2ZXIuZGFtCgpEZWFyIEVhZ2VyOgoKTm8gcHJvYmxlbSwganVzdCBwb3N0IHlvdXIgbWVzc2Fn ZSB0byBhIGdyb3VwIHRoYXQgYSBsb3Qgb2YgcGVvcGxlIHJlYWQuClNheSwgIlRoaXMgaXMgZm9y IEpvaG4gU21pdGguIEkgY291bGRuJ3QgZ2V0IG1haWwgdGhyb3VnaCBzbyBJJ20gcG9zdGluZyBp dC4KQWxsIG90aGVycyBwbGVhc2UgaWdub3JlLiIKClRoaXMgd2F5IHRlbnMgb2YgdGhvdXNhbmRz IG9mIHBlb3BsZSB3aWxsIHNwZW5kIGEgZmV3IHNlY29uZHMgc2Nhbm5pbmcgb3ZlcgphbmQgaWdu b3JpbmcgeW91ciBhcnRpY2xlLCB1c2luZyB1cCBvdmVyIDE2IG1hbi1ob3VycyBvZiB0aGVpciBj b2xsZWN0aXZlCnRpbWUsIGJ1dCB5b3Ugd2lsbCBiZSBzYXZlZCB0aGUgdGVycmlibGUgdHJvdWJs ZSBvZiBjaGVja2luZyB0aHJvdWdoIHVzZW5ldAptYXBzIG9yIGxvb2tpbmcgZm9yIGFsdGVybmF0 ZSByb3V0ZXMuIEp1c3QgdGhpbmssIGlmIHlvdSBjb3VsZG4ndCBkaXN0cmlidXRlCnlvdXIgbWVz c2FnZSB0byA5MDAwIG90aGVyIGNvbXB1dGVycywgeW91IG1pZ2h0IGFjdHVhbGx5IGhhdmUgdG8g KGdhc3ApIGNhbGwKZGlyZWN0b3J5IGFzc2lzdGFuY2UgZm9yIDYwIGNlbnRzLCBvciBldmVuIHBo b25lIHRoZSBwZXJzb24uIFRoaXMgY2FuIGNvc3QKYXMgbXVjaCBhcyBhIGZldyBET0xMQVJTICgh KSBmb3IgYSA1IG1pbnV0ZSBjYWxsIQoKQW5kIGNlcnRhaW5seSBpdCdzIGJldHRlciB0byBzcGVu ZCAxMCB0byAyMCBkb2xsYXJzIG9mIG90aGVyIHBlb3BsZSdzIG1vbmV5CmRpc3RyaWJ1dGluZyB0 aGUgbWVzc2FnZSB0aGFuIGZvciB5b3UgdG8gaGF2ZSB0byB3YXN0ZSAkOSBvbiBhbiBvdmVybmln aHQKbGV0dGVyLCBvciBldmVuIDI5IGNlbnRzIG9uIGEgc3RhbXAhCgpEb24ndCBmb3JnZXQuIFRo ZSB3b3JsZCB3aWxsIGVuZCBpZiB5b3VyIG1lc3NhZ2UgZG9lc24ndCBnZXQgdGhyb3VnaCwgc28K cG9zdCBpdCBhcyBtYW55IHBsYWNlcyBhcyB5b3UgY2FuLgoKRW0K --Boundary-=_pHqghUmeaYlNlfdXfircvsCxgGBw-- mimelib1-1.1.4/mimelib/tests/exampl03.cpp0000644000175000017500000000526411175345261017545 0ustar resivoresivo//============================================================================= // File: exampl03.cpp // Contents: Source code for Example 3 -- Creating a multipart message // Maintainer: Doug Sauder // WWW: http://www.fwb.gulf.net/~dwsauder/mimepp.html // // Copyright (c) 1996, 1997 Douglas W. Sauder // All rights reserved. // // IN NO EVENT SHALL DOUGLAS W. SAUDER BE LIABLE TO ANY PARTY FOR DIRECT, // INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF // THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF DOUGLAS W. SAUDER // HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // DOUGLAS W. SAUDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT // NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A // PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" // BASIS, AND DOUGLAS W. SAUDER HAS NO OBLIGATION TO PROVIDE MAINTENANCE, // SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. // //============================================================================= #include #include #include #include #include "multipar.h" int main() { // Initialize the library DwInitialize(); // Get a buffer of data from a text file DwString buffer = ""; DwString line; std::ifstream istrm("exampl03.txt"); while (DwTrue) { getline(istrm, line); if (istrm.eof()) { break; } buffer += line + DW_EOL; } istrm.close(); // Create a MultipartMessage MultipartMessage msg; // Create MIME-Version and Message-id header fields msg.SetAutomaticFields(); // Set header fields DwUint32 t = (DwUint32) time(NULL); msg.SetDate(t); msg.SetFrom("Emily Postnews "); msg.SetTo("verbose@noisy"); msg.SetCc("forgetful@myvax"); msg.SetBcc("eager@beaver.dam"); msg.SetSubject("Getting email through"); // Add body part 1 MultipartBodyPart part; part.SetType(DwMime::kTypeText); part.SetSubtype(DwMime::kSubtypePlain); part.SetContentTransferEncoding(DwMime::kCte7bit); part.SetContentDescription("text, unencoded"); part.SetBody(buffer); msg.AddBodyPart(part); // Add body part 2 part.SetType(DwMime::kTypeText); part.SetSubtype(DwMime::kSubtypePlain); part.SetContentTransferEncoding(DwMime::kCteBase64); part.SetContentDescription("text, base64 encoded"); DwString ascData; DwEncodeBase64(buffer, ascData); part.SetBody(ascData); msg.AddBodyPart(part); // Write it to a file std::ofstream ostrm("exampl03.out"); ostrm << msg.AsString(); return 0; } mimelib1-1.1.4/mimelib/field.cpp0000644000175000017500000003061211175345261016030 0ustar resivoresivo//============================================================================= // File: field.cpp // Contents: Definitions for DwField // Maintainer: Doug Sauder // WWW: http://www.fwb.gulf.net/~dwsauder/mimepp.html // // Copyright (c) 1996, 1997 Douglas W. Sauder // All rights reserved. // // IN NO EVENT SHALL DOUGLAS W. SAUDER BE LIABLE TO ANY PARTY FOR DIRECT, // INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF // THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF DOUGLAS W. SAUDER // HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // DOUGLAS W. SAUDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT // NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A // PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" // BASIS, AND DOUGLAS W. SAUDER HAS NO OBLIGATION TO PROVIDE MAINTENANCE, // SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. // //============================================================================= #define DW_IMPLEMENTATION #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include class DwFieldParser { friend class DwField; private: DwFieldParser(const DwString&); void Parse(); const DwString mString; DwString mName; DwString mBody; }; DwFieldParser::DwFieldParser(const DwString& aStr) : mString(aStr) { Parse(); } void DwFieldParser::Parse() { const char* buf = mString.data(); size_t bufEnd = mString.length(); size_t pos = 0; size_t start = 0; size_t len = 0; // Get field name while (pos < bufEnd) { if (buf[pos] == ':') { break; } ++pos; } len = pos; // Remove any white space at end of field-name while (len > 0) { int ch = buf[len-1]; if (ch != ' ' && ch != '\t') break; --len; } mName = mString.substr(start, len); if (pos < bufEnd && buf[pos] == ':') { ++pos; } // Skip spaces and tabs (but not newline!) while (pos < bufEnd) { if (buf[pos] != ' ' && buf[pos] != '\t') break; ++pos; } start = pos; len = 0; // Get field body while (pos < bufEnd) { if (buf[pos] == '\n') { // Are we at the end of the string? if (pos == bufEnd - 1) { ++pos; break; } // Is this really the end of the field body, and not just // the end of a wrapped line? else if (buf[pos+1] != ' ' && buf[pos+1] != '\t') { ++pos; break; } } ++pos; } // Remove white space at end of field-body while (pos > start) { if (!isspace(buf[pos-1])) break; --pos; } len = pos - start; mBody = mString.substr(start, len); } //=========================================================================== const char* const DwField::sClassName = "DwField"; DwField* (*DwField::sNewField)(const DwString&, DwMessageComponent*) = 0; DwFieldBody* (*DwField::sCreateFieldBody)(const DwString&, const DwString&, DwMessageComponent*) = 0; DwField* DwField::NewField(const DwString& aStr, DwMessageComponent* aParent) { if (sNewField) { return sNewField(aStr, aParent); } else { return new DwField(aStr, aParent); } } DwField::DwField() { mNext = 0; mFieldBody = 0; mClassId = kCidField; mClassName = sClassName; } DwField::DwField(const DwField& aField) : DwMessageComponent(aField), mFieldNameStr(aField.mFieldNameStr), mFieldBodyStr(aField.mFieldBodyStr) { mNext = 0; if (aField.mFieldBody) { mFieldBody = (DwFieldBody*) aField.mFieldBody->Clone(); } else { mFieldBody = 0; } mClassId = kCidField; mClassName = sClassName; } DwField::DwField(const DwString& aStr, DwMessageComponent* aParent) : DwMessageComponent(aStr, aParent) { mNext = 0; mFieldBody = 0; mClassId = kCidField; mClassName = sClassName; } DwField::~DwField() { if (mFieldBody) { delete mFieldBody; } } const DwField& DwField::operator = (const DwField& aField) { if (this == &aField) return *this; DwMessageComponent::operator = (aField); mFieldNameStr = aField.mFieldNameStr; mFieldBodyStr = aField.mFieldBodyStr; if (mFieldBody) { delete mFieldBody; mFieldBody = (DwFieldBody*) aField.mFieldBody->Clone(); } return *this; } const DwString& DwField::FieldNameStr() const { return mFieldNameStr; } void DwField::SetFieldNameStr(const DwString& aStr) { mFieldNameStr = aStr; SetModified(); } const DwString& DwField::FieldBodyStr() const { return mFieldBodyStr; } void DwField::SetFieldBodyStr(const DwString& aStr) { mFieldBodyStr = aStr; if (mFieldBody) { delete mFieldBody; mFieldBody = 0; } SetModified(); } DwFieldBody* DwField::FieldBody() const { return mFieldBody; } void DwField::SetFieldBody(DwFieldBody* aFieldBody) { int isModified = 0; if (mFieldBody != aFieldBody) { isModified = 1; } mFieldBody = aFieldBody; if (mFieldBody) { mFieldBody->SetParent(this); } if (isModified) { SetModified(); } } void DwField::_SetFieldBody(DwFieldBody* aFieldBody) { mFieldBody = aFieldBody; if (mFieldBody) { mFieldBody->SetParent(this); } } DwField* DwField::Next() const { return (DwField*) mNext; } void DwField::SetNext(const DwField* aNext) { mNext = aNext; } void DwField::Parse() { mIsModified = 0; DwFieldParser parser(mString); mFieldNameStr = parser.mName; mFieldBodyStr = parser.mBody; mFieldBody = CreateFieldBody(mFieldNameStr, mFieldBodyStr, this); assert(mFieldBody != 0); mFieldBody->Parse(); } void DwField::Assemble() { if (!mIsModified) return; if (mFieldBody) { mFieldBody->Assemble(); mFieldBodyStr = mFieldBody->AsString(); } mString = ""; mString += mFieldNameStr; mString += ": "; mString += mFieldBodyStr; mString += DW_EOL; mIsModified = 0; } DwMessageComponent* DwField::Clone() const { return new DwField(*this); } DwFieldBody* DwField::CreateFieldBody(const DwString& aFieldName, const DwString& aFieldBody, DwMessageComponent* aParent) { DwFieldBody* fieldBody; if (sCreateFieldBody != 0) { fieldBody = sCreateFieldBody(aFieldName, aFieldBody, aParent); } else { fieldBody = _CreateFieldBody(aFieldName, aFieldBody, aParent); } return fieldBody; } DwFieldBody* DwField::_CreateFieldBody(const DwString& aFieldName, const DwString& aFieldBody, DwMessageComponent* aParent) { enum { kAddressList, kDispositionType, kDateTime, kMailbox, kMailboxList, kMechanism, kMediaType, kMsgId, kText } fieldBodyType; // Default field type is 'text' fieldBodyType = kText; int ch = aFieldName[0]; ch = tolower(ch); switch (ch) { case 'b': if (DwStrcasecmp(aFieldName, "bcc") == 0) { fieldBodyType = kAddressList; } break; case 'c': if (DwStrcasecmp(aFieldName, "cc") == 0) { fieldBodyType = kAddressList; } else if (DwStrcasecmp(aFieldName, "content-id") == 0) { fieldBodyType = kMsgId; } else if (DwStrcasecmp(aFieldName, "content-transfer-encoding") == 0) { fieldBodyType = kMechanism; } else if (DwStrcasecmp(aFieldName, "content-type") == 0) { fieldBodyType = kMediaType; } else if (DwStrcasecmp(aFieldName, "content-disposition") == 0) { fieldBodyType = kDispositionType; } break; case 'd': if (DwStrcasecmp(aFieldName, "date") == 0) { fieldBodyType = kDateTime; } break; case 'f': if (DwStrcasecmp(aFieldName, "from") == 0) { fieldBodyType = kMailboxList; } break; case 'm': if (DwStrcasecmp(aFieldName, "message-id") == 0) { fieldBodyType = kMsgId; } break; case 'r': if (DwStrcasecmp(aFieldName, "reply-to") == 0) { fieldBodyType = kAddressList; } else if (DwStrcasecmp(aFieldName, "resent-bcc") == 0) { fieldBodyType = kAddressList; } else if (DwStrcasecmp(aFieldName, "resent-cc") == 0) { fieldBodyType = kAddressList; } else if (DwStrcasecmp(aFieldName, "resent-date") == 0) { fieldBodyType = kDateTime; } else if (DwStrcasecmp(aFieldName, "resent-from") == 0) { fieldBodyType = kMailboxList; } else if (DwStrcasecmp(aFieldName, "resent-message-id") == 0) { fieldBodyType = kMsgId; } else if (DwStrcasecmp(aFieldName, "resent-reply-to") == 0) { fieldBodyType = kAddressList; } else if (DwStrcasecmp(aFieldName, "resent-sender") == 0) { fieldBodyType = kMailbox; } else if (DwStrcasecmp(aFieldName, "return-path") == 0) { fieldBodyType = kMailbox; } break; case 's': if (DwStrcasecmp(aFieldName, "sender") == 0) { fieldBodyType = kMailbox; } break; case 't': if (DwStrcasecmp(aFieldName, "to") == 0) { fieldBodyType = kAddressList; } break; } DwFieldBody* fieldBody; switch (fieldBodyType) { case kAddressList: fieldBody = DwAddressList::NewAddressList(aFieldBody, aParent); break; case kDispositionType: fieldBody = DwDispositionType::NewDispositionType(aFieldBody, aParent); break; case kMediaType: fieldBody = DwMediaType::NewMediaType(aFieldBody, aParent); break; case kMechanism: fieldBody = DwMechanism::NewMechanism(aFieldBody, aParent); break; case kDateTime: fieldBody = DwDateTime::NewDateTime(aFieldBody, aParent); break; case kMailbox: fieldBody = DwMailbox::NewMailbox(aFieldBody, aParent); break; case kMailboxList: fieldBody = DwMailboxList::NewMailboxList(aFieldBody, aParent); break; case kMsgId: fieldBody = DwMsgId::NewMsgId(aFieldBody, aParent); break; case kText: default: fieldBody = DwText::NewText(aFieldBody, aParent); break; } return fieldBody; } #if defined (DW_DEBUG_VERSION) void DwField::PrintDebugInfo(std::ostream& aStrm, int aDepth) const { aStrm << "----------------- Debug info for DwField class -----------------\n"; _PrintDebugInfo(aStrm); int depth = aDepth - 1; depth = (depth >= 0) ? depth : 0; if (mFieldBody && (aDepth == 0 || depth > 0)) { mFieldBody->PrintDebugInfo(aStrm, depth); } } #else void DwField::PrintDebugInfo(std::ostream& , int ) const {} #endif // defined (DW_DEBUG_VERSION) #if defined (DW_DEBUG_VERSION) void DwField::_PrintDebugInfo(std::ostream& aStrm) const { DwMessageComponent::_PrintDebugInfo(aStrm); aStrm << "Field name: " << mFieldNameStr << '\n'; aStrm << "Field body: " << mFieldBodyStr << '\n'; aStrm << "Field body object:"; if (mFieldBody) { aStrm << mFieldBody->ObjectId() << '\n'; } else { aStrm << "(none)\n"; } aStrm << "Next field: "; if (mNext) { aStrm << mNext->ObjectId() << '\n'; } else { aStrm << "(none)\n"; } } #else void DwField::_PrintDebugInfo(std::ostream& ) const {} #endif // defined (DW_DEBUG_VERSION) void DwField::CheckInvariants() const { #if defined (DW_DEBUG_VERSION) DwMessageComponent::CheckInvariants(); mFieldNameStr.CheckInvariants(); mFieldBodyStr.CheckInvariants(); if (mFieldBody) { mFieldBody->CheckInvariants(); } if (mFieldBody) { assert((DwMessageComponent*) this == mFieldBody->Parent()); } #endif // defined (DW_DEBUG_VERSION) } mimelib1-1.1.4/mimelib/fieldbdy.cpp0000644000175000017500000000600411175345261016525 0ustar resivoresivo//============================================================================= // File: fieldbdy.cpp // Contents: Definitions for DwFieldBody // Maintainer: Doug Sauder // WWW: http://www.fwb.gulf.net/~dwsauder/mimepp.html // // Copyright (c) 1996, 1997 Douglas W. Sauder // All rights reserved. // // IN NO EVENT SHALL DOUGLAS W. SAUDER BE LIABLE TO ANY PARTY FOR DIRECT, // INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF // THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF DOUGLAS W. SAUDER // HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // DOUGLAS W. SAUDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT // NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A // PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" // BASIS, AND DOUGLAS W. SAUDER HAS NO OBLIGATION TO PROVIDE MAINTENANCE, // SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. // //============================================================================= #define DW_IMPLEMENTATION #include #include #include #include #include #include #include const char* const DwFieldBody::sClassName = "DwFieldBody"; DwFieldBody::DwFieldBody() { mLineOffset = 0; mDoFolding = DwTrue; mClassId = kCidFieldBody; mClassName = sClassName; } DwFieldBody::DwFieldBody(const DwFieldBody& aFieldBody) : DwMessageComponent(aFieldBody) { mLineOffset = aFieldBody.mLineOffset; mDoFolding = aFieldBody.mDoFolding; mClassId = kCidFieldBody; mClassName = sClassName; } DwFieldBody::DwFieldBody(const DwString& aStr, DwMessageComponent* aParent) : DwMessageComponent(aStr, aParent) { mLineOffset = 0; mDoFolding = DwTrue; mClassId = kCidFieldBody; mClassName = sClassName; } DwFieldBody::~DwFieldBody() { } const DwFieldBody& DwFieldBody::operator = (const DwFieldBody& aFieldBody) { if (this == &aFieldBody) return *this; DwMessageComponent::operator = (aFieldBody); mLineOffset = aFieldBody.mLineOffset; return *this; } #if defined (DW_DEBUG_VERSION) void DwFieldBody::PrintDebugInfo(std::ostream& aStrm, int /*aDepth*/) const { aStrm << "--------------- Debug info for DwFieldBody class ---------------\n"; _PrintDebugInfo(aStrm); } #else void DwFieldBody::PrintDebugInfo(std::ostream& , int ) const {} #endif // defined (DW_DEBUG_VERSION) #if defined (DW_DEBUG_VERSION) void DwFieldBody::_PrintDebugInfo(std::ostream& aStrm) const { DwMessageComponent::_PrintDebugInfo(aStrm); aStrm << "LineOffset: " << mLineOffset << '\n'; aStrm << "IsFolding: " << (IsFolding() ? "True" : "False") << '\n'; } #else void DwFieldBody::_PrintDebugInfo(std::ostream& ) const {} #endif // defined (DW_DEBUG_VERSION) void DwFieldBody::CheckInvariants() const { #if defined (DW_DEBUG_VERSION) DwMessageComponent::CheckInvariants(); #endif // defined (DW_DEBUG_VERSION) } mimelib1-1.1.4/mimelib/dw_mime.cpp0000644000175000017500000002751111175345261016372 0ustar resivoresivo//============================================================================= // File: dw_mime.cpp // Contents: Various functions // Maintainer: Doug Sauder // WWW: http://www.fwb.gulf.net/~dwsauder/mimepp.html // // Copyright (c) 1996, 1997 Douglas W. Sauder // All rights reserved. // // IN NO EVENT SHALL DOUGLAS W. SAUDER BE LIABLE TO ANY PARTY FOR DIRECT, // INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF // THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF DOUGLAS W. SAUDER // HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // DOUGLAS W. SAUDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT // NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A // PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" // BASIS, AND DOUGLAS W. SAUDER HAS NO OBLIGATION TO PROVIDE MAINTENANCE, // SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. // //============================================================================= #define DW_IMPLEMENTATION #include #include #include #include #include #include void DwInitialize() { } void DwFinalize() { } int DwCteStrToEnum(const DwString& aStr) { int cte = DwMime::kCteUnknown; int ch = aStr[0]; switch (ch) { case '7': if( DwStrcasecmp(aStr, "7bit") == 0 ) { cte = DwMime::kCte7bit; } break; case '8': if (DwStrcasecmp(aStr, "8bit") == 0) { cte = DwMime::kCte8bit; } break; case 'B': case 'b': if (DwStrcasecmp(aStr, "base64") == 0) { cte = DwMime::kCteBase64; } else if (DwStrcasecmp(aStr, "binary") == 0) { cte = DwMime::kCteBinary; } break; case 'Q': case 'q': if (DwStrcasecmp(aStr, "quoted-printable") == 0) { cte = DwMime::kCteQuotedPrintable; } break; } return cte; } void DwCteEnumToStr(int aEnum, DwString& aStr) { switch (aEnum) { case DwMime::kCte7bit: aStr = "7bit"; break; case DwMime::kCte8bit: aStr = "8bit"; break; case DwMime::kCteBinary: aStr = "binary"; break; case DwMime::kCteBase64: aStr = "base64"; break; case DwMime::kCteQuotedPrintable: aStr = "quoted-printable"; break; } } int DwTypeStrToEnum(const DwString& aStr) { int type = DwMime::kTypeUnknown; int ch = aStr[0]; switch (ch) { case 'A': case 'a': if (DwStrcasecmp(aStr, "application") == 0) { type = DwMime::kTypeApplication; } else if (DwStrcasecmp(aStr, "audio") == 0) { type = DwMime::kTypeAudio; } break; case 'I': case 'i': if (DwStrcasecmp(aStr, "image") == 0) { type = DwMime::kTypeImage; } break; case 'M': case 'm': if (DwStrcasecmp(aStr, "message") == 0) { type = DwMime::kTypeMessage; } else if (DwStrcasecmp(aStr, "multipart") == 0) { type = DwMime::kTypeMultipart; } break; case 'T': case 't': if (DwStrcasecmp(aStr, "text") == 0) { type = DwMime::kTypeText; } break; case 'V': case 'v': if (DwStrcasecmp(aStr, "video") == 0) { type = DwMime::kTypeVideo; } break; case 0: type = DwMime::kTypeNull; break; } return type; } void DwTypeEnumToStr(int aEnum, DwString& aStr) { switch (aEnum) { case DwMime::kTypeNull: aStr = ""; break; case DwMime::kTypeUnknown: default: aStr = "Unknown"; break; case DwMime::kTypeText: aStr = "Text"; break; case DwMime::kTypeMultipart: aStr = "Multipart"; break; case DwMime::kTypeMessage: aStr = "Message"; break; case DwMime::kTypeApplication: aStr = "Application"; break; case DwMime::kTypeImage: aStr = "Image"; break; case DwMime::kTypeAudio: aStr = "Audio"; break; case DwMime::kTypeVideo: aStr = "Video"; break; case DwMime::kTypeModel: aStr = "Model"; break; } } int DwSubtypeStrToEnum(const DwString& aStr) { if (aStr.empty()) { return DwMime::kSubtypeNull; } int type = DwMime::kSubtypeUnknown; int ch = aStr[0]; switch (ch) { case 'A': case 'a': if (DwStrcasecmp(aStr, "alternative") == 0) { type = DwMime::kSubtypeAlternative; } break; case 'B': case 'b': if (DwStrcasecmp(aStr, "basic") == 0) { type = DwMime::kSubtypeBasic; } break; case 'C': case 'c': if (DwStrcasecmp(aStr, "calendar") == 0) { type = DwMime::kSubtypeVCal; } break; case 'D': case 'd': if (DwStrcasecmp(aStr, "digest") == 0) { type = DwMime::kSubtypeDigest; } if (DwStrcasecmp(aStr, "directory") == 0) { type = DwMime::kSubtypeDirectory; } else if (DwStrcasecmp(aStr, "disposition-notification") == 0 ) { type = DwMime::kSubtypeDispositionNotification; } break; case 'E': case 'e': if (DwStrcasecmp(aStr, "enriched") == 0) { type = DwMime::kSubtypeEnriched; } else if (DwStrcasecmp(aStr, "external-body") == 0) { type = DwMime::kSubtypeExternalBody; } else if (DwStrcasecmp(aStr, "encrypted") == 0) { type = DwMime::kSubtypeEncrypted; } break; case 'G': case 'g': if (DwStrcasecmp(aStr, "gif") == 0) { type = DwMime::kSubtypeGif; } break; case 'H': case 'h': if (DwStrcasecmp(aStr, "html") == 0) { type = DwMime::kSubtypeHtml; } break; case 'J': case 'j': if (DwStrcasecmp(aStr, "jpeg") == 0) { type = DwMime::kSubtypeJpeg; } break; case 'M': case 'm': if (DwStrcasecmp(aStr, "mixed") == 0) { type = DwMime::kSubtypeMixed; } else if (DwStrcasecmp(aStr, "mpeg") == 0) { type = DwMime::kSubtypeMpeg; } else if (DwStrcasecmp(aStr, "ms-tnef") == 0) { type = DwMime::kSubtypeMsTNEF; } break; case 'O': case 'o': if (DwStrcasecmp(aStr, "octet-stream") == 0) { type = DwMime::kSubtypeOctetStream; } break; case 'P': case 'p': if (DwStrcasecmp(aStr, "plain") == 0) { type = DwMime::kSubtypePlain; } else if (DwStrcasecmp(aStr, "parallel") == 0) { type = DwMime::kSubtypeParallel; } else if (DwStrcasecmp(aStr, "partial") == 0) { type = DwMime::kSubtypePartial; } else if (DwStrcasecmp(aStr, "postscript") == 0) { type = DwMime::kSubtypePostscript; } else if (DwStrcasecmp(aStr, "pgp-signature") == 0) { type = DwMime::kSubtypePgpSignature; } else if (DwStrcasecmp(aStr, "pgp-encrypted") == 0) { type = DwMime::kSubtypePgpEncrypted; } else if (DwStrcasecmp(aStr, "pgp") == 0) { type = DwMime::kSubtypePgpClearsigned; } else if (DwStrcasecmp(aStr, "pkcs7-signature") == 0) { type = DwMime::kSubtypePkcs7Signature; } else if (DwStrcasecmp(aStr, "pkcs7-mime") == 0) { type = DwMime::kSubtypePkcs7Mime; } break; case 'R': case 'r': if (DwStrcasecmp(aStr, "richtext") == 0) { type = DwMime::kSubtypeRichtext; } else if (DwStrcasecmp(aStr, "rfc822") == 0) { type = DwMime::kSubtypeRfc822; } else if (DwStrcasecmp(aStr, "report") == 0) { type = DwMime::kSubtypeReport; } else if (DwStrcasecmp(aStr, "rtf") == 0) { type = DwMime::kSubtypeRtf; } else if (DwStrcasecmp(aStr, "related") == 0) { type = DwMime::kSubtypeRelated; } break; case 'S': case 's': if (DwStrcasecmp(aStr, "signed") == 0) { type = DwMime::kSubtypeSigned; } break; case 'V': case 'v': if (DwStrcasecmp(aStr, "vnd.de.bund.bsi.chiasmus-text") == 0) { type = DwMime::kSubtypeChiasmusText; } break; case 'X': case 'x': if (DwStrcasecmp(aStr, "x-vcard") == 0) { type = DwMime::kSubtypeXVCard; } else if (DwStrcasecmp(aStr, "x-pkcs7-signature") == 0) { type = DwMime::kSubtypePkcs7Signature; } else if (DwStrcasecmp(aStr, "x-pkcs7-mime") == 0) { type = DwMime::kSubtypePkcs7Mime; } if (DwStrcasecmp(aStr, "x-diff") == 0) { type = DwMime::kSubtypeXDiff; } break; } return type; } void DwSubtypeEnumToStr(int aEnum, DwString& aStr) { switch (aEnum) { case DwMime::kSubtypeNull: aStr = ""; break; case DwMime::kSubtypeUnknown: default: aStr = "Unknown"; break; case DwMime::kSubtypePlain: aStr = "Plain"; break; case DwMime::kSubtypeRichtext: aStr = "Richtext"; break; case DwMime::kSubtypeEnriched: aStr = "Enriched"; break; case DwMime::kSubtypeHtml: aStr = "HTML"; break; case DwMime::kSubtypeVCal: aStr = "Calendar"; break; case DwMime::kSubtypeXVCard: aStr = "X-VCard"; break; case DwMime::kSubtypeDirectory: aStr = "Directory"; break; case DwMime::kSubtypeXDiff: aStr = "X-Diff"; break; case DwMime::kSubtypeRtf: aStr = "RTF"; break; case DwMime::kSubtypeMixed: aStr = "Mixed"; break; case DwMime::kSubtypeSigned: aStr = "Signed"; break; case DwMime::kSubtypeEncrypted: aStr = "Encrypted"; break; case DwMime::kSubtypeAlternative: aStr = "Alternative"; break; case DwMime::kSubtypeDigest: aStr = "Digest"; break; case DwMime::kSubtypeParallel: aStr = "Parallel"; break; case DwMime::kSubtypeReport: aStr = "report"; break; case DwMime::kSubtypeRelated: aStr = "Related"; break; case DwMime::kSubtypeRfc822: aStr = "Rfc822"; break; case DwMime::kSubtypeDispositionNotification: aStr = "disposition-notification"; break; case DwMime::kSubtypePartial: aStr = "Partial"; break; case DwMime::kSubtypeExternalBody: aStr = "External-body"; break; case DwMime::kSubtypePostscript: aStr = "Postscript"; break; case DwMime::kSubtypeOctetStream: aStr = "Octet-stream"; break; case DwMime::kSubtypePgpSignature: aStr = "pgp-signature"; break; case DwMime::kSubtypePgpEncrypted: aStr = "pgp-encrypted"; break; case DwMime::kSubtypePgpClearsigned: aStr = "pgp"; break; case DwMime::kSubtypePkcs7Signature: aStr = "pkcs7-signature"; break; case DwMime::kSubtypePkcs7Mime: aStr = "pkcs7-mime"; break; case DwMime::kSubtypeMsTNEF: aStr = "ms-tnef"; break; case DwMime::kSubtypeChiasmusText: aStr = "vnd.de.bund.bsi.chiasmus-text"; break; case DwMime::kSubtypeJpeg: aStr = "jpeg"; break; case DwMime::kSubtypeGif: aStr = "gif"; break; case DwMime::kSubtypeBasic: aStr = "basic"; break; case DwMime::kSubtypeMpeg: aStr = "mpeg"; break; } } mimelib1-1.1.4/mimelib/message.cpp0000644000175000017500000000573311175345261016377 0ustar resivoresivo//============================================================================= // File: message.cpp // Contents: Definitions for DwMessage // Maintainer: Doug Sauder // WWW: http://www.fwb.gulf.net/~dwsauder/mimepp.html // // Copyright (c) 1996, 1997 Douglas W. Sauder // All rights reserved. // // IN NO EVENT SHALL DOUGLAS W. SAUDER BE LIABLE TO ANY PARTY FOR DIRECT, // INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF // THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF DOUGLAS W. SAUDER // HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // DOUGLAS W. SAUDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT // NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A // PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" // BASIS, AND DOUGLAS W. SAUDER HAS NO OBLIGATION TO PROVIDE MAINTENANCE, // SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. // //============================================================================= #define DW_IMPLEMENTATION #include #include #include #include #include #include const char* const DwMessage::sClassName = "DwMessage"; DwMessage* (*DwMessage::sNewMessage)(const DwString&, DwMessageComponent*) = 0; DwMessage* DwMessage::NewMessage(const DwString& aStr, DwMessageComponent* aParent) { if (sNewMessage) { return sNewMessage(aStr, aParent); } else { return new DwMessage(aStr, aParent); } } DwMessage::DwMessage() { mClassId = kCidMessage; mClassName = sClassName; } DwMessage::DwMessage(const DwMessage& aMessage) : DwEntity(aMessage) { mClassId = kCidMessage; mClassName = sClassName; } DwMessage::DwMessage(const DwString& aStr, DwMessageComponent* aParent) : DwEntity(aStr, aParent) { mClassId = kCidMessage; mClassName = sClassName; } DwMessage::~DwMessage() { } DwMessageComponent* DwMessage::Clone() const { return new DwMessage(*this); } const DwMessage& DwMessage::operator = (const DwMessage& aMessage) { if (this == &aMessage) return *this; DwEntity::operator = (aMessage); return *this; } #if defined(DW_DEBUG_VERSION) void DwMessage::PrintDebugInfo(std::ostream& aStrm, int aDepth) const { aStrm << "------------ Debug info for DwMessage class ------------\n"; _PrintDebugInfo(aStrm); int depth = aDepth - 1; depth = (depth >= 0) ? depth : 0; if (aDepth == 0 || depth > 0) { mHeaders->PrintDebugInfo(aStrm, depth); mBody->PrintDebugInfo(aStrm, depth); } } #else void DwMessage::PrintDebugInfo(std::ostream& , int ) const {} #endif // defined(DW_DEBUG_VERSION) #if defined(DW_DEBUG_VERSION) void DwMessage::_PrintDebugInfo(std::ostream& aStrm) const { DwEntity::_PrintDebugInfo(aStrm); } #else void DwMessage::_PrintDebugInfo(std::ostream& ) const {} #endif // defined(DW_DEBUG_VERSION) mimelib1-1.1.4/mimelib/multipar.h0000644000175000017500000001051211175345261016244 0ustar resivoresivo//============================================================================= // File: multipar.h // Contents: Declarations for MultiparBodyPart and MultipartMessage // Maintainer: Doug Sauder // WWW: http://www.fwb.gulf.net/~dwsauder/mimepp.html // // Copyright (c) 1996, 1997 Douglas W. Sauder // All rights reserved. // // IN NO EVENT SHALL DOUGLAS W. SAUDER BE LIABLE TO ANY PARTY FOR DIRECT, // INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF // THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF DOUGLAS W. SAUDER // HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // DOUGLAS W. SAUDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT // NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A // PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" // BASIS, AND DOUGLAS W. SAUDER HAS NO OBLIGATION TO PROVIDE MAINTENANCE, // SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. // //============================================================================= #ifndef MULTIPAR_H #define MULTIPAR_H #include "basicmsg.h" class MultipartBodyPart { public: MultipartBodyPart(); virtual ~MultipartBodyPart(); // Get or set the 'Content-Type' header field // + The member functions that involve enumerated types (ints) // will work only for well-known types or subtypes. The enum // values are defined in . // Type const DwString& TypeStr() const; int Type() const; void SetTypeStr(const DwString& aStr); void SetType(int aType); // Subtype const DwString& SubtypeStr() const; int Subtype() const; void SetSubtypeStr(const DwString& aStr); void SetSubtype(int aSubtype); // Get or set the 'Content-Transfer-Encoding' header field // + The member functions that involve enumerated types (ints) // will work only for well-known encodings. The enum values // are defined in . const DwString& ContentTransferEncodingStr() const; int ContentTransferEncoding() const; void SetContentTransferEncodingStr(const DwString& aStr); void SetContentTransferEncoding(int aCte); // Cte is short for ContentTransferEncoding. // These functions are an alternative to the ones with longer names. const DwString& CteStr() const; int Cte() const; void SetCteStr(const DwString& aStr); void SetCte(int aCte); // Get or set the 'Content-Description' header field const DwString& ContentDescription() const; void SetContentDescription(const DwString& aStr); // Get or set the 'Content-Disposition' header field const DwString& ContentDisposition() const; void SetContentDisposition(const DwString& aStr); // Get or set the body of this body part const DwString& Body() const; void SetBody(const DwString& aStr); protected: DwString mType; DwString mSubtype; DwString mCte; DwString mContentDescription; DwString mContentDisposition; DwString mBody; }; class MultipartMessage : public BasicMessage { public: // Use this constructor to create a new multipart message MultipartMessage(); // Use this constructor to create a wrapper for a DwMessage that has // been parsed and has been verified as a multipart MultipartMessage(DwMessage* aMsg); virtual ~MultipartMessage(); // This virtual function is overridden from BasicMessage. In // MultipartMessage, we add the Content-Type header field with // type Multipart and subtype Mixed virtual void SetAutomaticFields(); // Return the number of body parts contained int NumberOfParts() const; // Get the body part at position in aIdx. Indexing starts at 0. // If there is no body part at that index, aPart will have its // attributes set to empty values. void BodyPart(int aIdx, MultipartBodyPart& aPart); // Set the body part at position in aIdx. Indexing starts at 0. // If you have aIdx = 10 and there are only 2 body parts, 7 empty // body parts will be created to fill slots 2 through 8. If you // just want to add a body part at the end, use AddBodyPart(). void SetBodyPart(int aIdx, const MultipartBodyPart& aPart); // Append a body part to the message. void AddBodyPart(const MultipartBodyPart& aPart); }; #endif mimelib1-1.1.4/mimelib/msgcmp.cpp0000644000175000017500000001430711175345261016236 0ustar resivoresivo//============================================================================= // File: msgcmp.cpp // Contents: Definitions for DwMessageComponent // Maintainer: Doug Sauder // WWW: http://www.fwb.gulf.net/~dwsauder/mimepp.html // // Copyright (c) 1996, 1997 Douglas W. Sauder // All rights reserved. // // IN NO EVENT SHALL DOUGLAS W. SAUDER BE LIABLE TO ANY PARTY FOR DIRECT, // INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF // THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF DOUGLAS W. SAUDER // HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // DOUGLAS W. SAUDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT // NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A // PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" // BASIS, AND DOUGLAS W. SAUDER HAS NO OBLIGATION TO PROVIDE MAINTENANCE, // SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. // //============================================================================= #define DW_IMPLEMENTATION #include #include #include #include #define kMagicNumber ((DwUint32) 0x22222222L) const char* const DwMessageComponent::sClassName = "DwMessageComponent"; DwMessageComponent::DwMessageComponent() { mMagicNumber = (DwUint32) kMagicNumber; mIsModified = 0; mParent = 0; mClassId = kCidMessageComponent; mClassName = sClassName; mId = DwString(); } DwMessageComponent::DwMessageComponent(const DwMessageComponent& aCmp) : mString(aCmp.mString) { mMagicNumber = (DwUint32) kMagicNumber; mIsModified = aCmp.mIsModified; mParent = 0; mClassId = kCidMessageComponent; mClassName = sClassName; mId = aCmp.mId; } DwMessageComponent::DwMessageComponent(const DwString& aStr, DwMessageComponent* aParent) : mString(aStr) { mMagicNumber = (DwUint32) kMagicNumber; mIsModified = 0; mParent = aParent; mClassId = kCidMessageComponent; mClassName = sClassName; mId = DwString(); } DwMessageComponent::~DwMessageComponent() { #if defined (DW_DEBUG_VERSION) || defined (DW_DEVELOPMENT_VERSION) if (mMagicNumber != (DwUint32) kMagicNumber) { std::cerr << "Bad value for 'this' in destructor" << std::endl; std::cerr << "(Possibly 'delete' was called twice for same object)" << std::endl; abort(); } mMagicNumber = 0; #endif // defined (DW_DEBUG_VERSION) || defined (DW_DEVELOPMENT_VERSION) } const DwMessageComponent& DwMessageComponent::operator = (const DwMessageComponent& aCmp) { if (this == &aCmp) return *this; mString = aCmp.mString; mIsModified = aCmp.mIsModified; mId = aCmp.mId; return *this; } void DwMessageComponent::FromString(const DwString& aStr) { mString = aStr; mIsModified = DwFalse; if (mParent != 0) { mParent->SetModified(); } } void DwMessageComponent::FromString(const char* aCstr) { assert(aCstr != 0); mString = aCstr; if (mParent != 0) { mParent->SetModified(); } } const DwString& DwMessageComponent::AsString() { return mString; } DwMessageComponent* DwMessageComponent::Parent() { return mParent; } void DwMessageComponent::SetParent(DwMessageComponent* aParent) { mParent = aParent; } DwBool DwMessageComponent::IsModified() const { return mIsModified; } void DwMessageComponent::SetModified() { mIsModified = 1; if (mParent != 0) { mParent->SetModified(); } } int DwMessageComponent::ClassId() const { return mClassId; } const char* DwMessageComponent::ClassName() const { return mClassName; } int DwMessageComponent::ObjectId() const { return (int) (long) this; } #if defined (DW_DEBUG_VERSION) void DwMessageComponent::PrintDebugInfo(std::ostream& aStrm, int /*aDepth*/) const { _PrintDebugInfo(aStrm); } #else void DwMessageComponent::PrintDebugInfo(std::ostream& , int ) const {} #endif // defined (DW_DEBUG_VERSION) #if defined (DW_DEBUG_VERSION) void DwMessageComponent::_PrintDebugInfo(std::ostream& aStrm) const { aStrm << "ObjectId: " << ObjectId() << '\n'; aStrm << "ClassId: "; switch (ClassId()) { case kCidError: aStrm << "kCidError"; break; case kCidUnknown: aStrm << "kCidUnknown"; break; case kCidAddress: aStrm << "kCidAddress"; break; case kCidAddressList: aStrm << "kCidAddressList"; break; case kCidBody: aStrm << "kCidBody"; break; case kCidBodyPart: aStrm << "kCidBodyPart"; break; case kCidDispositionType: aStrm << "kCidDispositionType"; break; case kCidMechanism: aStrm << "kCidMechanism"; break; case kCidMediaType: aStrm << "kCidMediaType"; break; case kCidParameter: aStrm << "kCidParameter"; break; case kCidDateTime: aStrm << "kCidDateTime"; break; case kCidEntity: aStrm << "kCidEntity"; break; case kCidField: aStrm << "kCidField"; break; case kCidFieldBody: aStrm << "kCidFieldBody"; break; case kCidGroup: aStrm << "kCidGroup"; break; case kCidHeaders: aStrm << "kCidHeaders"; break; case kCidMailbox: aStrm << "kCidMailbox"; break; case kCidMailboxList: aStrm << "kCidMailboxList"; break; case kCidMessage: aStrm << "kCidMessage"; break; case kCidMessageComponent: aStrm << "kCidMessageComponent"; break; case kCidMsgId: aStrm << "kCidMsgId"; break; case kCidText: aStrm << "kCidText"; break; } aStrm << '\n'; aStrm << "ClassName: " << ClassName() << '\n'; aStrm << "String: " << mString << '\n'; aStrm << "IsModified: " << (IsModified() ? "True" : "False") << '\n'; aStrm << "Parent ObjectId: "; if (mParent) { aStrm << mParent->ObjectId() << '\n'; } else { aStrm << "(none)\n"; } } #else void DwMessageComponent::_PrintDebugInfo(std::ostream& ) const {} #endif // defined (DW_DEBUG_VERSION) void DwMessageComponent::CheckInvariants() const { #if defined (DW_DEBUG_VERSION) assert(mMagicNumber == kMagicNumber); assert(mClassName != 0); mString.CheckInvariants(); #endif // defined (DW_DEBUG_VERSION) } mimelib1-1.1.4/mimelib/disptype.cpp0000644000175000017500000002646611175345261016622 0ustar resivoresivo//============================================================================= // File: disptype.cpp // Contents: Definitions for DwDispositionType // Maintainer: Doug Sauder // WWW: http://www.fwb.gulf.net/~dwsauder/mimepp.html // // Copyright (c) 1996, 1997 Douglas W. Sauder // All rights reserved. // // IN NO EVENT SHALL DOUGLAS W. SAUDER BE LIABLE TO ANY PARTY FOR DIRECT, // INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF // THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF DOUGLAS W. SAUDER // HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // DOUGLAS W. SAUDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT // NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A // PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" // BASIS, AND DOUGLAS W. SAUDER HAS NO OBLIGATION TO PROVIDE MAINTENANCE, // SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. // //============================================================================= #define DW_IMPLEMENTATION #include #include #include #include #include #include #include const char* const DwDispositionType::sClassName = "DwDispositionType"; DwDispositionType* (*DwDispositionType::sNewDispositionType)( const DwString&, DwMessageComponent*) = 0; DwDispositionType* DwDispositionType::NewDispositionType( const DwString& aStr, DwMessageComponent* aParent) { if (sNewDispositionType) { return sNewDispositionType(aStr, aParent); } else { return new DwDispositionType(aStr, aParent); } } DwDispositionType::DwDispositionType() { mDispositionType = DwMime::kDispTypeNull; mFirstParameter = 0; mClassId = kCidDispositionType; mClassName = sClassName; } DwDispositionType::DwDispositionType(const DwDispositionType& aDispType) : DwFieldBody(aDispType), mDispositionTypeStr(aDispType.mDispositionTypeStr), mFilenameStr(aDispType.mFilenameStr) { mFirstParameter = 0; mDispositionType = aDispType.mDispositionType; if (aDispType.mFirstParameter) { CopyParameterList(aDispType.mFirstParameter); } mClassId = kCidDispositionType; mClassName = sClassName; } DwDispositionType::DwDispositionType(const DwString& aStr, DwMessageComponent* aParent) : DwFieldBody(aStr, aParent) { mDispositionType = DwMime::kDispTypeNull; mFirstParameter = 0; mClassId = kCidDispositionType; mClassName = sClassName; } DwDispositionType::~DwDispositionType() { if (mFirstParameter) { DeleteParameterList(); } } const DwDispositionType& DwDispositionType::operator = ( const DwDispositionType& aDispType) { if (this == &aDispType) return *this; mDispositionType = aDispType.mDispositionType; mDispositionTypeStr = aDispType.mDispositionTypeStr; mFilenameStr = aDispType.mFilenameStr; if (mFirstParameter) { DeleteParameterList(); } if (aDispType.mFirstParameter) { CopyParameterList(aDispType.mFirstParameter); } if (mParent) { mParent->SetModified(); } return *this; } int DwDispositionType::DispositionType() const { return mDispositionType; } void DwDispositionType::SetDispositionType(int aType) { mDispositionType = aType; EnumToStr(); SetModified(); } const DwString& DwDispositionType::DispositionTypeStr() const { return mDispositionTypeStr; } void DwDispositionType::SetDispositionTypeStr(const DwString& aStr) { mDispositionTypeStr = aStr; StrToEnum(); SetModified(); } const DwString& DwDispositionType::Filename() const { DwParameter* param = mFirstParameter; while (param) { if (DwStrcasecmp(param->Attribute(), "filename") == 0) { // Filename parameter found. Return its value. // Implementation note: this member function is const, which // forbids us from assigning to mFilenameStr. The following // trick gets around this. (ANSI implementations could use the // "mutable" declaration). DwDispositionType* _this = (DwDispositionType*) this; _this->mFilenameStr = param->Value(); break; } param = param->Next(); } return mFilenameStr; } void DwDispositionType::SetFilename(const DwString& aStr) { mFilenameStr = aStr; // Search for filename parameter in parameter list. If found, set its // value. DwParameter* param = mFirstParameter; while (param) { if (DwStrcasecmp(param->Attribute(), "filename") == 0) { param->SetValue(mFilenameStr); return; } param = param->Next(); } // Boundary parameter not found. Add it. param = DwParameter::NewParameter("", 0); param->SetAttribute("Filename"); param->SetValue(aStr); AddParameter(param); } DwParameter* DwDispositionType::FirstParameter() const { return mFirstParameter; } void DwDispositionType::AddParameter(DwParameter* aParam) { _AddParameter(aParam); SetModified(); } void DwDispositionType::_AddParameter(DwParameter* aParam) { if (!mFirstParameter) { mFirstParameter = aParam; } else { DwParameter* cur = mFirstParameter; if( cur ) { DwParameter* next = cur->Next(); while (next) { cur = next; next = cur->Next(); } cur->SetNext(aParam); } } aParam->SetParent(this); } void DwDispositionType::Parse() { mIsModified = 0; mDispositionType = DwMime::kDispTypeNull; mDispositionTypeStr = ""; if (mFirstParameter) { DeleteParameterList(); } if (mString.length() == 0) return; DwRfc1521Tokenizer tokenizer(mString); int found = 0; while (!found && tokenizer.Type() != eTkNull) { if (tokenizer.Type() == eTkToken) { mDispositionTypeStr = tokenizer.Token(); found = 1; } ++tokenizer; } // Get parameters DwTokenString tokenStr(mString); while (1) { // Get ';' found = 0; while (!found && tokenizer.Type() != eTkNull) { if (tokenizer.Type() == eTkTspecial && tokenizer.Token()[0] == ';') { found = 1; } ++tokenizer; } if (tokenizer.Type() == eTkNull) { // No more parameters break; } tokenStr.SetFirst(tokenizer); // Get attribute DwString attrib; int attribFound = 0; while (!attribFound && tokenizer.Type() != eTkNull) { if (tokenizer.Type() == eTkToken) { attrib = tokenizer.Token(); attribFound = 1; } ++tokenizer; } // Get '=' found = 0; while (!found && tokenizer.Type() != eTkNull) { if (tokenizer.Type() == eTkTspecial && tokenizer.Token()[0] == '=') { found = 1; } ++tokenizer; } // Get value int valueFound = 0; while (!valueFound && tokenizer.Type() != eTkNull) { if (tokenizer.Type() == eTkToken || tokenizer.Type() == eTkQuotedString) { valueFound = 1; } ++tokenizer; } if (attribFound && valueFound) { tokenStr.ExtendTo(tokenizer); DwParameter* param = DwParameter::NewParameter(tokenStr.Tokens(), this); param->Parse(); _AddParameter(param); } } StrToEnum(); } void DwDispositionType::Assemble() { if (!mIsModified) return; mString = ""; if (mDispositionTypeStr.length() == 0) return; mString += mDispositionTypeStr; DwParameter* param = FirstParameter(); while (param) { param->Assemble(); if (IsFolding()) { mString += ";" DW_EOL " "; } else { mString += "; "; } mString += param->AsString(); param = param->Next(); } mIsModified = 0; } DwMessageComponent* DwDispositionType::Clone() const { return new DwDispositionType(*this); } void DwDispositionType::EnumToStr() { switch (mDispositionType) { case DwMime::kDispTypeInline: mDispositionTypeStr = "inline"; break; case DwMime::kDispTypeAttachment: mDispositionTypeStr = "attachment"; break; } } void DwDispositionType::StrToEnum() { switch (mDispositionTypeStr[0]) { case 'i': if (DwStrcasecmp(mDispositionTypeStr, "inline") == 0) { mDispositionType = DwMime::kDispTypeInline; } else { mDispositionType = DwMime::kDispTypeUnknown; } break; case 'a': if (DwStrcasecmp(mDispositionTypeStr, "attachment") == 0) { mDispositionType = DwMime::kDispTypeAttachment; } else { mDispositionType = DwMime::kDispTypeUnknown; } break; } } void DwDispositionType::DeleteParameterList() { DwParameter* param = mFirstParameter; while (param) { DwParameter* nextParam = param->Next(); delete param; param = nextParam; } mFirstParameter = 0; SetModified(); } void DwDispositionType::CopyParameterList(DwParameter* aFirst) { DwParameter* param = aFirst; while (param) { DwParameter* newParam = (DwParameter*) param->Clone(); AddParameter(newParam); param = param->Next(); } } #if defined(DW_DEBUG_VERSION) void DwDispositionType::PrintDebugInfo(std::ostream& aStrm, int aDepth) const { aStrm << "------------ Debug info for DwDispositionType class ------------\n"; _PrintDebugInfo(aStrm); int depth = aDepth - 1; depth = (depth >= 0) ? depth : 0; if (aDepth == 0 || depth > 0) { DwParameter* param = mFirstParameter; while (param) { param->PrintDebugInfo(aStrm, depth); param = param->Next(); } } } #else void DwDispositionType::PrintDebugInfo(std::ostream&, int) const {} #endif // defined(DW_DEBUG_VERSION) #if defined(DW_DEBUG_VERSION) void DwDispositionType::_PrintDebugInfo(std::ostream& aStrm) const { DwFieldBody::_PrintDebugInfo(aStrm); aStrm << "Disposition Type: " << mDispositionTypeStr << " (" << mDispositionType << ")\n"; aStrm << "Filename: " << mFilenameStr << "\n"; aStrm << "Parameters: "; DwParameter* param = mFirstParameter; if (param) { int count = 0; while (param) { if (count) aStrm << ' '; aStrm << param->ObjectId(); param = param->Next(); ++count; } aStrm << '\n'; } else { aStrm << "(none)\n"; } } #else void DwDispositionType::_PrintDebugInfo(std::ostream& ) const {} #endif // defined(DW_DEBUG_VERSION) void DwDispositionType::CheckInvariants() const { #if defined(DW_DEBUG_VERSION) mDispositionTypeStr.CheckInvariants(); mFilenameStr.CheckInvariants(); DwParameter* param = mFirstParameter; while (param) { param->CheckInvariants(); assert((DwMessageComponent*) this == param->Parent()); param = param->Next(); } #endif // defined(DW_DEBUG_VERSION) } mimelib1-1.1.4/mimelib/binhex.cpp0000644000175000017500000005412711175345261016231 0ustar resivoresivo// binhex.cpp #define DW_IMPLEMENTATION #include #include const char * const kPreamble = "(This file must be converted with BinHex 4.0)"; const char kBinhexChars[] = "!\"#$%&'()*+,-012345689@ABCDEFGHIJKLMNPQRSTUVXYZ[`abcdefhijklmpqr"; // 1 2 3 4 5 6 // 0 123456789012345678901234567890123456789012345678901234567890123 #define DONE 0x7F #define SKIP 0x7E #define FAIL 0x7D const char kBinhexTable[] = { // 0x00 SKIP, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, SKIP, SKIP, FAIL, FAIL, SKIP, FAIL, FAIL, // 0x10 FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, // 0x20 SKIP, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, FAIL, FAIL, // 0x30 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, FAIL, 0x14, 0x15, DONE, FAIL, FAIL, FAIL, FAIL, FAIL, // 0x40 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, FAIL, // 0x50 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, FAIL, 0x2C, 0x2D, 0x2E, 0x2F, FAIL, FAIL, FAIL, FAIL, // 0x60 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, FAIL, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, FAIL, FAIL, // 0x70 0x3D, 0x3E, 0x3F, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, // 0x80 FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, // 0x90 FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, // 0xA0 FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, // 0xB0 FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, // 0xC0 FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, // 0xD0 FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, // 0xE0 FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, // 0xF0 FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, }; static DwUint16 kCrcTable[] = { 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7, 0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef, 0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6, 0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de, 0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485, 0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d, 0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4, 0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc, 0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823, 0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b, 0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12, 0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a, 0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41, 0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49, 0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70, 0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78, 0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f, 0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067, 0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e, 0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256, 0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d, 0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405, 0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c, 0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634, 0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab, 0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3, 0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a, 0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92, 0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9, 0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1, 0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8, 0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0 }; inline DwUint16 UPDATE_CRC(DwUint16 crc, int ch) { int idx = ((crc >> 8) ^ ch) & 0xff; return (DwUint16) ((crc << 8) ^ kCrcTable[idx]); } struct DwBinhexEncodeCtx { DwBinhexEncodeCtx(); void PutChar(int aChar); void EncodeChar(int aChar); void Finalize(); DwString mBuffer; int mRunLen; int mLastChar; char mScratch[8]; // for 8-bit to ASCII conversion int mScratchPos; // number of chars in mScratch int mLineLength; }; DwBinhexEncodeCtx::DwBinhexEncodeCtx() { mRunLen = 1; mLastChar = -1; mScratchPos = 0; mLineLength = 0; } inline void DwBinhexEncodeCtx::PutChar(int aChar) { if (mLineLength == 64) { mBuffer.append(DW_EOL); mLineLength = 0; } mBuffer.append((size_t) 1, (char) aChar); ++mLineLength; } void DwBinhexEncodeCtx::EncodeChar(int aChar) { // If we're in a run... if (aChar == mLastChar && mRunLen < 255) { ++mRunLen; return; } // If we are not in a run, and have not just finished a run... if (mRunLen == 1) { // Output the current character, but watch for 0x90, which must be // output as the two character sequence 0x90 0x00 if (aChar != 0x90) { mScratch[mScratchPos++] = (DwUint8) aChar; } else { mScratch[mScratchPos++] = (DwUint8) 0x90; mScratch[mScratchPos++] = (DwUint8) 0x00; } } // If we just finished a run of length 2 ... else if (mRunLen == 2) { // Output the last character, but watch for 0x90, which must be // output as the two character sequence 0x90 0x00 if (mLastChar != 0x90) { mScratch[mScratchPos++] = (DwUint8) mLastChar; } else { mScratch[mScratchPos++] = (DwUint8) 0x90; mScratch[mScratchPos++] = (DwUint8) 0x00; } // Output the current character, but watch for 0x90, which must be // output as the two character sequence 0x90 0x00 if (aChar != 0x90) { mScratch[mScratchPos++] = (DwUint8) aChar; } else { mScratch[mScratchPos++] = (DwUint8) 0x90; mScratch[mScratchPos++] = (DwUint8) 0x00; } } // If we just finished a run of length greater than 2 ... else /* if (mRunLen > 2) */ { // Output the run length code mScratch[mScratchPos++] = (DwUint8) 0x90; mScratch[mScratchPos++] = (DwUint8) mRunLen; // Output the current character, but watch for 0x90, which must be // output as the two character sequence 0x90 0x00 if (aChar != 0x90) { mScratch[mScratchPos++] = (DwUint8) aChar; } else { mScratch[mScratchPos++] = (DwUint8) 0x90; mScratch[mScratchPos++] = (DwUint8) 0x00; } } mRunLen = 1; mLastChar = aChar; while (mScratchPos >= 3) { int n = mScratch[0] >> 2; PutChar(kBinhexChars[n&0x3f]); n = (mScratch[0] << 4) | ((mScratch[1] >> 4) & 0x0f); PutChar(kBinhexChars[n&0x3f]); n = (mScratch[1] << 2) | ((mScratch[2] >> 6) & 0x03); PutChar(kBinhexChars[n&0x3f]); n = mScratch[2]; PutChar(kBinhexChars[n&0x3f]); for (int i=0; i < mScratchPos-3; ++i) { mScratch[i] = mScratch[i+3]; } mScratchPos -= 3; } } void DwBinhexEncodeCtx::Finalize() { if (mRunLen == 1) { } else if (mRunLen == 2) { // Output the last character, but watch for 0x90, which must be // output as the two character sequence 0x90 0x00 if (mLastChar != 0x90) { mScratch[mScratchPos++] = (DwUint8) mLastChar; } else { mScratch[mScratchPos++] = (DwUint8) 0x90; mScratch[mScratchPos++] = (DwUint8) 0x00; } } else /* if aCtx->mRunLen > 2) */ { // Output the run length code mScratch[mScratchPos++] = (DwUint8) 0x90; mScratch[mScratchPos++] = (DwUint8) mRunLen; } int n; while (mScratchPos >= 3) { n = mScratch[0] >> 2; PutChar(kBinhexChars[n&0x3f]); n = (mScratch[0] << 4) | ((mScratch[1] >> 4) & 0x0f); PutChar(kBinhexChars[n&0x3f]); n = (mScratch[1] << 2) | ((mScratch[2] >> 6) & 0x03); PutChar(kBinhexChars[n&0x3f]); n = mScratch[2]; PutChar(kBinhexChars[n&0x3f]); for (int i=0; i < mScratchPos-3; ++i) { mScratch[i] = mScratch[i+3]; } mScratchPos -= 3; } switch (mScratchPos) { case 0: break; case 1: n = mScratch[0] >> 2; PutChar(kBinhexChars[n&0x3f]); n = (mScratch[0] << 4); PutChar(kBinhexChars[n&0x3f]); case 2: n = mScratch[0] >> 2; PutChar(kBinhexChars[n&0x3f]); n = (mScratch[0] << 4) | ((mScratch[1] >> 4) & 0x0f); PutChar(kBinhexChars[n&0x3f]); n = (mScratch[1] << 2); PutChar(kBinhexChars[n&0x3f]); } } #if 0 //============================================================================ struct DwBinhexDecodeCtx { DwBinhexDecodeCtx(); int GetChar(); int DecodeChar(); DwString mBinhexChars; size_t mPos; int mRunLen; int mLastChar; DwUint8 mScratch[4]; int mScratchPos; int mScratchCount; int mError; }; DwBinhexDecodeCtx::DwBinhexDecodeCtx() { mPos = 0; mRunLen = 1; mLastChar = -1; mScratch[0] = 0; mScratch[1] = 0; mScratch[2] = 0; mScratch[3] = 0; mScratchPos = 0; mScratchCount = 0; mError = 0; } int DwBinhexDecodeCtx::GetChar() { // Refill the scratch buffer, if necessary if (mScratchCount == 0) { // Get up to four ASCII chars char cc[4]; size_t k = 0; size_t len = mBinhexChars.length(); const DwString& binhexChars = mBinhexChars; while (k < (size_t) 4 && mPos < len) { int ch = binhexChars[mPos++] & 0xff; ch = kBinhexTable[ch]; switch (ch) { case DONE: goto BREAK_1; case SKIP: break; case FAIL: mError = 1; // error! return -1; default: cc[k++] = (char) ch; break; } } BREAK_1: // Convert the ASCII chars to 8-bit chars mScratch[0] = 0; mScratch[1] = 0; mScratch[2] = 0; mScratchCount = 0; mScratchPos = 0; switch (k) { case 4: mScratch[2] |= (DwUint8) (cc[3] & 0x3f); // fall through case 3: mScratch[2] |= (DwUint8) (cc[2] << 6); mScratch[1] |= (DwUint8) ((cc[2] >> 2) & 0x0f); ++mScratchCount; // fall through case 2: mScratch[1] |= (DwUint8) (cc[1] << 4); mScratch[0] |= (DwUint8) ((cc[1] >> 4) & 0x03); ++mScratchCount; // fall through case 1: mScratch[0] |= (DwUint8) (cc[0] << 2); ++mScratchCount; case 0: break; } } // Return an 8-bit char, or -1 if there are no more chars int ch; if (mScratchCount > 0) { --mScratchCount; ch = mScratch[mScratchPos++] & 0xff; } else { ch = -1; } return ch; } int DwBinhexDecodeCtx::DecodeChar() { int ch; if (mRunLen > 1) { ch = mLastChar; --mRunLen; } else /* if (mRunLen == 1) */ { ch = GetChar(); // 0x90 is the escape character if ((ch & 0xff) == 0x90) { ch = GetChar(); if (ch == -1) { // end of buffer or illegal character mError = 1; // error! } else if (ch == 0) { // 0x90 0x00 is decoded to 0x90 ch = 0x90; mRunLen = 1; } else if (ch == 1) { // Could be interpreted as a run of length 1, but in all // likelihood, it's an error. mError = 1; // error! ch = -1; mRunLen = 1; } else if (ch >= 2) { // 0x90 n indicates a run of length n mRunLen = ch - 1; ch = mLastChar; } } } mLastChar = ch; return ch; } //============================================================================ DwBinhex::DwBinhex() { Initialize(); } #endif // 0 DwBinhex::~DwBinhex() { } #if 0 void DwBinhex::Initialize() { memset(mFileName, 0, sizeof(mFileName)); memset(mFileType, 0, sizeof(mFileType)); memset(mFileCreator, 0, sizeof(mFileCreator)); mFlag1 = 0; mFlag2 = 0; mDataFork = mResourceFork = mBinhexChars = ""; } void DwBinhex::SetFileName(const char* aName) { strncpy(mFileName, aName, 64); mFileName[63] = 0; } const char* DwBinhex::FileName() const { return mFileName; } void DwBinhex::SetFileType(const char* aType) { memcpy(mFileType, aType, 4); } void DwBinhex::FileType(char* aBuf) const { memcpy(aBuf, mFileType, 4); } void DwBinhex::SetFileCreator(const char* aCreator) { memcpy(mFileCreator, aCreator, 4); } void DwBinhex::FileCreator(char* aBuf) const { memcpy(aBuf, mFileCreator, 4); } void DwBinhex::SetFlag1(DwUint8 aFlag) { mFlag1 = aFlag; } DwUint8 DwBinhex::Flag1() const { return mFlag1; } void DwBinhex::SetFlag2(DwUint8 aFlag) { mFlag2 = aFlag; } DwUint8 DwBinhex::Flag2() const { return mFlag2; } void DwBinhex::SetDataFork(const DwString& aStr) { mDataFork = aStr; } const DwString& DwBinhex::DataFork() const { return mDataFork; } void DwBinhex::SetResourceFork(const DwString& aStr) { mResourceFork = aStr; } const DwString& DwBinhex::ResourceFork() const { return mResourceFork; } void DwBinhex::SetBinhexChars(const DwString& aStr) { mBinhexChars = aStr; } const DwString& DwBinhex::BinhexChars() const { return mBinhexChars; } void DwBinhex::Encode() { size_t bufSize = (mResourceFork.length()+2)/3*4 + (mDataFork.length()+2)/3*4 + 27 + strlen(mFileName); DwBinhexEncodeCtx ctx; ctx.mBuffer.reserve(bufSize); ctx.mBuffer.assign(kPreamble); ctx.mBuffer.append(DW_EOL); ctx.mBuffer.append(1, ':'); ++ctx.mLineLength; DwUint16 crc = 0; size_t fileNameLen = strlen(mFileName); int ch = fileNameLen; crc = UPDATE_CRC(crc, ch); ctx.EncodeChar(ch); // File name size_t j; for (j=0; j < fileNameLen; ++j) { ch = mFileName[j] & 0xff; crc = UPDATE_CRC(crc, ch); ctx.EncodeChar(ch); } // Version ch = 0; crc = UPDATE_CRC(crc, ch); ctx.EncodeChar(ch); // File type for (j=0; j < (size_t) 4; ++j) { ch = mFileType[j] & 0xff; crc = UPDATE_CRC(crc, ch); ctx.EncodeChar(ch); } // File creator for (j=0; j < (size_t) 4; ++j) { ch = mFileCreator[j] & 0xff; crc = UPDATE_CRC(crc, ch); ctx.EncodeChar(ch); } // Flags ch = mFlag1 & 0xff; crc = UPDATE_CRC(crc, ch); ctx.EncodeChar(ch); ch = mFlag2 & 0xff; crc = UPDATE_CRC(crc, ch); ctx.EncodeChar(ch); // Data fork length DwUint32 len = (DwUint32) mDataFork.length(); ch = (len >> 24) & 0xff; crc = UPDATE_CRC(crc, ch); ctx.EncodeChar(ch); ch = (len >> 16) & 0xff; crc = UPDATE_CRC(crc, ch); ctx.EncodeChar(ch); ch = (len >> 8) & 0xff; crc = UPDATE_CRC(crc, ch); ctx.EncodeChar(ch); ch = len & 0xff; crc = UPDATE_CRC(crc, ch); ctx.EncodeChar(ch); // Resource fork length len = mResourceFork.length(); ch = (len >> 24) & 0xff; crc = UPDATE_CRC(crc, ch); ctx.EncodeChar(ch); ch = (len >> 16) & 0xff; crc = UPDATE_CRC(crc, ch); ctx.EncodeChar(ch); ch = (len >> 8) & 0xff; crc = UPDATE_CRC(crc, ch); ctx.EncodeChar(ch); ch = len & 0xff; crc = UPDATE_CRC(crc, ch); ctx.EncodeChar(ch); // Header CRC ch = (crc >> 8) & 0xff; ctx.EncodeChar(ch); ch = crc & 0xff; ctx.EncodeChar(ch); //===== End of header ===== // Data fork crc = 0; size_t dataForkLen = mDataFork.length(); for (j=0; j < dataForkLen; ++j) { ch = mDataFork[j] & 0xff; crc = UPDATE_CRC(crc, ch); ctx.EncodeChar(ch); } // Data fork CRC ch = (crc >> 8) & 0xff; ctx.EncodeChar(ch); ch = crc & 0xff; ctx.EncodeChar(ch); // Resource fork crc = 0; size_t rsrcForkLen = mResourceFork.length(); for (j=0; j < rsrcForkLen; ++j) { ch = mResourceFork[j] & 0xff; crc = UPDATE_CRC(crc, ch); ctx.EncodeChar(ch); } // Resource fork CRC ch = (crc >> 8) & 0xff; ctx.EncodeChar(ch); ch = crc & 0xff; ctx.EncodeChar(ch); ctx.Finalize(); ctx.mBuffer.append(1, ':'); ctx.mBuffer.append(DW_EOL); mBinhexChars = ctx.mBuffer; } int DwBinhex::Decode() { // Initialize memset(mFileName, 0, sizeof(mFileName)); memset(mFileType, 0, sizeof(mFileType)); memset(mFileCreator, 0, sizeof(mFileCreator)); mFlag1 = 0; mFlag2 = 0; mDataFork = mResourceFork = ""; DwBinhexDecodeCtx ctx; ctx.mBinhexChars = mBinhexChars; // Find the preamble ctx.mPos = ctx.mBinhexChars.find("(This file must be converted " "with BinHex", 0); if (ctx.mPos == DwString::npos) { return -1; // error! } ctx.mPos += 40; // Advance to just past the colon ctx.mPos = ctx.mBinhexChars.find((char) ':', ctx.mPos); if (ctx.mPos == DwString::npos) { return -1; // error! } ++ctx.mPos; DwUint16 crc = 0; // File name length int ch = ctx.DecodeChar(); if (ch < 1 || 63 < ch) { return -1; // error! } crc = UPDATE_CRC(crc, ch); size_t fileNameLen = (size_t) ch; // File name size_t j; for (j=0; j < fileNameLen; ++j) { ch = ctx.DecodeChar(); if (ch == -1) { return -1; // error! } crc = UPDATE_CRC(crc, ch); mFileName[j] = (char) ch; } // Version ch = ctx.DecodeChar(); if (ch != 0) { return -1; // error! } crc = UPDATE_CRC(crc, ch); // File type for (j=0; j < (size_t) 4; ++j) { ch = ctx.DecodeChar(); if (ch == -1) { return -1; // error! } crc = UPDATE_CRC(crc, ch); mFileType[j] = (char) ch; } // File creator for (j=0; j < (size_t) 4; ++j) { ch = ctx.DecodeChar(); if (ch == -1) { return -1; // error! } crc = UPDATE_CRC(crc, ch); mFileCreator[j] = (char) ch; } // Flags ch = ctx.DecodeChar(); if (ch == -1) { return -1; // error! } crc = UPDATE_CRC(crc, ch); mFlag1 = (DwUint8) ch; ch = ctx.DecodeChar(); if (ch == -1) { return -1; // error! } crc = UPDATE_CRC(crc, ch); mFlag2 = (DwUint8) ch; // Data fork length ch = ctx.DecodeChar(); if (ch == -1) { return -1; // error! } crc = UPDATE_CRC(crc, ch); DwUint32 dataForkLen = ch & 0xff; ch = ctx.DecodeChar(); if (ch == -1) { return -1; // error! } crc = UPDATE_CRC(crc, ch); dataForkLen <<= 8; dataForkLen |= ch & 0xff; ch = ctx.DecodeChar(); if (ch == -1) { return -1; // error! } crc = UPDATE_CRC(crc, ch); dataForkLen <<= 8; dataForkLen |= ch & 0xff; ch = ctx.DecodeChar(); if (ch == -1) { return -1; // error! } crc = UPDATE_CRC(crc, ch); dataForkLen <<= 8; dataForkLen |= ch & 0xff; // Resource fork length ch = ctx.DecodeChar(); if (ch == -1) { return -1; // error! } crc = UPDATE_CRC(crc, ch); DwUint32 rsrcForkLen = ch & 0xff; ch = ctx.DecodeChar(); if (ch == -1) { return -1; // error! } crc = UPDATE_CRC(crc, ch); rsrcForkLen <<= 8; rsrcForkLen |= ch & 0xff; ch = ctx.DecodeChar(); if (ch == -1) { return -1; // error! } crc = UPDATE_CRC(crc, ch); rsrcForkLen <<= 8; rsrcForkLen |= ch & 0xff; ch = ctx.DecodeChar(); if (ch == -1) { return -1; // error! } crc = UPDATE_CRC(crc, ch); rsrcForkLen <<= 8; rsrcForkLen |= ch & 0xff; // Header CRC ch = ctx.DecodeChar(); if (ch == -1) { return -1; // error! } DwUint16 crc1 = (DwUint16) (ch & 0xff); ch = ctx.DecodeChar(); if (ch == -1) { return -1; // error! } crc1 <<= 8; crc1 |= (DwUint16) (ch & 0xff); if (crc1 != crc) { return -1; // error! } // Data fork crc = 0; for (j=0; j < dataForkLen; ++j) { ch = ctx.DecodeChar(); if (ch == -1) { return -1; // error! } crc = UPDATE_CRC(crc, ch); mDataFork.append((size_t) 1, (char) ch); } ch = ctx.DecodeChar(); if (ch == -1) { return -1; // error! } crc1 = (DwUint16) (ch & 0xff); ch = ctx.DecodeChar(); if (ch == -1) { return -1; // error! } crc1 <<= 8; crc1 |= (DwUint16) (ch & 0xff); if (crc1 != crc) { mDataFork = ""; return -1; // error! } // Resource fork crc = 0; for (j=0; j < rsrcForkLen; ++j) { ch = ctx.DecodeChar(); if (ch == -1) { return -1; // error! } crc = UPDATE_CRC(crc, ch); mResourceFork.append((size_t) 1, (char) ch); } ch = ctx.DecodeChar(); if (ch == -1) { return -1; // error! } crc1 = (DwUint16) (ch & 0xff); ch = ctx.DecodeChar(); if (ch == -1) { return -1; // error! } crc1 <<= 8; crc1 |= (DwUint16) (ch & 0xff); if (crc1 != crc) { mResourceFork = ""; return -1; // error! } return 0; } #endif mimelib1-1.1.4/mimelib/multipar.cpp0000644000175000017500000002141311175345261016601 0ustar resivoresivo//============================================================================= // File: multipar.cpp // Contents: Definitions for MultiparBodyPart and MultipartMessage // Maintainer: Doug Sauder // WWW: http://www.fwb.gulf.net/~dwsauder/mimepp.html // // Copyright (c) 1996, 1997 Douglas W. Sauder // All rights reserved. // // IN NO EVENT SHALL DOUGLAS W. SAUDER BE LIABLE TO ANY PARTY FOR DIRECT, // INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF // THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF DOUGLAS W. SAUDER // HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // DOUGLAS W. SAUDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT // NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A // PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" // BASIS, AND DOUGLAS W. SAUDER HAS NO OBLIGATION TO PROVIDE MAINTENANCE, // SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. // //============================================================================= #include #include #include "multipar.h" MultipartBodyPart::MultipartBodyPart() : mType("Text"), mSubtype("Plain"), mCte("7bit") { } MultipartBodyPart::~MultipartBodyPart() { } const DwString& MultipartBodyPart::TypeStr() const { return mType; } int MultipartBodyPart::Type() const { int type = DwTypeStrToEnum(mType); return type; } void MultipartBodyPart::SetTypeStr(const DwString& aStr) { mType = aStr; } void MultipartBodyPart::SetType(int aType) { DwTypeEnumToStr(aType, mType); } const DwString& MultipartBodyPart::SubtypeStr() const { return mSubtype; } int MultipartBodyPart::Subtype() const { int subtype = DwSubtypeStrToEnum(mSubtype); return subtype; } void MultipartBodyPart::SetSubtypeStr(const DwString& aStr) { mSubtype = aStr; } void MultipartBodyPart::SetSubtype(int aSubtype) { DwSubtypeEnumToStr(aSubtype, mSubtype); } const DwString& MultipartBodyPart::ContentTransferEncodingStr() const { return mCte; } int MultipartBodyPart::ContentTransferEncoding() const { int cte = DwCteStrToEnum(mCte); return cte; } void MultipartBodyPart::SetContentTransferEncodingStr(const DwString& aStr) { mCte = aStr; } void MultipartBodyPart::SetContentTransferEncoding(int aCte) { DwCteEnumToStr(aCte, mCte); } const DwString& MultipartBodyPart::CteStr() const { return mCte; } int MultipartBodyPart::Cte() const { int cte = DwCteStrToEnum(mCte); return cte; } void MultipartBodyPart::SetCteStr(const DwString& aStr) { mCte = aStr; } void MultipartBodyPart::SetCte(int aCte) { DwCteEnumToStr(aCte, mCte); } const DwString& MultipartBodyPart::ContentDescription() const { return mContentDescription; } void MultipartBodyPart::SetContentDescription(const DwString& aStr) { mContentDescription = aStr; } const DwString& MultipartBodyPart::ContentDisposition() const { return mContentDisposition; } void MultipartBodyPart::SetContentDisposition(const DwString& aStr) { mContentDisposition = aStr; } const DwString& MultipartBodyPart::Body() const { return mBody; } void MultipartBodyPart::SetBody(const DwString& aStr) { mBody = aStr; } //------------------------------------------------------------------------- MultipartMessage::MultipartMessage() { } MultipartMessage::MultipartMessage(DwMessage* aMsg) : BasicMessage(aMsg) { } MultipartMessage::~MultipartMessage() { } void MultipartMessage::SetAutomaticFields() { BasicMessage::SetAutomaticFields(); // Set the type to 'Multipart' and the subtype to 'Mixed' DwMediaType& contentType = mMessage->Headers().ContentType(); contentType.SetType(DwMime::kTypeMultipart); contentType.SetSubtype(DwMime::kSubtypeMixed); // Create a random printable string and set it as the boundary parameter contentType.CreateBoundary(0); } int MultipartMessage::NumberOfParts() const { int count = 0; DwBodyPart* part = mMessage->Body().FirstBodyPart(); while (part) { ++count; part = part->Next(); } return count; } void MultipartMessage::BodyPart(int aIdx, MultipartBodyPart& aPart) { // Get the DwBodyPart for this index DwBodyPart* part = mMessage->Body().FirstBodyPart(); for (int curIdx=0; curIdx < aIdx && part; ++curIdx) { part = part->Next(); } // If the DwBodyPart was found get the header fields and body if (part != 0) { DwHeaders& headers = part->Headers(); // Content-type if (headers.HasContentType()) { const DwString& type = headers.ContentType().TypeStr(); const DwString& subtype = headers.ContentType().SubtypeStr(); aPart.SetTypeStr(type); aPart.SetSubtypeStr(subtype); } else { // Set to defaults aPart.SetTypeStr("Text"); aPart.SetSubtypeStr("Plain"); } // Content-transfer-encoding if (headers.HasContentTransferEncoding()) { const DwString& cte = headers.ContentTransferEncoding().AsString(); aPart.SetCteStr(cte); } else { // Set to default aPart.SetCteStr("7bit"); } // Content-description if (headers.HasContentDescription()) { const DwString& desc = headers.ContentDescription().AsString(); aPart.SetContentDescription(desc); } else { aPart.SetContentDescription(""); } // Content-disposition if (headers.HasContentDisposition()) { const DwString& disp = headers.ContentDisposition().AsString(); aPart.SetContentDisposition(disp); } else { aPart.SetContentDisposition(""); } // Body const DwString& body = part->Body().AsString(); aPart.SetBody(body); } // If the body part was not found, set all MultipartBodyPart attributes // to empty values. This only happens if you don't pay attention to // the value returned from NumberOfParts(). else { aPart.SetTypeStr(""); aPart.SetSubtypeStr(""); aPart.SetCteStr(""); aPart.SetContentDescription(""); aPart.SetContentDisposition(""); aPart.SetBody(""); } } void MultipartMessage::SetBodyPart(int aIdx, const MultipartBodyPart& aPart) { DwBody& body = mMessage->Body(); int numParts = NumberOfParts(); DwBodyPart* part = 0; // If indexed part exists already, just replace its values if (0 <= aIdx && aIdx < numParts) { part = body.FirstBodyPart(); for (int curIdx=0; curIdx < aIdx; ++curIdx) { part = part->Next(); } } // Otherwise, add as many new parts as necessary. else if (numParts <= aIdx) { while (numParts <= aIdx) { part = DwBodyPart::NewBodyPart(mEmptyString, 0); body.AddBodyPart(part); ++numParts; } } else /* if (aIdx < 0) */ { // error! return; } const DwString& type = aPart.TypeStr(); const DwString& subtype = aPart.SubtypeStr(); const DwString& cte = aPart.CteStr(); const DwString& contDesc = aPart.ContentDescription(); const DwString& contDisp = aPart.ContentDisposition(); const DwString& bodyStr = aPart.Body(); DwHeaders& headers = part->Headers(); if (!type.empty() && !subtype.empty()) { headers.ContentType().SetTypeStr(type); headers.ContentType().SetSubtypeStr(subtype); } if (!cte.empty()) { headers.Cte().FromString(cte); } if (!contDesc.empty()) { headers.ContentDescription().FromString(contDesc); } if (!contDisp.empty()) { headers.ContentDisposition().FromString(contDisp); } part->Body().FromString(bodyStr); } void MultipartMessage::AddBodyPart(const MultipartBodyPart& aPart) { DwBodyPart* part = DwBodyPart::NewBodyPart(mEmptyString, 0); const DwString& type = aPart.TypeStr(); const DwString& subtype = aPart.SubtypeStr(); const DwString& cte = aPart.CteStr(); const DwString& contDesc = aPart.ContentDescription(); const DwString& contDisp = aPart.ContentDisposition(); const DwString& bodyStr = aPart.Body(); DwHeaders& headers = part->Headers(); if (!type.empty() && !subtype.empty()) { headers.ContentType().SetTypeStr(type); headers.ContentType().SetSubtypeStr(subtype); } if (!cte.empty()) { headers.Cte().FromString(cte); } if (!contDesc.empty()) { headers.ContentDescription().FromString(contDesc); } if (!contDisp.empty()) { headers.ContentDisposition().FromString(contDisp); } part->Body().FromString(bodyStr); mMessage->Body().AddBodyPart(part); } mimelib1-1.1.4/mimelib/address.cpp0000644000175000017500000000653711175345261016403 0ustar resivoresivo//============================================================================= // File: address.cpp // Contents: Definitions for DwAddress // Maintainer: Doug Sauder // WWW: http://www.fwb.gulf.net/~dwsauder/mimepp.html // // Copyright (c) 1996, 1997 Douglas W. Sauder // All rights reserved. // // IN NO EVENT SHALL DOUGLAS W. SAUDER BE LIABLE TO ANY PARTY FOR DIRECT, // INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF // THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF DOUGLAS W. SAUDER // HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // DOUGLAS W. SAUDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT // NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A // PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" // BASIS, AND DOUGLAS W. SAUDER HAS NO OBLIGATION TO PROVIDE MAINTENANCE, // SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. // //============================================================================= #define DW_IMPLEMENTATION #include #include #include #include #include #include #include #include #include const char* const DwAddress::sClassName = "DwAddress"; DwAddress::DwAddress() { mIsValid = 0; mNext = 0; mClassId = kCidAddress; mClassName = sClassName; } DwAddress::DwAddress(const DwAddress& aAddr) : DwFieldBody(aAddr) { mIsValid = aAddr.mIsValid; mNext = 0; mClassId = kCidAddress; mClassName = sClassName; } DwAddress::DwAddress(const DwString& aStr, DwMessageComponent* aParent) : DwFieldBody(aStr, aParent) { mIsValid = 0; mNext = 0; mClassId = kCidAddress; mClassName = sClassName; } DwAddress::~DwAddress() { } const DwAddress& DwAddress::operator = (const DwAddress& aAddr) { if (this == &aAddr) return *this; DwFieldBody::operator = (aAddr); mIsValid = aAddr.mIsValid; return *this; } DwBool DwAddress::IsMailbox() const { DwBool r = (mClassId == kCidMailbox) ? 1 : 0; return r; } DwBool DwAddress::IsGroup() const { DwBool r = (mClassId == kCidGroup) ? 1 : 0; return r; } DwAddress* DwAddress::Next() const { return mNext; } void DwAddress::SetNext(DwAddress* aAddress) { mNext = aAddress; } #if defined (DW_DEBUG_VERSION) void DwAddress::PrintDebugInfo(std::ostream& aStrm, int /*aDepth*/) const { aStrm << "---------------- Debug info for DwAddress class ----------------\n"; _PrintDebugInfo(aStrm); } #else void DwAddress::PrintDebugInfo(std::ostream&, int ) const {} #endif // defined (DW_DEBUG_VERSION) #if defined (DW_DEBUG_VERSION) void DwAddress::_PrintDebugInfo(std::ostream& aStrm) const { DwFieldBody::_PrintDebugInfo(aStrm); aStrm << "IsValid: "; if (mIsValid) { aStrm << "True\n"; } else { aStrm << "False\n"; } aStrm << "Next address: "; if (mNext) { aStrm << mNext->ObjectId() << '\n'; } else { aStrm << "(none)\n"; } } #else void DwAddress::_PrintDebugInfo(std::ostream& ) const {} #endif // defined (DW_DEBUG_VERSION) void DwAddress::CheckInvariants() const { #if defined (DW_DEBUG_VERSION) DwFieldBody::CheckInvariants(); #endif // defined (DW_DEBUG_VERSION) } mimelib1-1.1.4/mimelib/dwstring.cpp0000644000175000017500000013536111175345261016615 0ustar resivoresivo//============================================================================= // File: dwstring.cpp // Contents: Definitions for DwString // Maintainer: Doug Sauder // WWW: http://www.fwb.gulf.net/~dwsauder/mimepp.html // // Copyright (c) 1996, 1997 Douglas W. Sauder // All rights reserved. // // IN NO EVENT SHALL DOUGLAS W. SAUDER BE LIABLE TO ANY PARTY FOR DIRECT, // INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF // THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF DOUGLAS W. SAUDER // HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // DOUGLAS W. SAUDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT // NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A // PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" // BASIS, AND DOUGLAS W. SAUDER HAS NO OBLIGATION TO PROVIDE MAINTENANCE, // SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. // //============================================================================= #define DW_IMPLEMENTATION #include #include #include #include #include #include #include // mmap #include #include #define DW_MIN(a,b) ((a) <= (b) ? (a) : (b)) #define DW_MAX(a,b) ((a) >= (b) ? (a) : (b)) /* In some locales (such as tr_TR.UTF-8, az_AZ) using tolower() can cause unexpected results. Keywords must be compared in a locale-independent manner */ static char dw_asciitolower( const char c ) { if ( c >= 'A' && c <= 'Z' ) return c - 'A' + 'a'; else return c; } static char dw_asciitoupper( const char c ) { if ( c >= 'a' && c <= 'z' ) return c - 'a' + 'A'; else return c; } static int dw_strasciicasecmp(const char* s1, size_t len1, const char* s2, size_t len2) { assert(s1 != 0); assert(s2 != 0); size_t len = DW_MIN(len1, len2); for (size_t i=0; i < len; ++i) { int c1 = dw_asciitolower( s1[i] ); int c2 = dw_asciitolower( s2[i] ); if ( c1 < c2 ) return -1; else if ( c1 > c2 ) return 1; } if (len1 < len2) { return -1; } else if (len1 > len2) { return 1; } return 0; } #if 0 static int dw_strcasecmp(const char* s1, size_t len1, const char* s2, size_t len2) { assert(s1 != 0); assert(s2 != 0); size_t len = DW_MIN(len1, len2); for (size_t i=0; i < len; ++i) { int c1 = tolower(s1[i]); int c2 = tolower(s2[i]); if (c1 < c2) { return -1; } else if (c1 > c2) { return 1; } } if (len1 < len2) { return -1; } else if (len1 > len2) { return 1; } return 0; } #endif static int dw_strcmp(const char* s1, size_t len1, const char* s2, size_t len2) { assert(s1 != 0); assert(s2 != 0); size_t len = DW_MIN(len1, len2); for (size_t i=0; i < len; ++i) { if (s1[i] < s2[i]) { return -1; } else if (s1[i] > s2[i]) { return 1; } } if (len1 < len2) { return -1; } else if (len1 > len2) { return 1; } return 0; } // Copy inline void mem_copy(const char* src, size_t n, char* dest) { assert(src != 0); assert(dest != 0); assert(src != dest); if (n == 0 || src == dest || !src || !dest) return; memmove(dest, src, n); } #if !defined(DW_USE_ANSI_STRING) // Allocate buffer whose size is a power of 2 static char* mem_alloc(size_t* aSize) { assert(aSize != 0); // minimum size is 32 size_t size = 32; while (size < *aSize) { size <<= 1; } *aSize = 0; char* buf = new char[size]; if (buf != 0) *aSize = size; return buf; } // Free buffer inline void mem_free(char* buf) { assert(buf != 0); if (buf && buf != DwString::sEmptyBuffer) delete [] buf; } inline DwStringRep* new_rep_reference(DwStringRep* rep) { assert(rep != 0); ++rep->mRefCount; return rep; } inline void delete_rep_safely(DwStringRep* rep) { assert(rep != 0); #if defined(DW_DEBUG_VERSION) || defined(DW_DEVELOPMENT_VERSION) if (rep->mRefCount <= 0) { std::cerr << "Error: attempt to delete a DwStringRep " "with ref count <= 0" << std::endl; std::cerr << "(Possibly 'delete' was called twice for same object)" << std::endl; abort(); } #endif // defined(DW_DEBUG_VERSION) || defined(DW_DEVELOPMENT_VERSION) --rep->mRefCount; if (rep->mRefCount == 0) { delete rep; } } //-------------------------------------------------------------------------- //DwStringRep* DwStringRep::theirPool = NULL; //int DwStringRep::theirPoolCount = 0; // DwStringRep takes ownership of the buffer passed as an argument DwStringRep::DwStringRep(char* aBuf, size_t aSize) { assert(aBuf != 0); mSize = aSize; mBuffer = aBuf; mRefCount = 1; mPageMod = 0; } DwStringRep::DwStringRep(FILE* aFile, size_t aSize) { assert(aFile != 0); static int pagesize = -1; if (pagesize < 0) pagesize = getpagesize(); assert(pagesize != 0); int tell = ftell(aFile); mPageMod = tell % pagesize; mSize = aSize; mRefCount = 1; mBuffer = (char *)mmap(0, aSize + mPageMod, PROT_READ, MAP_SHARED, fileno(aFile), tell - mPageMod) + mPageMod; ++mPageMod; if (mBuffer == MAP_FAILED) { mBuffer = 0; mSize = 0; mPageMod = 0; } } DwStringRep::~DwStringRep() { #if defined (DW_DEBUG_VERSION) || defined (DW_DEVELOPMENT_VERSION) if (mBuffer == 0) { std::cerr << "DwStringRep destructor called for bad DwStringRep object" << std::endl; std::cerr << "(Possibly 'delete' was called twice for same object)" << std::endl; abort(); } #endif // defined (DW_DEBUG_VERSION) || defined (DW_DEVELOPMENT_VERSION) if (mPageMod) { --mPageMod; munmap(mBuffer - mPageMod, mSize + mPageMod); } else { mem_free(mBuffer); } //DEV_STMT(mBuffer = 0) } void DwStringRep::CheckInvariants() const { #if defined (DW_DEBUG_VERSION) assert(mBuffer != 0); assert(mSize > 0); assert(mRefCount > 0); #endif // defined (DW_DEBUG_VERSION) } // Efficient memory management. May be used at some point in the future. #if 0 void* DwStringRep::operator new(size_t sz) { void* rep; if (theirPoolCount > 0) { --theirPoolCount; rep = theirPool; theirPool = theirPool->mNext; } else { rep = new char[sz]; } return rep; } void DwStringRep::operator delete(void* aRep, size_t) { if (theirPoolCount < 200) { DwStringRep* rep = (DwStringRep*) aRep; ++theirPoolCount; rep->mNext = theirPool; theirPool = rep; } else { delete [] (char*) aRep; } } #endif //-------------------------------------------------------------------------- const size_t DwString::kEmptyBufferSize = 4; char DW_EXPORT DwString::sEmptyBuffer[]=" "; DwStringRep* DwString::sEmptyRep = 0; const size_t DwString::npos = (size_t) -1; DwString::DwString() { if (sEmptyRep == 0) { sEmptyBuffer[0] = 0; sEmptyRep = new DwStringRep(sEmptyBuffer, kEmptyBufferSize); assert(sEmptyRep != 0); } DBG_STMT(sEmptyRep->CheckInvariants()) mRep = new_rep_reference(sEmptyRep); mStart = 0; mLength = 0; } DwString::DwString(const DwString& aStr, size_t aPos, size_t aLen) { assert(aPos <= aStr.mLength); if (sEmptyRep == 0) { sEmptyBuffer[0] = 0; sEmptyRep = new DwStringRep(sEmptyBuffer, kEmptyBufferSize); assert(sEmptyRep != 0); } DBG_STMT(aStr.CheckInvariants()) size_t pos = DW_MIN(aPos, aStr.mLength); size_t len = DW_MIN(aLen, aStr.mLength - pos); if (len > 0) { mRep = new_rep_reference(aStr.mRep); mStart = aStr.mStart + pos; mLength = len; } else /* if (len == 0) */ { mRep = new_rep_reference(sEmptyRep); mStart = 0; mLength = 0; } } DwString::DwString(const char* aBuf, size_t aLen) { assert(aBuf != 0); assert(aLen != (size_t)-1); if (sEmptyRep == 0) { sEmptyBuffer[0] = 0; sEmptyRep = new DwStringRep(sEmptyBuffer, kEmptyBufferSize); assert(sEmptyRep != 0); } DBG_STMT(sEmptyRep->CheckInvariants()) // Set valid values, in case an exception is thrown mRep = new_rep_reference(sEmptyRep); mStart = 0; mLength = 0; _replace(0, mLength, aBuf, aLen); } DwString::DwString(FILE* aFile , size_t aLen) { assert(aFile != 0); assert(aLen != (size_t)-1); if (sEmptyRep == 0) { sEmptyBuffer[0] = 0; sEmptyRep = new DwStringRep(sEmptyBuffer, kEmptyBufferSize); assert(sEmptyRep != 0); } DBG_STMT(sEmptyRep->CheckInvariants()) // Set valid values, in case an exception is thrown mRep = new DwStringRep(aFile, aLen); mStart = 0; mLength = aLen; } DwString::DwString(const char* aCstr) { if (sEmptyRep == 0) { sEmptyBuffer[0] = 0; sEmptyRep = new DwStringRep(sEmptyBuffer, kEmptyBufferSize); assert(sEmptyRep != 0); } DBG_STMT(sEmptyRep->CheckInvariants()) // Set valid values, in case an exception is thrown mRep = new_rep_reference(sEmptyRep); mStart = 0; mLength = 0; if ( aCstr ) { size_t len = strlen(aCstr); _replace(0, mLength, aCstr, len); } } DwString::DwString(size_t aLen, char aChar) { assert(aLen != (size_t)-1); if (sEmptyRep == 0) { sEmptyBuffer[0] = 0; sEmptyRep = new DwStringRep(sEmptyBuffer, kEmptyBufferSize); assert(sEmptyRep != 0); } DBG_STMT(sEmptyRep->CheckInvariants()) // Set valid values, in case an exception is thrown mRep = new_rep_reference(sEmptyRep); mStart = 0; mLength = 0; _replace(0, mLength, aLen, aChar); } DwString::DwString(char* aBuf, size_t aSize, size_t aStart, size_t aLen) { assert(aBuf != 0); assert(aSize > 0); assert(aLen < aSize); assert(aStart < aSize - aLen); if (sEmptyRep == 0) { sEmptyBuffer[0] = 0; sEmptyRep = new DwStringRep(sEmptyBuffer, kEmptyBufferSize); assert(sEmptyRep != 0); } DBG_STMT(sEmptyRep->CheckInvariants()) // Set valid values, in case an exception is thrown mRep = new_rep_reference(sEmptyRep); mStart = 0; mLength = 0; DwStringRep* rep = new DwStringRep(aBuf, aSize); assert(rep != 0); if (rep != 0) { mRep = rep; mStart = aStart; mLength = aLen; } else /* if (rep == 0) */ { delete [] aBuf; } } DwString::~DwString() { assert(mRep != 0); delete_rep_safely(mRep); DEV_STMT(mRep = 0) } size_t DwString::max_size() const { return ((size_t)-1) - 1; } void DwString::resize(size_t aLen, char aChar) { // making string shorter? if (aLen < mLength) { mLength = aLen; if (mRep->mRefCount == 1) { mRep->mBuffer[mStart + aLen] = 0; } } // expanding string else if (aLen > mLength) { _replace(mLength, 0, aLen-mLength, aChar); } } void DwString::resize(size_t aLen) { resize(aLen, 0); } void DwString::reserve(size_t aSize) { if (mRep->mRefCount == 1 && aSize < mRep->mSize && mRep != sEmptyRep) { return; } size_t size = aSize + 1; char* newBuf = mem_alloc(&size); assert(newBuf != 0); if (newBuf != 0) { char* to = newBuf; const char* from = mRep->mBuffer + mStart; mem_copy(from, mLength, to); to[mLength] = 0; DwStringRep* rep= new DwStringRep(newBuf, size); assert(rep != 0); if (rep != 0) { delete_rep_safely(mRep); mRep = rep; mStart = 0; } else { mem_free(newBuf); } } } void DwString::clear() { assign(""); } DwString& DwString::append(const DwString& aStr) { return append(aStr, 0, aStr.mLength); } DwString& DwString::append(const DwString& aStr, size_t aPos, size_t aLen) { assert(aPos <= aStr.mLength); size_t pos = DW_MIN(aPos, aStr.mLength); size_t len = DW_MIN(aLen, aStr.mLength - pos); if (&aStr == this) { DwString temp(aStr); _replace(mLength, 0, &temp.mRep->mBuffer[temp.mStart+pos], len); } else { _replace(mLength, 0, &aStr.mRep->mBuffer[aStr.mStart+pos], len); } return *this; } DwString& DwString::append(const char* aBuf, size_t aLen) { assert(aBuf != 0); if (aBuf != 0) { _replace(mLength, 0, aBuf, aLen); } return *this; } DwString& DwString::append(const char* aCstr) { assert(aCstr != 0); size_t len = (aCstr) ? strlen(aCstr) : 0; _replace(mLength, 0, aCstr, len); return *this; } DwString& DwString::append(size_t aLen, char aChar) { _replace(mLength, 0, aLen, aChar); return *this; } DwString& DwString::assign(const DwString& aStr) { if (this != &aStr) { assign(aStr, 0, aStr.mLength); } return *this; } DwString& DwString::assign(const DwString& aStr, size_t aPos, size_t aLen) { assert(aPos <= aStr.mLength); size_t pos = DW_MIN(aPos, aStr.mLength); size_t len = DW_MIN(aLen, aStr.mLength - pos); if (mRep == aStr.mRep) { mStart = aStr.mStart + pos; mLength = len; } else { delete_rep_safely(mRep); mRep = new_rep_reference(aStr.mRep); mStart = aStr.mStart + pos; mLength = len; } return *this; } DwString& DwString::assign(const char* aBuf, size_t aLen) { assert(aBuf != 0); assert(aLen != (size_t)-1); _replace(0, mLength, aBuf, aLen); return *this; } DwString& DwString::assign(const char* aCstr) { assert(aCstr != 0); size_t len = (aCstr) ? strlen(aCstr) : 0; _replace(0, mLength, aCstr, len); return *this; } DwString& DwString::assign(size_t aLen, char aChar) { assert(aLen != (size_t)-1); _replace(0, mLength, aLen, aChar); return *this; } DwString& DwString::insert(size_t aPos, const DwString& aStr) { return insert(aPos, aStr, 0, aStr.mLength); } DwString& DwString::insert(size_t aPos1, const DwString& aStr, size_t aPos2, size_t aLen2) { assert(aPos1 <= mLength); assert(aPos2 <= aStr.mLength); size_t pos2 = DW_MIN(aPos2, aStr.mLength); size_t len2 = DW_MIN(aLen2, aStr.mLength - pos2); if (&aStr == this) { DwString temp(aStr); _replace(aPos1, 0, &temp.mRep->mBuffer[temp.mStart+pos2], len2); } else { _replace(aPos1, 0, &aStr.mRep->mBuffer[aStr.mStart+pos2], len2); } return *this; } DwString& DwString::insert(size_t aPos, const char* aBuf, size_t aLen) { assert(aBuf != 0); _replace(aPos, 0, aBuf, aLen); return *this; } DwString& DwString::insert(size_t aPos, const char* aCstr) { assert(aCstr != 0); size_t len = (aCstr) ? strlen(aCstr) : 0; _replace(aPos, 0, aCstr, len); return *this; } DwString& DwString::insert(size_t aPos, size_t aLen, char aChar) { _replace(aPos, 0, aLen, aChar); return *this; } DwString& DwString::erase(size_t aPos, size_t aLen) { assert(aPos <= mLength); size_t pos = DW_MIN(aPos, mLength); size_t len = DW_MIN(aLen, mLength - pos); _replace(pos, len, "", 0); return *this; } DwString& DwString::replace(size_t aPos1, size_t aLen1, const DwString& aStr) { return replace(aPos1, aLen1, aStr, 0, aStr.mLength); } DwString& DwString::replace(size_t aPos1, size_t aLen1, const DwString& aStr, size_t aPos2, size_t aLen2) { assert(aPos2 <= aStr.mLength); size_t pos2 = DW_MIN(aPos2, aStr.mLength); size_t len2 = DW_MIN(aLen2, aStr.mLength - pos2); if (&aStr == this) { DwString temp(aStr); _replace(aPos1, aLen1, &temp.mRep->mBuffer[temp.mStart+pos2], len2); } else { _replace(aPos1, aLen1, &aStr.mRep->mBuffer[aStr.mStart+pos2], len2); } return *this; } DwString& DwString::replace(size_t aPos1, size_t aLen1, const char* aBuf, size_t aLen2) { _replace(aPos1, aLen1, aBuf, aLen2); return *this; } DwString& DwString::replace(size_t aPos1, size_t aLen1, const char* aCstr) { size_t len2 = (aCstr) ? strlen(aCstr) : 0; _replace(aPos1, aLen1, aCstr, len2); return *this; } DwString& DwString::replace(size_t aPos1, size_t aLen1, size_t aLen2, char aChar) { _replace(aPos1, aLen1, aLen2, aChar); return *this; } size_t DwString::copy(char* aBuf, size_t aLen, size_t aPos) const { assert(aPos <= mLength); assert(aBuf != 0); size_t pos = DW_MIN(aPos, mLength); size_t len = DW_MIN(aLen, mLength - pos); char* to = aBuf; const char* from = mRep->mBuffer + mStart + pos; mem_copy(from, len, to); return len; } void DwString::swap(DwString& aStr) { DwStringRep* rep = mRep; mRep = aStr.mRep; aStr.mRep = rep; size_t n = mStart; mStart = aStr.mStart; aStr.mStart = n; n = mLength; mLength = aStr.mLength; aStr.mLength = n; } size_t DwString::find(const DwString& aStr, size_t aPos) const { return find(&aStr.mRep->mBuffer[aStr.mStart], aPos, aStr.mLength); } size_t DwString::find(const char* aBuf, size_t aPos, size_t aLen) const { assert(aBuf != 0); if (aBuf == 0) return (size_t)-1; if (aLen > mLength) return (size_t)-1; if (aPos > mLength-aLen) return (size_t)-1; if (aLen == 0) return aPos; const char* buf = mRep->mBuffer + mStart; for (size_t i=aPos; i <= mLength-aLen; ++i) { size_t k = i; size_t j = 0; while (j < aLen && aBuf[j] == buf[k]) { ++j; ++k; } if (j == aLen) return i; } return (size_t)-1; } size_t DwString::find(const char* aCstr, size_t aPos) const { assert(aCstr != 0); if (aCstr == 0) return (size_t)-1; size_t len = strlen(aCstr); return find(aCstr, aPos, len); } size_t DwString::find(char aChar, size_t aPos) const { if (aPos >= mLength) return (size_t)-1; const char* buf = mRep->mBuffer + mStart; for (size_t i=aPos; i < mLength; ++i) { if (buf[i] == aChar) return i; } return (size_t)-1; } size_t DwString::rfind(const DwString& aStr, size_t aPos) const { return rfind(&aStr.mRep->mBuffer[aStr.mStart], aPos, aStr.mLength); } size_t DwString::rfind(const char* aBuf, size_t aPos, size_t aLen) const { assert(aBuf != 0); if (aBuf == 0) return (size_t)-1; if (aLen > mLength) return (size_t)-1; size_t pos = DW_MIN(aPos, mLength - aLen); if (aLen == 0) return pos; const char* buf = mRep->mBuffer + mStart; for (size_t i=0; i <= pos; ++i) { size_t k = pos - i; size_t j = 0; while (j < aLen && aBuf[j] == buf[k]) { ++j; ++k; } if (j == aLen) return pos - i; } return (size_t)-1; } size_t DwString::rfind(const char* aCstr, size_t aPos) const { assert(aCstr != 0); size_t len = (aCstr) ? strlen(aCstr) : 0; return rfind(aCstr, aPos, len); } size_t DwString::rfind(char aChar, size_t aPos) const { size_t pos = DW_MIN(aPos, mLength - 1); const char* buf = mRep->mBuffer + mStart; for (size_t i=0; i <= pos; ++i) { size_t k = pos - i; if (buf[k] == aChar) return k; } return (size_t)-1; } size_t DwString::find_first_of(const DwString& aStr, size_t aPos) const { return find_first_of(&aStr.mRep->mBuffer[aStr.mStart], aPos, aStr.mLength); } size_t DwString::find_first_of(const char* aBuf, size_t aPos, size_t aLen) const { assert(aBuf != 0); if (aBuf == 0) return (size_t)-1; if (aPos >= mLength) return (size_t)-1; if (aLen == 0) return aPos; char table[256]; memset(table, 0, sizeof(table)); for (size_t j=0; j < aLen; ++j) { table[aBuf[j]&0xff] = 1; } const char* buf = mRep->mBuffer + mStart; for (size_t i=aPos; i < mLength; ++i) { if (table[buf[i]&0xff]) return i; } return (size_t)-1; } size_t DwString::find_first_of(const char* aCstr, size_t aPos) const { assert(aCstr != 0); if (aCstr == 0) return (size_t)-1; size_t len = strlen(aCstr); return find_first_of(aCstr, aPos, len); } size_t DwString::find_last_of(const DwString& aStr, size_t aPos) const { return find_last_of(&aStr.mRep->mBuffer[aStr.mStart], aPos, aStr.mLength); } size_t DwString::find_last_of(const char* aBuf, size_t aPos, size_t aLen) const { assert(aBuf != 0); if (aBuf == 0) return (size_t)-1; if (mLength == 0) return (size_t)-1; size_t pos = DW_MIN(aPos, mLength - 1); if (aLen == 0) return pos; char table[256]; memset(table, 0, sizeof(table)); for (size_t j=0; j < aLen; ++j) { table[aBuf[j]&0xff] = 1; } const char* buf = mRep->mBuffer + mStart; for (size_t k=0; k <= pos; ++k) { size_t i = pos - k; if (table[buf[i]&0xff]) return i; } return (size_t)-1; } size_t DwString::find_last_of(const char* aCstr, size_t aPos) const { assert(aCstr != 0); if (aCstr == 0) return (size_t)-1; size_t len = strlen(aCstr); return find_last_of(aCstr, aPos, len); } size_t DwString::find_first_not_of(const DwString& aStr, size_t aPos) const { return find_first_not_of(&aStr.mRep->mBuffer[aStr.mStart], aPos, aStr.mLength); } size_t DwString::find_first_not_of(const char* aBuf, size_t aPos, size_t aLen) const { assert(aBuf != 0); if (aBuf == 0) return (size_t)-1; if (aPos >= mLength) return (size_t)-1; if (aLen == 0) return (size_t)-1; char table[256]; memset(table, 1, sizeof(table)); for (size_t j=0; j < aLen; ++j) { table[aBuf[j]&0xff] = 0; } const char* buf = mRep->mBuffer + mStart; for (size_t i=aPos; i < mLength; ++i) { if (table[buf[i]&0xff]) return i; } return (size_t)-1; } size_t DwString::find_first_not_of(const char* aCstr, size_t aPos) const { assert(aCstr != 0); if (aCstr == 0) return (size_t)-1; size_t len = strlen(aCstr); return find_first_not_of(aCstr, aPos, len); } size_t DwString::find_last_not_of(const DwString& aStr, size_t aPos) const { return find_last_not_of(&aStr.mRep->mBuffer[aStr.mStart], aPos, aStr.mLength); } size_t DwString::find_last_not_of(const char* aBuf, size_t aPos, size_t aLen) const { assert(aBuf != 0); if (aBuf == 0) return (size_t)-1; if (mLength == 0) return (size_t)-1; size_t pos = DW_MIN(aPos, mLength - 1); if (aLen == 0) return (size_t)-1; char table[256]; memset(table, 1, sizeof(table)); for (size_t j=0; j < aLen; ++j) { table[aBuf[j]&0xff] = 0; } const char* buf = mRep->mBuffer + mStart; for (size_t k=0; k <= pos; ++k) { size_t i = pos - k; if (table[buf[i]&0xff]) return i; } return (size_t)-1; } size_t DwString::find_last_not_of(const char* aCstr, size_t aPos) const { assert(aCstr != 0); if (aCstr == 0) return (size_t)-1; size_t len = strlen(aCstr); return find_last_not_of(aCstr, aPos, len); } DwString DwString::substr(size_t aPos, size_t aLen) const { assert(aPos <= mLength); size_t pos = DW_MIN(aPos, mLength); size_t len = DW_MIN(aLen, mLength - pos); return DwString(*this, pos, len); } int DwString::compare(const DwString& aStr) const { return compare(0, mLength, aStr, 0, aStr.mLength); } int DwString::compare(size_t aPos1, size_t aLen1, const DwString& aStr) const { return compare(aPos1, aLen1, aStr, 0, aStr.mLength); } int DwString::compare(size_t aPos1, size_t aLen1, const DwString& aStr, size_t aPos2, size_t aLen2) const { assert(aPos1 <= mLength); assert(aPos2 <= aStr.mLength); size_t pos1 = DW_MIN(aPos1, mLength); const char* buf1 = mRep->mBuffer + mStart + pos1; size_t len1 = DW_MIN(aLen1, mLength - pos1); size_t pos2 = DW_MIN(aPos2, aStr.mLength); const char* buf2 = aStr.mRep->mBuffer + aStr.mStart + pos2; size_t len2 = DW_MIN(aLen2, aStr.mLength - pos2); size_t len = DW_MIN(len1, len2); int r = strncmp(buf1, buf2, len); if (r == 0) { if (len1 < len2) r = -1; else if (len1 > len2) { r = 1; } } return r; } int DwString::compare(const char* aCstr) const { assert(aCstr != 0); size_t len = (aCstr) ? strlen(aCstr) : 0; return compare(0, mLength, aCstr, len); } int DwString::compare(size_t aPos1, size_t aLen1, const char* aBuf, size_t aLen2) const { assert(aBuf != 0); assert(aPos1 <= mLength); if (aBuf == 0) { return (aLen1 > 0) ? 1 : 0; } size_t pos1 = DW_MIN(aPos1, mLength); const char* buf1 = mRep->mBuffer + mStart + pos1; size_t len1 = DW_MIN(aLen1, mLength - pos1); const char* buf2 = aBuf; size_t len2 = aLen2; size_t len = DW_MIN(len1, len2); int r = strncmp(buf1, buf2, len); if (r == 0) { if (len1 < len2) r = -1; else if (len1 > len2) { r = 1; } } return r; } const char* DwString::ClassName() const { return "DwString"; } int DwString::ObjectId() const { return (int) (long) this; } void DwString::ConvertToLowerCase() { if (mRep->mRefCount > 1) { _copy(); } char* buf = mRep->mBuffer + mStart; for (size_t i=0; i < mLength; ++i) { buf[i] = (char) dw_asciitolower(buf[i]); } } void DwString::ConvertToUpperCase() { if (mRep->mRefCount > 1) { _copy(); } char* buf = mRep->mBuffer + mStart; for (size_t i=0; i < mLength; ++i) { buf[i] = (char) dw_asciitoupper(buf[i]); } } void DwString::Trim() { const char* buf = mRep->mBuffer + mStart; size_t i = 0; while (mLength > 0) { if (isspace(buf[i])) { ++mStart; --mLength; ++i; } else { break; } } buf = mRep->mBuffer + mStart; i = mLength - 1; while (mLength > 0) { if (isspace(buf[i])) { --mLength; --i; } else { break; } } if (mLength == 0) { assign(""); } } void DwString::WriteTo(std::ostream& aStrm) const { const char* buf = mRep->mBuffer + mStart; for (size_t i=0; i < mLength; ++i) { aStrm << buf[i]; } } void DwString::TakeBuffer(char* aBuf, size_t aSize, size_t aStart, size_t aLen) { assert(aBuf != 0); DwStringRep* rep = new DwStringRep(aBuf, aSize); assert(rep != 0); if (rep) { delete_rep_safely(mRep); mRep = rep; mStart = aStart; mLength = aLen; } } void DwString::ReleaseBuffer(char** aBuf, size_t* aSize, size_t* aStart, size_t* aLen) { assert(aBuf != 0); assert(aSize != 0); assert(aStart != 0); assert(aLen != 0); if (mRep->mRefCount == 1) { *aBuf = mRep->mBuffer; *aSize = mRep->mSize; } else { size_t size = mRep->mSize; char* buf = new char [size]; assert(buf != 0); if (buf != 0) { mem_copy(mRep->mBuffer, size, buf); *aBuf = buf; *aSize = size; } else { // If not throwing an exception, recover as best we can *aBuf = 0; *aSize = 0; *aStart = mStart = 0; *aLen = mLength = 0; return; } } *aStart = mStart; *aLen = mLength; mRep = new_rep_reference(sEmptyRep); mStart = 0; mLength = 0; } void DwString::CopyTo(DwString* aStr) const { assert(aStr != 0); if (!aStr) return; size_t len = mLength; size_t size = len + 1; char* buf = mem_alloc(&size); assert(buf != 0); if (buf != 0) { mem_copy(mRep->mBuffer+mStart, len, buf); buf[len] = 0; DwStringRep* rep = new DwStringRep(buf, size); assert(rep != 0); if (rep != 0) { aStr->mRep = rep; delete_rep_safely(aStr->mRep); aStr->mStart = 0; aStr->mLength = len; } } } void DwString::_copy() { if (mRep->mRefCount > 1) { size_t size = mLength + 1; char* newBuf = mem_alloc(&size); assert(newBuf != 0); if (newBuf != 0) { char* to = newBuf; const char* from = mRep->mBuffer + mStart; mem_copy(from, mLength, to); to[mLength] = 0; DwStringRep* rep = new DwStringRep(newBuf, size); assert(rep != 0); if (rep != 0) { delete_rep_safely(mRep); mRep = rep; mStart = 0; } else /* if (rep == 0) */ { mem_free(newBuf); mLength = 0; } } else /* if (newBuf == 0) */ { mLength = 0; } } } void DwString::_replace(size_t aPos1, size_t aLen1, const char* aBuf, size_t aLen2) { assert(aPos1 <= mLength); assert(aBuf != 0); size_t pos1 = DW_MIN(aPos1, mLength); size_t len1 = DW_MIN(aLen1, mLength - pos1); assert(mStart + mLength - len1 < ((size_t)-1) - aLen2); size_t len2 = DW_MIN(aLen2, ((size_t)-1) - (mStart + mLength - len1)); size_t i; char* to; const char* from; size_t newLen = (mLength - len1) + len2; // Is new string empty? if (newLen == 0 || aBuf == 0) { if (mRep != sEmptyRep) { delete_rep_safely(mRep); mRep = new_rep_reference(sEmptyRep); mStart = 0; mLength = 0; } } // Is buffer shared? Is buffer too small? else if (mRep->mRefCount > 1 || newLen >= mRep->mSize) { size_t size = newLen + 1; char* newBuf = mem_alloc(&size); assert(newBuf != 0); if (newBuf != 0) { to = newBuf; memcpy(to, mRep->mBuffer + mStart, pos1); to += pos1; memcpy(to, aBuf, len2); to += len2; memcpy(to, mRep->mBuffer + mStart + pos1 + len1, mLength - pos1 - len1); to += mLength - pos1 - len1; *to = 0; DwStringRep* rep = new DwStringRep(newBuf, size); assert(rep != 0); if (rep != 0) { delete_rep_safely(mRep); mRep = rep; mStart = 0; mLength = newLen; } } } // Is the replacement smaller than the replaced? else if (len2 < len1) { to = mRep->mBuffer + mStart + pos1; from = aBuf; for (i=0; i < len2; ++i) *to++ = *from++; from = mRep->mBuffer + mStart + pos1 + len1; for (i=0; i < mLength - pos1 - len1; ++i) *to++ = *from++; *to = 0; mLength = newLen; } // Is there enough room at end of buffer? else if (mStart + newLen < mRep->mSize) { to = mRep->mBuffer + mStart + newLen; from = mRep->mBuffer + mStart + mLength - 1; *to-- = 0; for (i=0; i < mLength-pos1-len1; ++i) *to-- = *from--; from = aBuf + (len2 - 1); for (i=0; i < len2; ++i) *to-- = *from--; mLength = newLen; } // Is there enough room at beginning of buffer? else if (len2 - len1 <= mStart) { to = mRep->mBuffer + mStart - (len2 - len1); from = mRep->mBuffer + mStart; for (i=0; i < pos1; ++i) *to++ = *from++; from = aBuf; for (i=0; i < len2; ++i) *to++ = *from++; mStart -= len2 - len1; mLength = newLen; } // There's enough room, but we must move characters. else { to = mRep->mBuffer + newLen; from = mRep->mBuffer + mStart + mLength - 1; *to-- = 0; for (i=0; i < mLength-pos1-len1; ++i) *to-- = *from--; to = mRep->mBuffer; from = mRep->mBuffer + mStart; for (i=0; i < pos1; ++i) *to++ = *from++; from = aBuf; for (i=0; i < len2; ++i) *to++ = *from++; mStart = 0; mLength = newLen; } } void DwString::_replace(size_t aPos1, size_t aLen1, size_t aLen2, char aChar) { assert(aPos1 <= mLength); size_t pos1 = DW_MIN(aPos1, mLength); size_t len1 = DW_MIN(aLen1, mLength - pos1); assert(mStart + mLength - len1 < ((size_t)-1) - aLen2); size_t len2 = DW_MIN(aLen2, ((size_t)-1) - (mStart + mLength - len1)); size_t i; char* to; const char* from; size_t newLen = mLength - len1 + len2; // Is new string empty? if (newLen == 0) { if (mRep != sEmptyRep) { delete_rep_safely(mRep); mRep = new_rep_reference(sEmptyRep); mStart = 0; mLength = 0; } } // Is buffer shared? Is buffer too small? else if (mRep->mRefCount > 1 || newLen >= mRep->mSize) { size_t size = newLen + 1; char* newBuf = mem_alloc(&size); assert(newBuf != 0); if (newBuf != 0) { to = newBuf; from = mRep->mBuffer + mStart; for (i=0; i < pos1; ++i) *to++ = *from++; for (i=0; i < len2; ++i) *to++ = aChar; from = mRep->mBuffer + mStart + pos1 + len1; for (i=0; i < mLength - pos1 - len1; ++i) *to++ = *from++; *to = 0; DwStringRep* rep = new DwStringRep(newBuf, size); assert(rep != 0); if (rep != 0) { delete_rep_safely(mRep); mRep = rep; mStart = 0; mLength = newLen; } } } // Is the replacement smaller than the replaced? else if (len2 < len1) { to = mRep->mBuffer + mStart + pos1; for (i=0; i < len2; ++i) *to++ = aChar; from = mRep->mBuffer + mStart + pos1 + len1; for (i=0; i < mLength - pos1 - len1; ++i) *to++ = *from++; *to = 0; mLength = newLen; } // Is there enough room at end of buffer? else if (mStart + newLen < mRep->mSize) { to = mRep->mBuffer + mStart + newLen; from = mRep->mBuffer + mStart + mLength - 1; *to-- = 0; for (i=0; i < mLength-pos1-len1; ++i) *to-- = *from--; for (i=0; i < len2; ++i) *to-- = aChar; mLength = newLen; } // Is there enough room at beginning of buffer? else if (len2 - len1 <= mStart) { to = mRep->mBuffer + mStart - (len2 - len1); from = mRep->mBuffer + mStart; for (i=0; i < pos1; ++i) *to++ = *from++; for (i=0; i < len2; ++i) *to++ = aChar; mStart -= len2 - len1; mLength = newLen; } // There's enough room, but we must move characters. else { to = mRep->mBuffer + newLen; from = mRep->mBuffer + mStart + mLength - 1; *to-- = 0; for (i=0; i < mLength-pos1-len1; ++i) *to-- = *from--; to = mRep->mBuffer; from = mRep->mBuffer + mStart; for (i=0; i < pos1; ++i) *to++ = *from++; for (i=0; i < len2; ++i) *to++ = aChar; mStart = 0; mLength = newLen; } } #if defined (DW_DEBUG_VERSION) void DwString::PrintDebugInfo(std::ostream& aStrm) const { aStrm << "----------------- Debug info for DwString class ----------------\n"; aStrm << "Id: " << ClassName() << ", " << ObjectId() << "\n"; aStrm << "Rep: " << (void*) mRep << "\n"; aStrm << "Buffer: " << (void*) mRep->mBuffer << "\n"; aStrm << "Buffer size: " << mRep->mSize << "\n"; aStrm << "Start: " << mStart << "\n"; aStrm << "Length: " << mLength << "\n"; aStrm << "Contents: "; for (size_t i=0; i < mLength && i < 64; ++i) { aStrm << mRep->mBuffer[mStart+i]; } aStrm << std::endl; } #else void DwString::PrintDebugInfo(std::ostream& ) const {} #endif // defined (DW_DEBUG_VERSION) void DwString::CheckInvariants() const { #if defined (DW_DEBUG_VERSION) assert(mRep != 0); mRep->CheckInvariants(); #endif // defined (DW_DEBUG_VERSION) } DwString operator + (const DwString& aStr1, const DwString& aStr2) { DwString str(aStr1); str.append(aStr2); return str; } DwString operator + (const char* aCstr, const DwString& aStr2) { DwString str(aCstr); str.append(aStr2); return str; } DwString operator + (char aChar, const DwString& aStr2) { DwString str(1, aChar); str.append(aStr2); return str; } DwString operator + (const DwString& aStr1, const char* aCstr) { DwString str(aStr1); str.append(aCstr); return str; } DwString operator + (const DwString& aStr1, char aChar) { DwString str(aStr1); str.append(1, aChar); return str; } DwBool operator == (const DwString& aStr1, const DwString& aStr2) { const char* s1 = aStr1.data(); size_t len1 = aStr1.length(); const char* s2 = aStr2.data(); size_t len2 = aStr2.length(); int r = dw_strcmp(s1, len1, s2, len2); r = (r == 0) ? 1 : 0; return r; } DwBool operator == (const DwString& aStr1, const char* aCstr) { assert(aCstr != 0); const char* s1 = aStr1.data(); size_t len1 = aStr1.length(); const char* s2 = aCstr; size_t len2 = (aCstr) ? strlen(aCstr) : 0; int r = dw_strcmp(s1, len1, s2, len2); r = (r == 0) ? 1 : 0; return r; } DwBool operator == (const char* aCstr, const DwString& aStr2) { assert(aCstr != 0); const char* s1 = aCstr; size_t len1 = (aCstr) ? strlen(aCstr) : 0; const char* s2 = aStr2.data(); size_t len2 = aStr2.length(); int r = dw_strcmp(s1, len1, s2, len2); r = (r == 0) ? 1 : 0; return r; } DwBool operator != (const DwString& aStr1, const DwString& aStr2) { const char* s1 = aStr1.data(); size_t len1 = aStr1.length(); const char* s2 = aStr2.data(); size_t len2 = aStr2.length(); int r = dw_strcmp(s1, len1, s2, len2); r = (r == 0) ? 0 : 1; return r; } DwBool operator != (const DwString& aStr1, const char* aCstr) { assert(aCstr != 0); const char* s1 = aStr1.data(); size_t len1 = aStr1.length(); const char* s2 = aCstr; size_t len2 = (aCstr) ? strlen(aCstr) : 0; int r = dw_strcmp(s1, len1, s2, len2); r = (r == 0) ? 0 : 1; return r; } DwBool operator != (const char* aCstr, const DwString& aStr2) { assert(aCstr != 0); const char* s1 = aCstr; size_t len1 = (aCstr) ? strlen(aCstr) : 0; const char* s2 = aStr2.data(); size_t len2 = aStr2.length(); int r = dw_strcmp(s1, len1, s2, len2); r = (r == 0) ? 0 : 1; return r; } DwBool operator < (const DwString& aStr1, const DwString& aStr2) { const char* s1 = aStr1.data(); size_t len1 = aStr1.length(); const char* s2 = aStr2.data(); size_t len2 = aStr2.length(); int r = dw_strcmp(s1, len1, s2, len2); r = (r < 0) ? 1 : 0; return r; } DwBool operator < (const DwString& aStr1, const char* aCstr) { assert(aCstr != 0); const char* s1 = aStr1.data(); size_t len1 = aStr1.length(); const char* s2 = aCstr; size_t len2 = (aCstr) ? strlen(aCstr) : 0; int r = dw_strcmp(s1, len1, s2, len2); r = (r < 0) ? 1 : 0; return r; } DwBool operator < (const char* aCstr, const DwString& aStr2) { assert(aCstr != 0); const char* s1 = aCstr; size_t len1 = (aCstr) ? strlen(aCstr) : 0; const char* s2 = aStr2.data(); size_t len2 = aStr2.length(); int r = dw_strcmp(s1, len1, s2, len2); r = (r < 0) ? 1 : 0; return r; } DwBool operator > (const DwString& aStr1, const DwString& aStr2) { const char* s1 = aStr1.data(); size_t len1 = aStr1.length(); const char* s2 = aStr2.data(); size_t len2 = aStr2.length(); int r = dw_strcmp(s1, len1, s2, len2); r = (r > 0) ? 1 : 0; return r; } DwBool operator > (const DwString& aStr1, const char* aCstr) { assert(aCstr != 0); const char* s1 = aStr1.data(); size_t len1 = aStr1.length(); const char* s2 = aCstr; size_t len2 = (aCstr) ? strlen(aCstr) : 0; int r = dw_strcmp(s1, len1, s2, len2); r = (r > 0) ? 1 : 0; return r; } DwBool operator > (const char* aCstr, const DwString& aStr2) { assert(aCstr != 0); const char* s1 = aCstr; size_t len1 = (aCstr) ? strlen(aCstr) : 0; const char* s2 = aStr2.data(); size_t len2 = aStr2.length(); int r = dw_strcmp(s1, len1, s2, len2); r = (r > 0) ? 1 : 0; return r; } DwBool operator <= (const DwString& aStr1, const DwString& aStr2) { const char* s1 = aStr1.data(); size_t len1 = aStr1.length(); const char* s2 = aStr2.data(); size_t len2 = aStr2.length(); int r = dw_strcmp(s1, len1, s2, len2); r = (r <= 0) ? 1 : 0; return r; } DwBool operator <= (const DwString& aStr1, const char* aCstr) { assert(aCstr != 0); const char* s1 = aStr1.data(); size_t len1 = aStr1.length(); const char* s2 = aCstr; size_t len2 = (aCstr) ? strlen(aCstr) : 0; int r = dw_strcmp(s1, len1, s2, len2); r = (r <= 0) ? 1 : 0; return r; } DwBool operator <= (const char* aCstr, const DwString& aStr2) { assert(aCstr != 0); const char* s1 = aCstr; size_t len1 = (aCstr) ? strlen(aCstr) : 0; const char* s2 = aStr2.data(); size_t len2 = aStr2.length(); int r = dw_strcmp(s1, len1, s2, len2); r = (r <= 0) ? 1 : 0; return r; } DwBool operator >= (const DwString& aStr1, const DwString& aStr2) { const char* s1 = aStr1.data(); size_t len1 = aStr1.length(); const char* s2 = aStr2.data(); size_t len2 = aStr2.length(); int r = dw_strcmp(s1, len1, s2, len2); r = (r >= 0) ? 1 : 0; return r; } DwBool operator >= (const DwString& aStr1, const char* aCstr) { assert(aCstr != 0); const char* s1 = aStr1.data(); size_t len1 = aStr1.length(); const char* s2 = aCstr; size_t len2 = (aCstr) ? strlen(aCstr) : 0; int r = dw_strcmp(s1, len1, s2, len2); r = (r >= 0) ? 1 : 0; return r; } DwBool operator >= (const char* aCstr, const DwString& aStr2) { assert(aCstr != 0); const char* s1 = aCstr; size_t len1 = (aCstr) ? strlen(aCstr) : 0; const char* s2 = aStr2.data(); size_t len2 = aStr2.length(); int r = dw_strcmp(s1, len1, s2, len2); r = (r >= 0) ? 1 : 0; return r; } std::ostream& operator << (std::ostream& aOstrm, const DwString& aStr) { const char* buf = aStr.data(); for (size_t i=0; i < aStr.length(); ++i) { aOstrm << buf[i]; } return aOstrm; } std::istream& getline(std::istream& aIstrm, DwString& aStr, char aDelim) { aStr.clear(); char ch; while (aIstrm.get(ch)) { if (ch == aDelim) break; if (aStr.length() < aStr.max_size()) { aStr.append(1, ch); } } return aIstrm; } std::istream& getline(std::istream& aIstrm, DwString& aStr) { return getline(aIstrm, aStr, '\n'); } #endif // !defined(DW_USE_ANSI_STRING) int DwStrcasecmp(const DwString& aStr1, const DwString& aStr2) { const char* s1 = aStr1.data(); size_t len1 = aStr1.length(); const char* s2 = aStr2.data(); size_t len2 = aStr2.length(); return dw_strasciicasecmp(s1, len1, s2, len2); } int DwStrcasecmp(const DwString& aStr, const char* aCstr) { assert(aCstr != 0); const char* s1 = aStr.data(); size_t len1 = aStr.length(); const char* s2 = aCstr; size_t len2 = (aCstr) ? strlen(aCstr) : 0; return dw_strasciicasecmp(s1, len1, s2, len2); } int DwStrcasecmp(const char* aCstr, const DwString& aStr) { assert(aCstr != 0); const char* s1 = aCstr; size_t len1 = (aCstr) ? strlen(aCstr) : 0; const char* s2 = aStr.data(); size_t len2 = aStr.length(); return dw_strasciicasecmp(s1, len1, s2, len2); } int DwStrncasecmp(const DwString& aStr1, const DwString& aStr2, size_t n) { const char* s1 = aStr1.data(); size_t len1 = aStr1.length(); len1 = DW_MIN(len1, n); const char* s2 = aStr2.data(); size_t len2 = aStr2.length(); len2 = DW_MIN(len2, n); return dw_strasciicasecmp(s1, len1, s2, len2); } int DwStrncasecmp(const DwString& aStr, const char* aCstr, size_t n) { assert(aCstr != 0); const char* s1 = aStr.data(); size_t len1 = aStr.length(); len1 = DW_MIN(len1, n); const char* s2 = aCstr; size_t len2 = (aCstr) ? strlen(aCstr) : 0; len2 = DW_MIN(len2, n); return dw_strasciicasecmp(s1, len1, s2, len2); } int DwStrncasecmp(const char* aCstr, const DwString& aStr, size_t n) { assert(aCstr != 0); const char* s1 = aCstr; size_t len1 = (aCstr) ? strlen(aCstr) : 0; len1 = DW_MIN(len1, n); const char* s2 = aStr.data(); size_t len2 = aStr.length(); len2 = DW_MIN(len2, n); return dw_strasciicasecmp(s1, len1, s2, len2); } int DwStrcmp(const DwString& aStr1, const DwString& aStr2) { const char* s1 = aStr1.data(); size_t len1 = aStr1.length(); const char* s2 = aStr2.data(); size_t len2 = aStr2.length(); return dw_strcmp(s1, len1, s2, len2); } int DwStrcmp(const DwString& aStr, const char* aCstr) { assert(aCstr != 0); const char* s1 = aStr.data(); size_t len1 = aStr.length(); const char* s2 = aCstr; size_t len2 = (aCstr) ? strlen(aCstr) : 0; return dw_strcmp(s1, len1, s2, len2); } int DwStrcmp(const char* aCstr, const DwString& aStr) { assert(aCstr != 0); const char* s1 = aCstr; size_t len1 = (aCstr) ? strlen(aCstr) : 0; const char* s2 = aStr.data(); size_t len2 = aStr.length(); return dw_strcmp(s1, len1, s2, len2); } int DwStrncmp(const DwString& aStr1, const DwString& aStr2, size_t n) { const char* s1 = aStr1.data(); size_t len1 = aStr1.length(); len1 = DW_MIN(len1, n); const char* s2 = aStr2.data(); size_t len2 = aStr2.length(); len2 = DW_MIN(len2, n); return dw_strcmp(s1, len1, s2, len2); } int DwStrncmp(const DwString& aStr, const char* aCstr, size_t n) { assert(aCstr != 0); const char* s1 = aStr.data(); size_t len1 = aStr.length(); len1 = DW_MIN(len1, n); const char* s2 = aCstr; size_t len2 = (aCstr) ? strlen(aCstr) : 0; len2 = DW_MIN(len2, n); return dw_strcmp(s1, len1, s2, len2); } int DwStrncmp(const char* aCstr, const DwString& aStr, size_t n) { assert(aCstr != 0); const char* s1 = aCstr; size_t len1 = (aCstr) ? strlen(aCstr) : 0; len1 = DW_MIN(len1, n); const char* s2 = aStr.data(); size_t len2 = aStr.length(); len2 = DW_MIN(len2, n); return dw_strcmp(s1, len1, s2, len2); } void DwStrcpy(DwString& aStrDest, const DwString& aStrSrc) { aStrDest.assign(aStrSrc); } void DwStrcpy(DwString& aStrDest, const char* aCstrSrc) { aStrDest.assign(aCstrSrc); } void DwStrcpy(char* aCstrDest, const DwString& aStrSrc) { assert(aCstrDest != 0); const char* buf = aStrSrc.data(); size_t len = aStrSrc.length(); mem_copy(buf, len, aCstrDest); aCstrDest[len] = 0; } void DwStrncpy(DwString& aStrDest, const DwString& aStrSrc, size_t n) { aStrDest.assign(aStrSrc, 0, n); } void DwStrncpy(DwString& aStrDest, const char* aCstrSrc, size_t n) { aStrDest.assign(aCstrSrc, 0, n); } void DwStrncpy(char* aCstrDest, const DwString& aStrSrc, size_t n) { assert(aCstrDest != 0); const char* buf = aStrSrc.data(); size_t len = aStrSrc.length(); len = DW_MIN(len, n); mem_copy(buf, len, aCstrDest); for (size_t i=len; i < n; ++i) { aCstrDest[i] = 0; } } char* DwStrdup(const DwString& aStr) { size_t len = aStr.length(); char* buf = new char[len+1]; assert(buf != 0); if (buf != 0) { DwStrncpy(buf, aStr, len); buf[len] = 0; } return buf; } mimelib1-1.1.4/mimelib/Tutorial0000644000175000017500000005240011175345261015766 0ustar resivoresivo T U T O R I A L F O R M I M E + + 1. Introduction Welcome to MIME++, a C++ class library for creating, parsing, and modifying messages in MIME format. MIME++ has been designed specifically with the following objectives in mind: * Create classes that directly correspond to the elements described in RFC-822, RFC-2045, and other MIME-related documents. * Create a library that is easy to use. * Create a library that is extensible. MIME++ classes directly model the elements of the BNF grammar specified in RFC-822, RFC-2045, and RFC-2046. For this reason, I recommend that you understand these RFCs and keep a copy of them handy as you learn MIME++. If you know C++ well, and if you are familiar with the RFCs, you should find MIME++ easy to learn and use. If you are new to C++ and object-oriented programming, you will find in MIME++ some very good object-oriented techinques, and hopefully you will learn a lot. Before looking at the MIME++ classes, it is important to understand how MIME++ represents a message. There are two representations of a message. The first is a string representation, in which a message is considered simply a sequence of characters. The second is a 'broken-down' -- that is, parsed -- representation, in which the message is represented as a tree of components. The tree will be explained later, but for now, let's consider the relationship between the string representation and the broken-down representation. When you create a new message, the string representation is initially empty. After you set the contents of the broken-down representation, such as the header fields and the message body, you then assemble the message from its broken-down representation into its string representation. The assembling is done through a call to the Assemble() member function of the DwMessage class. Conversely, when you receive a message, it is received in its string representation, and you parse the message to create its broken-down representation. The parsing is done through a call to the Parse() member function of the DwMessage class. From the broken-down representation, you can access the header fields, the body, and so on. If you want to modify a received message, you can change the contents of the broken-down representation, then assemble the message to create the modified string representation. Because of the way MIME++ implements the broken-down representation, only those specific components that were modified in the broken-down representation will be modified in the new string representation. The broken-down representation takes the form of a tree. The idea for the tree comes from the idea that a message can be broken down into various components, and that the components form a hierarchy. At the highest level, we have the complete message. We can break the message down into a header and a body to arrive at the second-highest level. We can break the header down into a collection of header fields. We can break each header field down into a field-name and a field-body. If the header field is a structured field, we can further break down its field-body into components specific to that field-body, such as a local-part and domain for a mailbox. Now, we can think of each component of the message as a node in the tree. The top, or root, node is the message itself. Below that, the message node contains child nodes for the header and body; the header node contains a child node for each header field; and so on. Each node contains a substring of the entire message, and a node's string is the concatenation of all of its child nodes' strings. In the MIME++ implementation, the abstract base class DwMessageComponent encapsulates all the common attributes and behavior of the tree's nodes. The most important member functions of DwMessageComponent are Parse() and Assemble(), which are declared as pure virtual functions. Normally, you would use these member functions only as operations on objects of the class DwMessage, a subclass of DwMessageComponent. Parse() builds the entire tree of components with the DwMessage object at the root. Assemble() builds the string representation of the DwMessage object by traversing the tree and concatenating the strings of the leaf nodes. While every node in the tree is a DwMessageComponent, and therefore has a Parse() and Assemble() member function, you do not have to call these member functions for every node in the tree. The reason is that both of these functions traverse the subtree rooted at the current node. Parse() acts first on the current node, then calls the Parse() member function of its child nodes. Assemble() first calls the Assemble() member functions of a node's child nodes, then concatenates the string representations of its child nodes. Therefore, when you call Parse() or Assemble() for an object of the class DwMessage, Parse() or Assemble() will be called automatically for every component (that is, child node) in the message. DwMessageComponent also has one important attribute that you should be aware of. That attribute is an is-modified flag (aka dirty flag), which is cleared whenever Parse() or Assemble() is called, and is set whenever the broken-down representation is modified. To understand how this works, suppose you have just called Parse() on a DwMessage object to create its broken-down representation. If you add a new DwField object (representing a new header field) to the DwHeaders object (representing the header), the is-modified flag will be set for the DwHeaders object, indicating that the string representation of the DwHeaders object will have to be re-assembled from the header fields that it contains. When a node's is-modified flag is set, it also notifies its parent node to set its is-modified flag. Thus, when the DwHeaders object's is-modified flag is set, the DwMessage object that is its parent will also have its is-modified flag set. That way, when Assemble() is called for the DwMessage object, it will call the Assemble() member function for the DwHeaders object, as required. Notice that the value of having an is-modified flag is that it can purge the tree traversal when the string representation of a message is being assembled. One of the first classes you should become familiar with is the DwString class, which handles character strings in MIME++. DwString has been designed to handle very large character strings, so it may be different from string classes in other libraries. Most of the standard C library string functions have DwString counterparts in MIME++. These functions all start with "Dw", and include DwStrcpy(), DwStrcmp(), DwStrcasecmp(), and so on. In addition, the equality operators and assignment operators work as expected. If you have used string classes from other libraries, you will find DwString fairly intuitive. The following sections describe how to create, parse, and modify a message. You should also look at the example programs included with the distribution. These example programs are well-commented and use wrapper classes. The wrapper classes BasicMessage, MultipartMessage, and MessageWithAttachments, are designed with three purposes in mind. First, if your requirements are very modest -- say you just want to send a few files as attachments -- then you may find these classes to be adequate for your needs, and you will not have to learn the MIME++ library classes. Second, wrapper classes are the recommended way to use MIME++. You should consider starting with these classes and customizing them for your own application. Using wrapper classes will simplify the use of the MIME++ library, but will also help to shield your application from future changes in the MIME++ library. Third, these classes provide excellent examples for how to use the MIME++ library classes. The rest of this tutorial focuses on the library classes themselves. 2. Creating a Message Creating a message with MIME++ involves instantiating a DwMessage object, setting values for its parts, and assembling the message into its final string representation. The following simple example shows how to accomplish this. void SendMessage( const char* aTo, const char* aFrom, const char* aSubject, const char* aBody) { // Create an empty message DwMessage msg; // Set the header fields. // [ Note that a temporary DwString object is created for // the argument for FromString() using the // DwString::DwString(const char*) constructor. ] DwHeaders& headers = msg.Headers(); headers.MessageId().CreateDefault(); headers.Date().FromCalendarTime(time(NULL)); //current date, time headers.To().FromString(aTo); headers.From().FromString(aFrom); headers.Subject().FromString(aSubject); // Set the message body msg.Body().FromString(aBody); // Assemble the message from its parts msg.Assemble(); // Finally, send it. In this example, just print it to the // cout stream. cout << msg.AsString(); } In this example, we set the fields 'Message-Id', 'Date', 'To', 'From', and 'Subject', which are all documented in RFC-822. The MIME++ class DwHeaders directly supports all header fields documented in RFC-822, RFC-2045, and RFC-1036. To access the field-body for any one these fields, use the member function from DwHeaders that has a name corresponding to the field-name for that field. The correspondence between a field-name and the name of the member function in DwHeaders is consistent: hyphens are dropped and the first character after the hyphen is capitalized. Thus, field-name Content-type in RFC-1521 corresponds to the member function name ContentType. These field-body access functions create an empty field in the headers if that field does not already exist. To check if a particular field exists already, DwHeaders provides member functions HasXxxxx(); for example, HasSender(), HasMimeVersion(), or HasXref() will indicate whether the DwHeaders object has a 'Sender' field, a 'MIME-Version' field, or an 'Xref' field, respectively. In the example, we used the FromString() member function of DwMessageComponent to set the string representation of the field-bodies. This is the simplest way to set the contents of a DwFieldBody object. Many of the field-bodies also have a broken-down represenation, and it is possible to set the parts of the broken-down representation. Consider, for example, the DwDateTime class, which represents the date-time element of the BNF grammar specified in RFC-822. In the example above, we did not set the string representation -- that would be more difficult and error prone. Instead we set the contents from the time_t value returned from a call to the ANSI C function time(). The DwDateTime class also contains member functions for setting individual attributes. For example, we could have used the following code: DwDateTime& date = msg.Headers().Date(); time_t t = time(NULL); struct tm stm = *localtime(&t); date.SetYear(stm.tm_year); date.SetMonth(stm.tm_mon); date.SetDay(stm.tm_mday); date.SetHour(stm.tm_hour); date.SetMinute(stm.tm_min); 3. Parsing a Message Parsing a received message with MIME++ involves instantiating a DwMessage object, setting its string representation to contain the message, and then calling the Parse() member function of the DwMessage object. The following simple example shows how to accomplish this. void ParseMessage(DwString& aMessageStr) { // Create a message object // We can set the message's string representation directly from the // constructor, as in the uncommented version. Or, we can use the // default constructor and set its string representation using // the member function DwMessage::FromString(), as in the // commented version. DwMessage msg(aMessageStr); // Alternate technique: // DwMessage msg; // Default constructor // msg.FromString(aMessageStr); // Set its string representation // Execute the parse method, which will create the broken-down // representation (the tree representation, if you recall) msg.Parse(); // Print some of the header fields, just to show how it's done // Date field. First check if the field exists, since // DwHeaders::Date() will create it if is not found. if (msg.Headers().HasDate()) { cout << "Date of message is " << msg.Headers().Date().AsString() << '\n'; } // From field. Here we access the broken-down field body, too, // to get the full name (which may be empty), the local part, // and the domain of the first mailbox. (The 'From' field can // have a list of mailboxes). if (msg.Headers().HasFrom()) { DwMailboxList& from = msg.Headers().From(); cout << "Message is from "; // Get first mailbox, then iterate through the list int isFirst = 1; DwMailbox* mb = from.FirstMailbox(); while (mb) { if (isFirst) { isFirst = 0; } else { cout << ", "; } DwString& fullName = mb->FullName(); if (fullName != "") { cout << fullName << '\n'; } else { // Apparently, there is no full name, so use the email // address cout << mb->LocalPart() << '@' << mb->Domain() << '\n'; } mb = mb->Next(); } } // Finally, print the message body, just to show how the body is // retrieved. cout << msg.Body().AsString() << '\n'; } Once you have parsed the message, you can access any of its parts. The field-bodies of well-known header fields can be accessed by calling member functions of DwHeaders. Some examples follow. DwMediaType& contType = msg.Headers().ContentType(); DwMechanism& cte = msg.Headers().ContentTransferEncoding(); DwDateTime& date = msg.Headers().Date(); The various subclasses of DwFieldBody, including DwMediaType, DwMechanism, and DwDateTime above, have member functions that allow you to access the parts of the field-body. For example, DwMediaType has member functions to allow you to access its type, subtype, and parameters. If the message is a multipart message, you may access the body parts by calling member functions of the class DwBody. See the example code in multipar.cpp for an example of how to do this. 4. Modifying a Message Modifying a message combines the procedures of parsing a message and creating a message. First, parse the message, as explained above. Then set the values of the components -- field-bodies, new fields, new body parts, or what have you -- that you wish to modify. Finally, call the Assemble() member function of the DwMessage object to reassemble the message. You can then access the modified message by calling DwMessage::AsString(). These final steps are the same as those involved in creating a new message. 5. Customizing MIME++ Classes MIME++ has been designed to be easily customizable. Typically, you customize C++ library classes through inheritance. MIME++ allows you to create subclasses of most of its library classes in order to change their behavior. MIME++ also includes certain 'hooks', which make it far easier to customize certain parts of the library. The most common customization is that of changing the way header fields are dealt with. This could include adding the ability to handle certain non-standard header fields, or to change the way the field-bodies of certain standard header fields are interpreted or parsed. As an example of the former customization, you may want to add the 'X-status' field or 'X-sender' field to your messages. As an example of the latter, you may want to change DwMediaType so that it will handle other MIME subtypes. Let's begin with the latter situation -- that of subclassing DwMediaType. Obviously, you will have to become familiar with DwMediaType and its superclasses before you change its behavior. Then, at a minimum, you will want to provide your own implementation of the virtual member functions Parse() and Assemble(). Once you feel comfortable with the behavior of the behavior of your new class -- call it MyMediaType -- you will have to take the right steps to ensure that the MIME++ library internal routines will create objects of type MyMediaType, and not DwMediaType. There are three such steps. First, define a function NewMyMediaType(), matching the prototype DwMediaType* NewMyMediaType( const DwString& aStr, DwMessage* aParent) that creates a new instance of MyMediaType and returns it. Set the static data member DwMediaType::sNewMediaType to point to this function. DwMediaType::sNewMediaType is normally NULL, meaning that no user-defined function is available. When you set this static data member, however, MIME++'s internal routines will call your own function, and will therefore be able to create instances of your subclass. Second, make sure you have reimplemented the virtual function DwMediaType::Clone() to return a clone of your own subclassed object. Clone() serves as a 'virtual constructor'. (See the discussion of virtual constructors in Stroustrup's _The C++ Programming Language_, 2nd Ed). Third, you should define a function CreateFieldBody(), matching the prototype DwFieldBody* CreateFieldBody( const DwString& aFieldName, const DwString& aFieldBody, DwMessageComponent* aParent) that returns an object of a subclass of DwFieldBody. (DwFieldBody is a superclass of MyMediaType). CreateFieldBody() is similar to the NewMyMediaType() function already described, except that its first argument supplies the field-name for the particular field currently being handled by MIME++. CreateFieldBody() should examine the field-name, create an object of the appropriate subclass of DwFieldBody, and return a pointer to the object. In this particular case, you need to make sure that when the field-name is 'Content-Type' you return an object of the class MyMediaType. Set the hook for CreateFieldBody() setting the static data member DwField::sCreateFieldBody to point to your CreateFieldBody() function. DwField::sCreateFieldBody is normally NULL when no user function is provided. These three steps are sufficient to ensure that your subclass of DwMediaType is integrated with the other MIME++ classes. The other customization task mentioned above is that of adding support for a non-standard header field. There is a simple way to do this, and a way that involves creating a subclass of DwHeaders. You can access any header field by calling DwHeaders's member functions. In fact, you can iterate over all the header fields if you would like. Therefore, the really simple way is just to not change anything and just use existing member functions. The relevant functions include DwHeaders::HasField(), which will return a boolean value indicating if the header has the specified field, and DwHeaders::FieldBody(), which will return the DwFieldBody object associated with a specified field. [ Note that DwHeaders::FieldBody() will create a field if it is not found. ] The default DwFieldBody subclass, which applies to all header fields not recognized by MIME++, is DwText, which is suitable for the unstructured field-bodies described in RFC-822 such as 'Subject', 'Comments', and so on. If a DwText object is suitable for your non-standard header field, then you don't have to do anything at all. Suppose, however, that you want an object of your own subclass of DwFieldBody, say StatusFieldBody, to be attached to the 'X-status' field. In this case, you will need to set the hook DwField::sCreateFieldBody as discussed above. Your CreateFieldBody() function should return an instance of StatusFieldBody whenever the field-name is 'X-status'. Finally, while you can access any header field using DwHeaders's member functions, you may want to create your own subclass of DwHeaders for some reason or other -- maybe to add a convenience function to access the 'X-status' header field. To ensure that your new class is integrated with the library routines, you basically follow steps 1 and 2 above for subclassing DwFieldBody. First, define a function NewMyHeaders() and set the static data member DwHeaders::sNewHeaders to point to your function. Second, make sure you have reimplemented the virtual function DwHeaders::Clone() to return an instance of your subclass. Step 3 for subclassing DwFieldBody does not apply when subclassing DwHeaders. 6. Getting Help I will try to help anyone who needs help specific to MIME++. I won't try to answer general questions about C++ that could be answered by any C++ expert. Bug reports will receive the highest priority. Other questions about how to do something I will try to answer in time, but I ask for your patience. If you have any comments -- perhaps maybe you know of a better way to do something -- please send them. My preferred email is dwsauder@fwb.gulf.net, but dwsauder@tasc.com is also acceptable. Good luck! mimelib1-1.1.4/mimelib/headers.cpp0000644000175000017500000004703411175345261016366 0ustar resivoresivo//============================================================================= // File: headers.cpp // Contents: Definitions for DwHeaders // Maintainer: Doug Sauder // WWW: http://www.fwb.gulf.net/~dwsauder/mimepp.html // // Copyright (c) 1996, 1997 Douglas W. Sauder // All rights reserved. // // IN NO EVENT SHALL DOUGLAS W. SAUDER BE LIABLE TO ANY PARTY FOR DIRECT, // INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF // THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF DOUGLAS W. SAUDER // HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // DOUGLAS W. SAUDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT // NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A // PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" // BASIS, AND DOUGLAS W. SAUDER HAS NO OBLIGATION TO PROVIDE MAINTENANCE, // SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. // //============================================================================= #define DW_IMPLEMENTATION #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include class DwHeadersParser { friend class DwHeaders; private: DwHeadersParser(const DwString&); void Rewind(); void NextField(DwString*); const DwString mString; size_t mPos; }; DwHeadersParser::DwHeadersParser(const DwString& aStr) : mString(aStr) { mPos = 0; } void DwHeadersParser::Rewind() { mPos = 0; } void DwHeadersParser::NextField(DwString* aStr) { if (!aStr) { return; } const char* buf = mString.data(); size_t bufEnd = mString.length(); size_t pos = mPos; size_t start = pos; size_t len = 0; while (pos < bufEnd) { if (buf[pos] == '\n' && pos+1 < bufEnd && buf[pos+1] != ' ' && buf[pos+1] != '\t') { ++len; ++pos; break; } ++len; ++pos; } *aStr = mString.substr(start, len); mPos = pos; } //============================================================================ const char* const DwHeaders::sClassName = "DwHeaders"; DwHeaders* (*DwHeaders::sNewHeaders)(const DwString&, DwMessageComponent*) = 0; DwHeaders* DwHeaders::NewHeaders(const DwString& aStr, DwMessageComponent* aParent) { if (sNewHeaders) { return sNewHeaders(aStr, aParent); } else { return new DwHeaders(aStr, aParent); } } DwHeaders::DwHeaders() { mFirstField = 0; mLastField = 0; mClassId = kCidHeaders; mClassName = sClassName; } DwHeaders::DwHeaders(const DwHeaders& aHeader) : DwMessageComponent(aHeader) { mFirstField = 0; mLastField = 0; if (aHeader.mFirstField) { CopyFields(aHeader.mFirstField); } mClassId = kCidHeaders; mClassName = sClassName; } DwHeaders::DwHeaders(const DwString& aStr, DwMessageComponent* aParent) : DwMessageComponent(aStr, aParent) { mFirstField = 0; mLastField = 0; mClassId = kCidHeaders; mClassName = sClassName; } DwHeaders::~DwHeaders() { if (mFirstField) { DeleteAllFields(); } } const DwHeaders& DwHeaders::operator = (const DwHeaders& aHeader) { if (this == &aHeader) return *this; DwMessageComponent::operator = (aHeader); if (mFirstField) { DeleteAllFields(); } if (aHeader.mFirstField) { CopyFields(aHeader.mFirstField); } if (mParent) { mParent->SetModified(); } return *this; } void DwHeaders::Parse() { mIsModified = 0; DwHeadersParser parser(mString); DwString str; parser.NextField(&str); while (!str.empty()) { DwField* field = DwField::NewField(str, this); field->Parse(); _AddField(field); parser.NextField(&str); } } void DwHeaders::Assemble() { if (!mIsModified) return; mString = ""; DwField* field = FirstField(); while (field) { field->Assemble(); mString += field->AsString(); field = field->Next(); } // We DwEntityParser skips the empty line separating the headers // from the body, so why should be add it here? //mString += DW_EOL; mIsModified = 0; } DwMessageComponent* DwHeaders::Clone() const { return new DwHeaders(*this); } DwFieldBody& DwHeaders::FieldBody(const DwString& aFieldName) { assert(!aFieldName.empty()); // First, search for field DwField* field = FindField(aFieldName); // If the field is not found, create the field and its field body if (field == 0) { field = DwField::NewField("", this); field->SetFieldNameStr(aFieldName); DwFieldBody* fieldBody = DwField::CreateFieldBody(aFieldName, "", field); field->SetFieldBody(fieldBody); AddField(field); } // Get the field body DwFieldBody* fieldBody = field->FieldBody(); // If it does not exist, create it if (fieldBody == 0) { fieldBody = DwField::CreateFieldBody(aFieldName, "", field); field->SetFieldBody(fieldBody); SetModified(); } return *fieldBody; } std::vector DwHeaders::AllFieldBodies(const DwString& aFieldName) { assert(!aFieldName.empty()); // First, search for field DwField* field = FindField(aFieldName); // If the field is not found, create the field and its field body if (field == 0) { field = DwField::NewField("", this); field->SetFieldNameStr(aFieldName); DwFieldBody* fieldBody = DwField::CreateFieldBody(aFieldName, "", field); field->SetFieldBody(fieldBody); AddField(field); } std::vector v; for ( ; field; field = field->Next() ) { if (DwStrcasecmp(field->FieldNameStr(), aFieldName) == 0) { // Get the field body DwFieldBody* fieldBody = field->FieldBody(); // If it does not exist, create it if (fieldBody == 0) { fieldBody = DwField::CreateFieldBody(aFieldName, "", field); field->SetFieldBody(fieldBody); SetModified(); } v.push_back( fieldBody ); } } return v; } int DwHeaders::NumFields() const { int count = 0; DwField* field = mFirstField; while (field) { ++count; field = field->Next(); } return count; } DwField* DwHeaders::FindField(const char* aFieldName) const { assert(aFieldName != 0); if (aFieldName == 0) return 0; DwField* field = mFirstField; while (field) { if (DwStrcasecmp(field->FieldNameStr(), aFieldName) == 0) { break; } field = field->Next(); } return field; } DwField* DwHeaders::FindField(const DwString& aFieldName) const { DwField* field = mFirstField; while (field) { if (DwStrcasecmp(field->FieldNameStr(), aFieldName) == 0) { break; } field = field->Next(); } return field; } void DwHeaders::AddOrReplaceField(DwField* aField) { assert(aField != 0); if (aField == 0) return; SetModified(); const DwString& fieldName = aField->FieldNameStr(); DwField* prevField = 0; DwField* field = mFirstField; while (field) { if (DwStrcasecmp(field->FieldNameStr(), fieldName) == 0) { break; } prevField = field; field = field->Next(); } // Field was not found, so just add it if (!field) { _AddField(aField); } // Field was found. Replace the old one with the new one. else { if (prevField) { prevField->SetNext(aField); } else { mFirstField = aField; } aField->SetNext(field->Next()); // Check whether we've replaced the last field if ( !aField->Next() ) mLastField = aField; delete field; } } void DwHeaders::AddField(DwField* aField) { assert(aField != 0); if (aField == 0) return; _AddField(aField); SetModified(); } void DwHeaders::AddFieldAt(int aPos, DwField* aField) { assert(aField != 0); if (aField == 0) return; SetModified(); // Special case: empty list if (mFirstField == 0) { aField->SetNext(0); mFirstField = aField; mLastField = aField; return; } // Special case: aPos == 1 --> add at beginning if (aPos == 1) { aField->SetNext(mFirstField); mFirstField = aField; return; } // aPos == 0 --> at at end if (aPos == 0) { _AddField(aField); return; } int count = 2; DwField* field = mFirstField; while (field->Next() && count < aPos) { field = field->Next(); ++count; } aField->SetNext(field->Next()); field->SetNext(aField); // Check whether we've a new last field if ( !aField->Next() ) mLastField = aField; } void DwHeaders::RemoveField(DwField* aField) { DwField* prevField = 0; DwField* field = mFirstField; while (field) { if (field == aField) { break; } prevField = field; field = field->Next(); } // If we found the field... if (field) { if (prevField == 0) { mFirstField = field->Next(); } else { prevField->SetNext(field->Next()); } // Check whether we've removed the last field if ( field == mLastField ) mLastField = prevField; field->SetNext(0); SetModified(); } } void DwHeaders::DeleteAllFields() { DwField* field = mFirstField; while (field) { DwField* nextField = field->Next(); delete field; field = nextField; } mFirstField = 0; mLastField = 0; } void DwHeaders::_AddField(DwField* aField) { if (aField == 0) return; // Add field with setting is-modified flag for header aField->SetParent(this); // Special case: empty list if (mFirstField == 0) { mFirstField = aField; mLastField = aField; return; } mLastField->SetNext(aField); mLastField = aField; } void DwHeaders::CopyFields(DwField* aFirst) { DwField* field = aFirst; DwField* newField; while (field) { newField = (DwField*) field->Clone(); _AddField(newField); field = field->Next(); } } DwBool DwHeaders::HasBcc() const { return FindField("bcc") ? 1 : 0; } DwBool DwHeaders::HasCc() const { return FindField("cc") ? 1 : 0; } DwBool DwHeaders::HasComments() const { return FindField("comments") ? 1 : 0; } DwBool DwHeaders::HasDate() const { return FindField("date") ? 1 : 0; } DwBool DwHeaders::HasEncrypted() const { return FindField("encrypted") ? 1 : 0; } DwBool DwHeaders::HasFrom() const { return FindField("from") ? 1 : 0; } DwBool DwHeaders::HasInReplyTo() const { return FindField("in-reply-to") ? 1 : 0; } DwBool DwHeaders::HasKeywords() const { return FindField("keywords") ? 1 : 0; } DwBool DwHeaders::HasMessageId() const { return FindField("message-id") ? 1 : 0; } DwBool DwHeaders::HasReceived() const { return FindField("received") ? 1 : 0; } DwBool DwHeaders::HasReferences() const { return FindField("references") ? 1 : 0; } DwBool DwHeaders::HasReplyTo() const { return FindField("reply-to") ? 1 : 0; } DwBool DwHeaders::HasResentBcc() const { return FindField("resent-bcc") ? 1 : 0; } DwBool DwHeaders::HasResentCc() const { return FindField("resent-cc") ? 1 : 0; } DwBool DwHeaders::HasResentDate() const { return FindField("resent-date") ? 1 : 0; } DwBool DwHeaders::HasResentFrom() const { return FindField("resent-from") ? 1 : 0; } DwBool DwHeaders::HasResentMessageId() const { return FindField("resent-message-id") ? 1 : 0; } DwBool DwHeaders::HasResentReplyTo() const { return FindField("resent-reply-to") ? 1 : 0; } DwBool DwHeaders::HasResentSender() const { return FindField("resent-sender") ? 1 : 0; } DwBool DwHeaders::HasResentTo() const { return FindField("resent-to") ? 1 : 0; } DwBool DwHeaders::HasReturnPath() const { return FindField("return-path") ? 1 : 0; } DwBool DwHeaders::HasSender() const { return FindField("sender") ? 1 : 0; } DwBool DwHeaders::HasSubject() const { return FindField("subject") ? 1 : 0; } DwBool DwHeaders::HasTo() const { return FindField("to") ? 1 : 0; } DwBool DwHeaders::HasApproved() const { return FindField("approved") ? 1 : 0; } DwBool DwHeaders::HasControl() const { return FindField("control") ? 1 : 0; } DwBool DwHeaders::HasDistribution() const { return FindField("distribution") ? 1 : 0; } DwBool DwHeaders::HasExpires() const { return FindField("expires") ? 1 : 0; } DwBool DwHeaders::HasFollowupTo() const { return FindField("followup-to") ? 1 : 0; } DwBool DwHeaders::HasLines() const { return FindField("lines") ? 1 : 0; } DwBool DwHeaders::HasNewsgroups() const { return FindField("newsgroups") ? 1 : 0; } DwBool DwHeaders::HasOrganization() const { return FindField("organization") ? 1 : 0; } DwBool DwHeaders::HasPath() const { return FindField("path") ? 1 : 0; } DwBool DwHeaders::HasSummary() const { return FindField("summary") ? 1 : 0; } DwBool DwHeaders::HasXref() const { return FindField("xref") ? 1 : 0; } DwBool DwHeaders::HasContentDescription() const { return FindField("content-description") ? 1 : 0; } DwBool DwHeaders::HasContentId() const { return FindField("content-id") ? 1 : 0; } DwBool DwHeaders::HasContentTransferEncoding() const { return FindField("content-transfer-encoding") ? 1 : 0; } DwBool DwHeaders::HasCte() const { return FindField("content-transfer-encoding") ? 1 : 0; } DwBool DwHeaders::HasContentType() const { return FindField("content-type") ? 1 : 0; } DwBool DwHeaders::HasMimeVersion() const { return FindField("mime-version") ? 1 : 0; } DwBool DwHeaders::HasContentDisposition() const { return FindField("content-disposition") ? 1 : 0; } DwBool DwHeaders::HasField(const char* aFieldName) const { return FindField(aFieldName) ? 1 : 0; } DwBool DwHeaders::HasField(const DwString& aFieldName) const { return FindField(aFieldName) ? 1 : 0; } DwAddressList& DwHeaders::Bcc() { return (DwAddressList&) FieldBody("Bcc"); } DwAddressList& DwHeaders::Cc() { return (DwAddressList&) FieldBody("Cc"); } DwText& DwHeaders::Comments() { return (DwText&) FieldBody("Comments"); } DwDateTime& DwHeaders::Date() { return (DwDateTime&) FieldBody("Date"); } DwText& DwHeaders::Encrypted() { return (DwText&) FieldBody("Encrypted"); } DwMailboxList& DwHeaders::From() { return (DwMailboxList&) FieldBody("From"); } DwText& DwHeaders::InReplyTo() { return (DwText&) FieldBody("In-Reply-To"); } DwText& DwHeaders::Keywords() { return (DwText&) FieldBody("Keywords"); } DwMsgId& DwHeaders::MessageId() { return (DwMsgId&) FieldBody("Message-Id"); } DwText& DwHeaders::Received() { return (DwText&) FieldBody("Received"); } DwText& DwHeaders::References() { return (DwText&) FieldBody("References"); } DwAddressList& DwHeaders::ReplyTo() { return (DwAddressList&) FieldBody("Reply-To"); } DwAddressList& DwHeaders::ResentBcc() { return (DwAddressList&) FieldBody("Resent-Bcc"); } DwAddressList& DwHeaders::ResentCc() { return (DwAddressList&) FieldBody("Resent-Cc"); } DwDateTime& DwHeaders::ResentDate() { return (DwDateTime&) FieldBody("Resent-Date"); } DwMailboxList& DwHeaders::ResentFrom() { return (DwMailboxList&) FieldBody("Resent-From"); } DwMsgId& DwHeaders::ResentMessageId() { return (DwMsgId&) FieldBody("Resent-Message-Id"); } DwAddressList& DwHeaders::ResentReplyTo() { return (DwAddressList&) FieldBody("Resent-Reply-To"); } DwMailbox& DwHeaders::ResentSender() { return (DwMailbox&) FieldBody("Resent-Sender"); } DwAddressList& DwHeaders::ResentTo() { return (DwAddressList&) FieldBody("Resent-To"); } DwAddress& DwHeaders::ReturnPath() { return (DwAddress&) FieldBody("Return-Path"); } DwMailbox& DwHeaders::Sender() { return (DwMailbox&) FieldBody("Sender"); } DwText& DwHeaders::Subject() { return (DwText&) FieldBody("Subject"); } DwAddressList& DwHeaders::To() { return (DwAddressList&) FieldBody("To"); } DwText& DwHeaders::Approved() { return (DwText&) FieldBody("Approved"); } DwText& DwHeaders::Control() { return (DwText&) FieldBody("Control"); } DwText& DwHeaders::Distribution() { return (DwText&) FieldBody("Distribution"); } DwText& DwHeaders::Expires() { return (DwText&) FieldBody("Expires"); } DwText& DwHeaders::FollowupTo() { return (DwText&) FieldBody("Followup-To"); } DwText& DwHeaders::Lines() { return (DwText&) FieldBody("Lines"); } DwText& DwHeaders::Newsgroups() { return (DwText&) FieldBody("Newsgroups"); } DwText& DwHeaders::Organization() { return (DwText&) FieldBody("Organization"); } DwText& DwHeaders::Path() { return (DwText&) FieldBody("Path"); } DwText& DwHeaders::Summary() { return (DwText&) FieldBody("Summary"); } DwText& DwHeaders::Xref() { return (DwText&) FieldBody("Xref"); } DwText& DwHeaders::ContentDescription() { return (DwText&) FieldBody("Content-Description"); } DwMsgId& DwHeaders::ContentId() { return (DwMsgId&) FieldBody("Content-Id"); } DwMechanism& DwHeaders::ContentTransferEncoding() { return (DwMechanism&) FieldBody("Content-Transfer-Encoding"); } DwMechanism& DwHeaders::Cte() { return (DwMechanism&) FieldBody("Content-Transfer-Encoding"); } DwMediaType& DwHeaders::ContentType() { return (DwMediaType&) FieldBody("Content-Type"); } DwText& DwHeaders::MimeVersion() { return (DwText&) FieldBody("MIME-Version"); } DwDispositionType& DwHeaders::ContentDisposition() { return (DwDispositionType&) FieldBody("Content-Disposition"); } #if defined (DW_DEBUG_VERSION) void DwHeaders::PrintDebugInfo(std::ostream& aStrm, int aDepth) const { aStrm << "---------------- Debug info for DwHeaders class ----------------\n"; _PrintDebugInfo(aStrm); int depth = aDepth - 1; depth = (depth >= 0) ? depth : 0; if (aDepth == 0 || depth > 0) { DwField* field = mFirstField; while (field) { field->PrintDebugInfo(aStrm, depth); field = (DwField*) field->Next(); } } } #else void DwHeaders::PrintDebugInfo(std::ostream& , int ) const {} #endif // defined (DW_DEBUG_VERSION) #if defined (DW_DEBUG_VERSION) void DwHeaders::_PrintDebugInfo(std::ostream& aStrm) const { DwMessageComponent::_PrintDebugInfo(aStrm); aStrm << "Fields: "; int count = 0; DwField* field = mFirstField; while (field) { if (count > 0) aStrm << ' '; aStrm << field->ObjectId(); field = (DwField*) field->Next(); ++count; } aStrm << '\n'; } #else void DwHeaders::_PrintDebugInfo(std::ostream& ) const {} #endif // defined (DW_DEBUG_VERSION) void DwHeaders::CheckInvariants() const { #if defined (DW_DEBUG_VERSION) DwMessageComponent::CheckInvariants(); DwField* field = mFirstField; while (field) { field->CheckInvariants(); assert((DwMessageComponent*) this == field->Parent()); field = (DwField*) field->Next(); } #endif // defined (DW_DEBUG_VERSION) } mimelib1-1.1.4/mimelib/entity.cpp0000644000175000017500000001755511175345261016274 0ustar resivoresivo//============================================================================= // File: entity.cpp // Contents: Definitions for DwEntity // Maintainer: Doug Sauder // WWW: http://www.fwb.gulf.net/~dwsauder/mimepp.html // // Copyright (c) 1996, 1997 Douglas W. Sauder // All rights reserved. // // IN NO EVENT SHALL DOUGLAS W. SAUDER BE LIABLE TO ANY PARTY FOR DIRECT, // INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF // THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF DOUGLAS W. SAUDER // HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // DOUGLAS W. SAUDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT // NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A // PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" // BASIS, AND DOUGLAS W. SAUDER HAS NO OBLIGATION TO PROVIDE MAINTENANCE, // SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. // //============================================================================= #define DW_IMPLEMENTATION #include #include #include #include #include #include #include #include class DwEntityParser { friend class DwEntity; private: DwEntityParser(const DwString&); void Parse(); const DwString mString; DwString mHeaders; DwString mBody; }; DwEntityParser::DwEntityParser(const DwString& aStr) : mString(aStr) { Parse(); } void DwEntityParser::Parse() { const char* buf = mString.data(); size_t bufEnd = mString.length(); size_t pos = 0; size_t headersStart = 0; size_t headersLength = 0; size_t lineStart = pos; DwBool isHeaderLine = DwFalse; // If first character is a LF (ANSI C or UNIX) // or if first two characters are CR LF (MIME or DOS), // there are no headers. if (pos < bufEnd && buf[pos] != '\n' && ! (buf[pos] == '\r' && pos+1 < bufEnd && buf[pos+1] == '\n')) { while (pos < bufEnd) { // End of line marked by LF if (buf[pos] == '\n') { ++pos; if (!isHeaderLine) { pos = lineStart; break; } // Check for LF LF else if (pos < bufEnd && buf[pos] == '\n') { break; } lineStart = pos; isHeaderLine = DwFalse; } // End of line marked by CRLF else if (buf[pos] == '\r' && pos+1 < bufEnd && buf[pos+1] == '\n') { pos += 2; if (!isHeaderLine) { pos = lineStart; break; } // Check for CR LF CR LF else if (pos+1 < bufEnd && buf[pos] == '\r' && buf[pos+1] == '\n') { break; } lineStart = pos; isHeaderLine = DwFalse; } else if (buf[pos] == ':') { isHeaderLine = DwTrue; ++pos; } else if (pos == lineStart && (buf[pos] == ' ' || buf[pos] == '\t')) { isHeaderLine = DwTrue; ++pos; } else { ++pos; } } } headersLength = pos; mHeaders = mString.substr(headersStart, headersLength); // Skip blank line // LF (ANSI C or UNIX) if (pos < bufEnd && buf[pos] == '\n') { ++pos; } // CR LF (MIME or DOS) else if (pos < bufEnd && buf[pos] == '\r' && pos+1 < bufEnd && buf[pos+1] == '\n') { pos += 2; } size_t bodyStart = pos; size_t bodyLength = mString.length() - bodyStart; mBody = mString.substr(bodyStart, bodyLength); } //========================================================================== const char* const DwEntity::sClassName = "DwEntity"; DwEntity::DwEntity() { mHeaders = DwHeaders::NewHeaders("", this); ASSERT(mHeaders != 0); mBody = DwBody::NewBody("", this); ASSERT(mBody != 0); mClassId = kCidEntity; mClassName = sClassName; mBodySize = -1; } DwEntity::DwEntity(const DwEntity& aEntity) : DwMessageComponent(aEntity) { mHeaders = (DwHeaders*) aEntity.mHeaders->Clone(); ASSERT(mHeaders != 0); mHeaders->SetParent(this); mBody = (DwBody*) aEntity.mBody->Clone(); ASSERT(mBody != 0); mBody->SetParent(this); mClassId = kCidEntity; mClassName = sClassName; mBodySize = aEntity.mBodySize; } DwEntity::DwEntity(const DwString& aStr, DwMessageComponent* aParent) : DwMessageComponent(aStr, aParent) { mHeaders = DwHeaders::NewHeaders("", this); ASSERT(mHeaders != 0); mBody = DwBody::NewBody("", this); ASSERT(mBody != 0); mClassId = kCidEntity; mClassName = sClassName; mBodySize = -1; } DwEntity::~DwEntity() { delete mHeaders; delete mBody; } const DwEntity& DwEntity::operator = (const DwEntity& aEntity) { if (this == &aEntity) return *this; DwMessageComponent::operator = (aEntity); // Note: Because of the derived assignment problem, we cannot use the // assignment operator for DwHeaders and DwBody in the following. delete mHeaders; mHeaders = (DwHeaders*) aEntity.mHeaders->Clone(); ASSERT(mHeaders != 0); mHeaders->SetParent(this); delete mBody; mBody = (DwBody*) aEntity.mBody->Clone(); ASSERT(mBody != 0); mBody->SetParent(this); if (mParent) { mParent->SetModified(); } return *this; } void DwEntity::Parse() { mIsModified = 0; DwEntityParser parser(mString); mHeaders->FromString(parser.mHeaders); mHeaders->Parse(); mBody->FromString(parser.mBody); mBody->Parse(); } void DwEntity::Assemble(DwHeaders& aHeaders, DwBody& aBody) { mString = ""; mString += aHeaders.AsString(); // DwEntityParser skips the line separating the headers from the // body. So it's neither part of DwHeaders, nor of DwBody // -> we need to readd it here: mString += DW_EOL; mString += aBody.AsString(); mIsModified = 0; } void DwEntity::Assemble() { if (!mIsModified) return; mBody->Assemble(); mHeaders->Assemble(); Assemble( *mHeaders, *mBody ); } DwHeaders& DwEntity::Headers() const { ASSERT(mHeaders != 0); return *mHeaders; } DwBody& DwEntity::Body() const { return *mBody; } int DwEntity::BodySize() const { if ( mBody->AsString().length() > 0 ) return mBody->AsString().length(); else if ( mBodySize > 0 ) return mBodySize; else return 0; } #if defined(DW_DEBUG_VERSION) void DwEntity::PrintDebugInfo(std::ostream& aStrm, int aDepth) const { aStrm << "------------ Debug info for DwEntity class ------------\n"; _PrintDebugInfo(aStrm); int depth = aDepth - 1; depth = (depth >= 0) ? depth : 0; if (aDepth == 0 || depth > 0) { mHeaders->PrintDebugInfo(aStrm, depth); mBody->PrintDebugInfo(aStrm, depth); } } #else void DwEntity::PrintDebugInfo(std::ostream& , int ) const {} #endif // defined(DW_DEBUG_VERSION) #if defined(DW_DEBUG_VERSION) void DwEntity::_PrintDebugInfo(std::ostream& aStrm) const { DwMessageComponent::_PrintDebugInfo(aStrm); aStrm << "Headers: " << mHeaders->ObjectId() << '\n'; aStrm << "Body: " << mBody->ObjectId() << '\n'; } #else void DwEntity::_PrintDebugInfo(std::ostream& ) const {} #endif // defined(DW_DEBUG_VERSION) void DwEntity::CheckInvariants() const { #if defined(DW_DEBUG_VERSION) DwMessageComponent::CheckInvariants(); mHeaders->CheckInvariants(); assert((DwMessageComponent*) this == mHeaders->Parent()); mBody->CheckInvariants(); assert((DwMessageComponent*) this == mBody->Parent()); #endif // defined(DW_DEBUG_VERSION) } mimelib1-1.1.4/mimelib/README0000644000175000017500000000056111175345261015121 0ustar resivoresivo This is the README for the mimelib library, which is based on the mimepp library by Doug Sauder . Since KDE uses a slightly patched version of mimepp, the author and the KDE Team agreed, that we rename it for use in KDE. But please report bugs, that you find in the code to Doug, since he still maintains the code. Stephan Kulow coolo@kde.org mimelib1-1.1.4/mimelib/mediatyp.cpp0000644000175000017500000003412211175345261016561 0ustar resivoresivo//============================================================================= // File: mediatyp.cpp // Contents: Definitions for DwMediaType // Maintainer: Doug Sauder // WWW: http://www.fwb.gulf.net/~dwsauder/mimepp.html // // Copyright (c) 1996, 1997 Douglas W. Sauder // All rights reserved. // // IN NO EVENT SHALL DOUGLAS W. SAUDER BE LIABLE TO ANY PARTY FOR DIRECT, // INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF // THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF DOUGLAS W. SAUDER // HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // DOUGLAS W. SAUDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT // NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A // PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" // BASIS, AND DOUGLAS W. SAUDER HAS NO OBLIGATION TO PROVIDE MAINTENANCE, // SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. // //============================================================================= #define DW_IMPLEMENTATION #include #include #include #include #include #include #include #include #include #include #include #include #include const char* const DwMediaType::sClassName = "DwMediaType"; DwMediaType* (*DwMediaType::sNewMediaType)(const DwString&, DwMessageComponent*) = 0; DwMediaType* DwMediaType::NewMediaType(const DwString& aStr, DwMessageComponent* aParent) { if (sNewMediaType) { return sNewMediaType(aStr, aParent); } else { return new DwMediaType(aStr, aParent); } } DwMediaType::DwMediaType() { mType = DwMime::kTypeNull; mSubtype = DwMime::kSubtypeNull; mFirstParameter = 0; mClassId = kCidMediaType; mClassName = sClassName; } DwMediaType::DwMediaType(const DwMediaType& aCntType) : DwFieldBody(aCntType), mTypeStr(aCntType.mTypeStr), mSubtypeStr(aCntType.mSubtypeStr), mBoundaryStr(aCntType.mBoundaryStr) { mType = aCntType.mType; mSubtype = aCntType.mSubtype; mFirstParameter = 0; if (aCntType.mFirstParameter) { CopyParameterList(aCntType.mFirstParameter); } mClassId = kCidMediaType; mClassName = sClassName; } DwMediaType::DwMediaType(const DwString& aStr, DwMessageComponent* aParent) : DwFieldBody(aStr, aParent) { mType = DwMime::kTypeNull; mSubtype = DwMime::kSubtypeNull; mFirstParameter = 0; mClassId = kCidMediaType; mClassName = sClassName; } DwMediaType::~DwMediaType() { if (mFirstParameter) { DeleteParameterList(); } } const DwMediaType& DwMediaType::operator = (const DwMediaType& aCntType) { if (this == &aCntType) return *this; DwFieldBody::operator = (aCntType); mType = aCntType.mType; mSubtype = aCntType.mSubtype; mTypeStr = aCntType.mTypeStr; mSubtypeStr = aCntType.mSubtypeStr; mBoundaryStr = aCntType.mBoundaryStr; if (mFirstParameter) { DeleteParameterList(); } if (aCntType.mFirstParameter) { CopyParameterList(aCntType.mFirstParameter); } if (mParent) { mParent->SetModified(); } return *this; } int DwMediaType::Type() const { return mType; } void DwMediaType::SetType(int aType) { mType = aType; TypeEnumToStr(); SetModified(); } const DwString& DwMediaType::TypeStr() const { return mTypeStr; } void DwMediaType::SetTypeStr(const DwString& aStr) { mTypeStr = aStr; TypeStrToEnum(); SetModified(); } int DwMediaType::Subtype() const { return mSubtype; } void DwMediaType::SetSubtype(int aSubtype) { mSubtype = aSubtype; SubtypeEnumToStr(); SetModified(); } const DwString& DwMediaType::SubtypeStr() const { return mSubtypeStr; } void DwMediaType::SetSubtypeStr(const DwString& aStr) { mSubtypeStr = aStr; SubtypeStrToEnum(); SetModified(); } const DwString& DwMediaType::Boundary() const { // Implementation note: this member function is const, which // forbids us from assigning to mBoundaryStr. The following // trick gets around this. (ANSI implementations could use the // "mutable" declaration). DwMediaType* _this = (DwMediaType*) this; _this->mBoundaryStr = ""; DwParameter* param = mFirstParameter; while (param) { if (DwStrcasecmp(param->Attribute(), "boundary") == 0) { // Boundary parameter found. Return its value. _this->mBoundaryStr = param->Value(); break; } param = param->Next(); } return mBoundaryStr; } void DwMediaType::SetBoundary(const DwString& aStr) { mBoundaryStr = aStr; // Search for boundary parameter in parameter list. If found, set its // value. DwParameter* param = mFirstParameter; while (param) { if (DwStrcasecmp(param->Attribute(), "boundary") == 0) { param->SetValue(mBoundaryStr); return; } param = param->Next(); } // Boundary parameter not found. Add it. param = DwParameter::NewParameter("", 0); param->SetAttribute("boundary"); param->SetValue(aStr); AddParameter(param); } void DwMediaType::CreateBoundary(unsigned aLevel) { // Create a random printable string and set it as the boundary parameter static const char c[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; const int cLen = 64; char buf[80]; strcpy(buf, "Boundary-"); int pos = strlen(buf); int n = aLevel / 10; buf[pos++] = (n % 10) + '0'; n = aLevel; buf[pos++] = (n % 10) + '0'; buf[pos++] = '='; buf[pos++] = '_'; DwUint32 r = (DwUint32) time(0); buf[pos++] = c[r % cLen]; r /= cLen; buf[pos++] = c[r % cLen]; r /= cLen; buf[pos++] = c[r % cLen]; r /= cLen; buf[pos++] = c[r % cLen]; r /= cLen; buf[pos++] = c[r % cLen]; for (int i=0; i < 2; ++i) { r = rand(); buf[pos++] = c[r % cLen]; r >>= 6; buf[pos++] = c[r % cLen]; r >>= 6; buf[pos++] = c[r % cLen]; r >>= 6; buf[pos++] = c[r % cLen]; r >>= 6; buf[pos++] = c[r % cLen]; } buf[pos] = 0; SetBoundary(buf); } const DwString& DwMediaType::Name() const { // Implementation note: this member function is const, which // forbids us from assigning to mNameStr. The following // trick gets around this. (ANSI implementations could use the // "mutable" declaration). DwMediaType* _this = (DwMediaType*) this; _this->mNameStr = ""; DwParameter* param = mFirstParameter; while (param) { if (DwStrcasecmp(param->Attribute(), "name") == 0) { // Name parameter found. Return its value. _this->mNameStr = param->Value(); break; } param = param->Next(); } return mNameStr; } void DwMediaType::SetName(const DwString& aStr) { mNameStr = aStr; // Search for name parameter in parameter list. If found, set its // value. DwParameter* param = mFirstParameter; while (param) { if (DwStrcasecmp(param->Attribute(), "name") == 0) { param->SetValue(mNameStr); return; } param = param->Next(); } // Name parameter not found. Add it. param = DwParameter::NewParameter("", 0); param->SetAttribute("name"); param->SetValue(aStr); AddParameter(param); } DwParameter* DwMediaType::FirstParameter() const { return mFirstParameter; } void DwMediaType::AddParameter(DwParameter* aParam) { _AddParameter(aParam); SetModified(); } void DwMediaType::_AddParameter(DwParameter* aParam) { if (!mFirstParameter) { mFirstParameter = aParam; } else { DwParameter* cur = mFirstParameter; DwParameter* next = cur->Next(); while (next) { cur = next; next = cur->Next(); } cur->SetNext(aParam); } aParam->SetParent(this); } void DwMediaType::Parse() { mIsModified = 0; mTypeStr = ""; mSubtypeStr = ""; mType = DwMime::kTypeNull; mSubtype = DwMime::kSubtypeNull; if (mFirstParameter) { DeleteParameterList(); } if (mString.length() == 0) return; DwRfc1521Tokenizer tokenizer(mString); // Get type. int found = 0; while (!found && tokenizer.Type() != eTkNull) { if (tokenizer.Type() == eTkToken) { mTypeStr = tokenizer.Token(); found = 1; } ++tokenizer; } // Get '/' found = 0; while (!found && tokenizer.Type() != eTkNull) { if (tokenizer.Type() == eTkTspecial && tokenizer.Token()[0] == '/') { found = 1; } ++tokenizer; } // Get subtype found = 0; while (!found && tokenizer.Type() != eTkNull) { if (tokenizer.Type() == eTkToken) { mSubtypeStr = tokenizer.Token(); found = 1; } ++tokenizer; } // Get parameters DwTokenString tokenStr(mString); while (1) { // Get ';' found = 0; while (!found && tokenizer.Type() != eTkNull) { if (tokenizer.Type() == eTkTspecial && tokenizer.Token()[0] == ';') { found = 1; } ++tokenizer; } if (tokenizer.Type() == eTkNull) { // No more parameters break; } tokenStr.SetFirst(tokenizer); // Get attribute DwString attrib; int attribFound = 0; while (!attribFound && tokenizer.Type() != eTkNull) { if (tokenizer.Type() == eTkToken) { attrib = tokenizer.Token(); attribFound = 1; } ++tokenizer; } // Get '=' found = 0; while (!found && tokenizer.Type() != eTkNull) { if (tokenizer.Type() == eTkTspecial && tokenizer.Token()[0] == '=') { found = 1; } ++tokenizer; } // Get value but do _not_ stop when finding a '/' in it int valueFound = 0; while (!valueFound && tokenizer.Type() != eTkNull) { if (tokenizer.Type() == eTkToken || tokenizer.Type() == eTkQuotedString) { ++tokenizer; if (tokenizer.Type() != eTkTspecial || tokenizer.Token()[0] != '/') valueFound = 1; } else ++tokenizer; } if (attribFound && valueFound) { tokenStr.ExtendTo(tokenizer); DwParameter* param = DwParameter::NewParameter(tokenStr.Tokens(), this); param->Parse(); _AddParameter(param); } } TypeStrToEnum(); SubtypeStrToEnum(); } void DwMediaType::Assemble() { if (!mIsModified) return; mString = ""; if (mTypeStr.length() == 0 || mSubtypeStr.length() == 0) return; mString += mTypeStr; mString += '/'; mString += mSubtypeStr; DwParameter* param = FirstParameter(); while (param) { param->Assemble(); if (IsFolding()) { mString += ";" DW_EOL " "; } else { mString += "; "; } mString += param->AsString(); param = param->Next(); } mIsModified = 0; } DwMessageComponent* DwMediaType::Clone() const { return new DwMediaType(*this); } void DwMediaType::TypeEnumToStr() { DwTypeEnumToStr(mType, mTypeStr); } void DwMediaType::TypeStrToEnum() { mType = DwTypeStrToEnum(mTypeStr); } void DwMediaType::SubtypeEnumToStr() { DwSubtypeEnumToStr(mSubtype, mSubtypeStr); } void DwMediaType::SubtypeStrToEnum() { mSubtype = DwSubtypeStrToEnum(mSubtypeStr); } void DwMediaType::DeleteParameterList() { DwParameter* param = mFirstParameter; while (param) { DwParameter* nextParam = param->Next(); delete param; param = nextParam; } mFirstParameter = 0; SetModified(); } void DwMediaType::CopyParameterList(DwParameter* aFirst) { DwParameter* param = aFirst; while (param) { DwParameter* newParam = (DwParameter*) param->Clone(); AddParameter(newParam); param = param->Next(); } } #if defined(DW_DEBUG_VERSION) void DwMediaType::PrintDebugInfo(std::ostream& aStrm, int aDepth) const { aStrm << "--------------- Debug info for DwMediaType class ---------------\n"; _PrintDebugInfo(aStrm); int depth = aDepth - 1; depth = (depth >= 0) ? depth : 0; if (aDepth == 0 || depth > 0) { DwParameter* param = mFirstParameter; while (param) { param->PrintDebugInfo(aStrm, depth); param = param->Next(); } } } #else void DwMediaType::PrintDebugInfo(std::ostream& , int ) const {} #endif // defined(DW_DEBUG_VERSION) #if defined(DW_DEBUG_VERSION) void DwMediaType::_PrintDebugInfo(std::ostream& aStrm) const { DwFieldBody::_PrintDebugInfo(aStrm); aStrm << "Type: " << mTypeStr << " (" << mType << ")\n"; aStrm << "Subtype: " << mSubtypeStr << " (" << mSubtype << ")\n"; aStrm << "Boundary: " << mBoundaryStr << '\n'; aStrm << "Parameters: "; DwParameter* param = mFirstParameter; if (param) { int count = 0; while (param) { if (count) aStrm << ' '; aStrm << param->ObjectId(); param = param->Next(); ++count; } aStrm << '\n'; } else { aStrm << "(none)\n"; } } #else void DwMediaType::_PrintDebugInfo(std::ostream& ) const {} #endif // defined(DW_DEBUG_VERSION) void DwMediaType::CheckInvariants() const { #if defined(DW_DEBUG_VERSION) mTypeStr.CheckInvariants(); mSubtypeStr.CheckInvariants(); mBoundaryStr.CheckInvariants(); DwParameter* param = mFirstParameter; while (param) { param->CheckInvariants(); assert((DwMessageComponent*) this == param->Parent()); param = param->Next(); } #endif // defined(DW_DEBUG_VERSION) } mimelib1-1.1.4/mimelib/boyermor.cpp0000644000175000017500000000714111175345261016604 0ustar resivoresivo//============================================================================= // File: boyermor.cpp // Contents: Definitions for DwBoyerMoore // Maintainer: Doug Sauder // WWW: http://www.fwb.gulf.net/~dwsauder/mimepp.html // // Copyright (c) 1996, 1997 Douglas W. Sauder // All rights reserved. // // IN NO EVENT SHALL DOUGLAS W. SAUDER BE LIABLE TO ANY PARTY FOR DIRECT, // INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF // THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF DOUGLAS W. SAUDER // HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // DOUGLAS W. SAUDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT // NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A // PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" // BASIS, AND DOUGLAS W. SAUDER HAS NO OBLIGATION TO PROVIDE MAINTENANCE, // SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. // //============================================================================= #define DW_IMPLEMENTATION #include #include #include #include #include DwBoyerMoore::DwBoyerMoore(const char* aCstr) : mPat( 0 ), mCiPat( 0 ) { size_t len = strlen(aCstr); _Assign(aCstr, len); } DwBoyerMoore::DwBoyerMoore(const DwString& aStr) : mPat( 0 ), mCiPat( 0 ) { _Assign(aStr.data(), aStr.length()); } DwBoyerMoore::DwBoyerMoore(const DwBoyerMoore & other) : mPat( 0 ), mCiPat( 0 ) { _Assign(other.mPat, other.mPatLen); } DwBoyerMoore::~DwBoyerMoore() { delete[] mPat; mPat = 0; delete[] mCiPat; mCiPat = 0; } const DwBoyerMoore & DwBoyerMoore::operator=( const DwBoyerMoore & other ) { if (this != &other) _Assign(other.mPat, other.mPatLen); return *this; } void DwBoyerMoore::Assign(const char* aCstr) { size_t len = strlen(aCstr); _Assign(aCstr, len); } void DwBoyerMoore::Assign(const DwString& aStr) { _Assign(aStr.data(), aStr.length()); } void DwBoyerMoore::_Assign(const char* aPat, size_t aPatLen) { mPatLen = 0; delete[] mPat; mPat = 0; delete[] mCiPat; mCiPat = 0; mPat = new char[aPatLen+1]; mCiPat = new char[aPatLen+1]; if (mPat != 0 && aPatLen) { mPatLen = aPatLen; strncpy(mPat, aPat, mPatLen); mCiPat[mPatLen] = mPat[mPatLen] = 0; // Initialize the jump table for Boyer-Moore-Horspool algorithm size_t i; for (i=0; i < 256; ++i) mSkipAmt[i] = mCiSkipAmt[i] = (unsigned char) mPatLen; for (i=0; i < mPatLen-1; ++i) { unsigned char skip = mPatLen - i - 1; mCiPat[i] = tolower(mPat[i]); mCiSkipAmt[(unsigned char)mCiPat[i]] = skip; mCiSkipAmt[(unsigned char)toupper(mCiPat[i])] = skip; mSkipAmt[(unsigned char)mPat[i]] = skip; } mCiPat[i] = tolower(mPat[i]); } } size_t DwBoyerMoore::FindIn(const DwString& aStr, size_t aPos, bool aCs) const { char *pat = aCs ? mPat : mCiPat; const unsigned char *skipAmt = aCs ? mSkipAmt : mCiSkipAmt; if (aStr.length() <= aPos) { return (size_t) -1; } if (pat == 0 || mPatLen == 0) { return 0; } size_t bufLen = aStr.length() - aPos; const char* buf = aStr.data() + aPos; size_t i; for (i=mPatLen-1; i < bufLen; i += skipAmt[(unsigned char)buf[i]]) { int iBuf = i; int iPat = mPatLen - 1; while (iPat >= 0 && (aCs ? buf[iBuf] : tolower(buf[iBuf])) == pat[iPat]) { --iBuf; --iPat; } if (iPat == -1) return aPos + iBuf + 1; } return (size_t)-1; } mimelib1-1.1.4/mimelib/nntp.cpp0000644000175000017500000004562111175345261015732 0ustar resivoresivo//============================================================================= // File: nntp.cpp // Contents: Definitions for DwNntpClient // Maintainer: Doug Sauder // WWW: http://www.fwb.gulf.net/~dwsauder/mimepp.html // // Copyright (c) 1996, 1997 Douglas W. Sauder // All rights reserved. // // IN NO EVENT SHALL DOUGLAS W. SAUDER BE LIABLE TO ANY PARTY FOR DIRECT, // INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF // THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF DOUGLAS W. SAUDER // HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // DOUGLAS W. SAUDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT // NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A // PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" // BASIS, AND DOUGLAS W. SAUDER HAS NO OBLIGATION TO PROVIDE MAINTENANCE, // SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. // //============================================================================= #define DW_IMPLEMENTATION #include #include #include #include #include #define NNTP_PORT 119 #define RECV_BUFFER_SIZE 8192 #define SEND_BUFFER_SIZE 1024 #if defined(DW_DEBUG_NNTP) # define DBG_NNTP_STMT(x) x #else # define DBG_NNTP_STMT(x) #endif DwNntpClient::DwNntpClient() { mSendBuffer = new char[SEND_BUFFER_SIZE]; mRecvBuffer = new char[RECV_BUFFER_SIZE]; mLastChar = -1; mLastLastChar = -1; mNumRecvBufferChars = 0; mRecvBufferPos = 0; mReplyCode = 0; mObserver = 0; } DwNntpClient::~DwNntpClient() { if (mRecvBuffer) { delete [] mRecvBuffer; mRecvBuffer = 0; } if (mSendBuffer) { delete [] mSendBuffer; mSendBuffer = 0; } } int DwNntpClient::Open(const char* aServer, DwUint16 aPort) { mReplyCode = 0; mStatusResponse = mTextResponse = ""; int err = DwProtocolClient::Open(aServer, aPort); if (! err) { PGetStatusResponse(); } return mReplyCode; } DwObserver* DwNntpClient::SetObserver(DwObserver* aObserver) { DwObserver* obs = mObserver; mObserver = aObserver; return obs; } int DwNntpClient::ReplyCode() const { return mReplyCode; } const DwString& DwNntpClient::StatusResponse() const { return mStatusResponse; } const DwString& DwNntpClient::TextResponse() const { return mTextResponse; } int DwNntpClient::Article(int aArticleNum) { mReplyCode = 0; mStatusResponse = mTextResponse = ""; mLastCommand = kCmdArticle; if (aArticleNum >= 0) { snprintf(mSendBuffer, SEND_BUFFER_SIZE, "ARTICLE %d\r\n", aArticleNum); } else { strcpy(mSendBuffer, "ARTICLE\r\n"); } DBG_NNTP_STMT(cout << "C: " << mSendBuffer << flush;) int bufferLen = strlen(mSendBuffer); int numSent = PSend(mSendBuffer, bufferLen); if (numSent == bufferLen) { PGetStatusResponse(); if (mReplyCode/100%10 == 2) { PGetTextResponse(); } } return mReplyCode; } int DwNntpClient::Article(const char* aMsgId) { mReplyCode = 0; mStatusResponse = mTextResponse = ""; mLastCommand = kCmdArticle; if (!aMsgId || !*aMsgId) { // error! return mReplyCode; } strcpy(mSendBuffer, "ARTICLE "); strncat(mSendBuffer, aMsgId, 80); strcat(mSendBuffer, "\r\n"); DBG_NNTP_STMT(cout << "C: " << mSendBuffer << flush;) int bufferLen = strlen(mSendBuffer); int numSent = PSend(mSendBuffer, bufferLen); if (numSent == bufferLen) { PGetStatusResponse(); if (mReplyCode/100%10 == 2) { PGetTextResponse(); } } return mReplyCode; } int DwNntpClient::Head(int aArticleNum) { mReplyCode = 0; mStatusResponse = mTextResponse = ""; mLastCommand = kCmdHead; if (aArticleNum >= 0) { snprintf(mSendBuffer, SEND_BUFFER_SIZE, "HEAD %d\r\n", aArticleNum); } else { strcpy(mSendBuffer, "HEAD\r\n"); } DBG_NNTP_STMT(cout << "C: " << mSendBuffer << flush;) int bufferLen = strlen(mSendBuffer); int numSent = PSend(mSendBuffer, bufferLen); if (numSent == bufferLen) { PGetStatusResponse(); if (mReplyCode/100%10 == 2) { PGetTextResponse(); } } return mReplyCode; } int DwNntpClient::Head(const char* aMsgId) { mReplyCode = 0; mStatusResponse = mTextResponse = ""; mLastCommand = kCmdHead; if (!aMsgId || !*aMsgId) { return mReplyCode; } strcpy(mSendBuffer, "HEAD "); strncat(mSendBuffer, aMsgId, 80); strcat(mSendBuffer, "\r\n"); DBG_NNTP_STMT(cout << "C: " << mSendBuffer << flush;) int bufferLen = strlen(mSendBuffer); int numSent = PSend(mSendBuffer, bufferLen); if (numSent == bufferLen) { PGetStatusResponse(); if (mReplyCode/100%10 == 2) { PGetTextResponse(); } } return mReplyCode; } int DwNntpClient::Body(int articleNum) { mReplyCode = 0; mStatusResponse = mTextResponse = ""; mLastCommand = kCmdBody; if (articleNum >= 0) { snprintf(mSendBuffer, SEND_BUFFER_SIZE, "BODY %d\r\n", articleNum); } else { strcpy(mSendBuffer, "BODY\r\n"); } DBG_NNTP_STMT(cout << "C: " << mSendBuffer << flush;) int bufferLen = strlen(mSendBuffer); int numSent = PSend(mSendBuffer, bufferLen); if (numSent == bufferLen) { PGetStatusResponse(); if (mReplyCode/100%10 == 2) { PGetTextResponse(); } } return mReplyCode; } int DwNntpClient::Body(const char* aMsgId) { mReplyCode = 0; mStatusResponse = mTextResponse = ""; mLastCommand = kCmdBody; if (!aMsgId || !*aMsgId) { return mReplyCode; } strcpy(mSendBuffer, "BODY "); strncat(mSendBuffer, aMsgId, 80); strcat(mSendBuffer, "\r\n"); DBG_NNTP_STMT(cout << "C: " << mSendBuffer << flush;) int bufferLen = strlen(mSendBuffer); int numSent = PSend(mSendBuffer, bufferLen); if (numSent == bufferLen) { PGetStatusResponse(); if (mReplyCode/100%10 == 2) { PGetTextResponse(); } } return mReplyCode; } int DwNntpClient::Stat(int articleNum) { mReplyCode = 0; mStatusResponse = mTextResponse = ""; mLastCommand = kCmdStat; if (articleNum >= 0) { snprintf(mSendBuffer, SEND_BUFFER_SIZE, "STAT %d\r\n", articleNum); } else { strcpy(mSendBuffer, "STAT\r\n"); } DBG_NNTP_STMT(cout << "C: " << mSendBuffer << flush;) int bufferLen = strlen(mSendBuffer); int numSent = PSend(mSendBuffer, bufferLen); if (numSent == bufferLen) { PGetStatusResponse(); } return mReplyCode; } int DwNntpClient::Stat(const char* aMsgId) { mReplyCode = 0; mStatusResponse = mTextResponse = ""; mLastCommand = kCmdStat; if (!aMsgId || !*aMsgId) { return mReplyCode; } strcpy(mSendBuffer, "STAT "); strncat(mSendBuffer, aMsgId, 80); strcat(mSendBuffer, "\r\n"); DBG_NNTP_STMT(cout << "C: " << mSendBuffer << flush;) int bufferLen = strlen(mSendBuffer); int numSent = PSend(mSendBuffer, bufferLen); if (numSent == bufferLen) { PGetStatusResponse(); } return mReplyCode; } int DwNntpClient::Group(const char* aNewsgroupName) { mReplyCode = 0; mStatusResponse = mTextResponse = ""; mLastCommand = kCmdGroup; if (!aNewsgroupName || !*aNewsgroupName) { return mReplyCode; } strcpy(mSendBuffer, "GROUP "); strncat(mSendBuffer, aNewsgroupName, SEND_BUFFER_SIZE-32); strcat(mSendBuffer, "\r\n"); DBG_NNTP_STMT(cout << "C: " << mSendBuffer << flush;) int bufferLen = strlen(mSendBuffer); int numSent = PSend(mSendBuffer, bufferLen); if (numSent == bufferLen) { PGetStatusResponse(); } return mReplyCode; } int DwNntpClient::Help() { mReplyCode = 0; mStatusResponse = mTextResponse = ""; mLastCommand = kCmdHelp; strcpy(mSendBuffer, "HELP\r\n"); DBG_NNTP_STMT(cout << "C: " << mSendBuffer << flush;) int bufferLen = strlen(mSendBuffer); int numSent = PSend(mSendBuffer, bufferLen); if (numSent == bufferLen) { PGetStatusResponse(); if (mReplyCode/100%10 == 1) { PGetTextResponse(); } } return mReplyCode; } int DwNntpClient::Last() { mReplyCode = 0; mStatusResponse = mTextResponse = ""; mLastCommand = kCmdLast; strcpy(mSendBuffer, "LAST\r\n"); DBG_NNTP_STMT(cout << "C: " << mSendBuffer << flush;) int bufferLen = strlen(mSendBuffer); int numSent = PSend(mSendBuffer, bufferLen); if (numSent == bufferLen) { PGetStatusResponse(); } return mReplyCode; } int DwNntpClient::List() { mReplyCode = 0; mStatusResponse = mTextResponse = ""; mLastCommand = kCmdList; strcpy(mSendBuffer, "LIST\r\n"); DBG_NNTP_STMT(cout << "C: " << mSendBuffer << flush;) int bufferLen = strlen(mSendBuffer); int numSent = PSend(mSendBuffer, bufferLen); if (numSent == bufferLen) { PGetStatusResponse(); if (mReplyCode/100%10 == 2) { PGetTextResponse(); } } return mReplyCode; } int DwNntpClient::Newgroups(const char* aDate, const char* aTime, DwBool aIsGmt, const char* aDistribution) { mReplyCode = 0; mStatusResponse = mTextResponse = ""; mLastCommand = kCmdNewgroups; strcpy(mSendBuffer, "NEWGROUPS "); strncat(mSendBuffer, aDate, 16); strcat(mSendBuffer, " "); strncat(mSendBuffer, aTime, 16); if (aIsGmt) { strcat(mSendBuffer, " GMT"); } if (aDistribution) { strcat(mSendBuffer, " "); strncat(mSendBuffer, aDistribution, SEND_BUFFER_SIZE-64); } strcat(mSendBuffer, "\r\n"); DBG_NNTP_STMT(cout << "C: " << mSendBuffer << flush;) int bufferLen = strlen(mSendBuffer); int numSent = PSend(mSendBuffer, bufferLen); if (numSent == bufferLen) { PGetStatusResponse(); if (mReplyCode/100%10 == 2) { PGetTextResponse(); } } return mReplyCode; } int DwNntpClient::Newnews(const char* aNewsgroups, const char* aDate, const char* aTime, DwBool aIsGmt, const char* aDistribution) { mReplyCode = 0; mStatusResponse = mTextResponse = ""; mLastCommand = kCmdNewnews; strcpy(mSendBuffer, "NEWNEWS "); strncat(mSendBuffer, aNewsgroups, SEND_BUFFER_SIZE-64); strcat(mSendBuffer, " "); strncat(mSendBuffer, aDate, 16); strcat(mSendBuffer, " "); strncat(mSendBuffer, aTime, 16); if (aIsGmt) { strcat(mSendBuffer, " GMT"); } if (aDistribution) { strcat(mSendBuffer, " "); size_t n = strlen(mSendBuffer); strncat(mSendBuffer, aDistribution, SEND_BUFFER_SIZE-n-4); } strcat(mSendBuffer, "\r\n"); DBG_NNTP_STMT(cout << "C: " << mSendBuffer << flush;) int bufferLen = strlen(mSendBuffer); int numSent = PSend(mSendBuffer, bufferLen); if (numSent == bufferLen) { PGetStatusResponse(); if (mReplyCode/100%10 == 2) { PGetTextResponse(); } } return mReplyCode; } int DwNntpClient::Next() { mReplyCode = 0; mStatusResponse = mTextResponse = ""; mLastCommand = kCmdNext; strcpy(mSendBuffer, "NEXT\r\n"); DBG_NNTP_STMT(cout << "C: " << mSendBuffer << flush;) int bufferLen = strlen(mSendBuffer); int numSent = PSend(mSendBuffer, bufferLen); if (numSent == bufferLen) { PGetStatusResponse(); } return mReplyCode; } int DwNntpClient::Post() { mReplyCode = 0; mStatusResponse = mTextResponse = ""; mLastCommand = kCmdPost; strcpy(mSendBuffer, "POST\r\n"); DBG_NNTP_STMT(cout << "C: " << mSendBuffer << flush;) int bufferLen = strlen(mSendBuffer); int numSent = PSend(mSendBuffer, bufferLen); if (numSent == bufferLen) { PGetStatusResponse(); } return mReplyCode; } int DwNntpClient::Quit() { mReplyCode = 0; mStatusResponse = mTextResponse = ""; mLastCommand = kCmdQuit; strcpy(mSendBuffer, "QUIT\r\n"); DBG_NNTP_STMT(cout << "C: " << mSendBuffer << flush;) int bufferLen = strlen(mSendBuffer); int numSent = PSend(mSendBuffer, bufferLen); if (numSent == bufferLen) { PGetStatusResponse(); } return mReplyCode; } int DwNntpClient::Slave() { mReplyCode = 0; mStatusResponse = mTextResponse = ""; mLastCommand = kCmdSlave; strcpy(mSendBuffer, "SLAVE\r\n"); DBG_NNTP_STMT(cout << "C: " << mSendBuffer << flush;) int bufferLen = strlen(mSendBuffer); int numSent = PSend(mSendBuffer, bufferLen); if (numSent == bufferLen) { PGetStatusResponse(); } return mReplyCode; } int DwNntpClient::SendData(const DwString& aStr) { return SendData(aStr.data(), aStr.length()); } int DwNntpClient::SendData(const char* aBuf, int aBufLen) { mReplyCode = 0; mStatusResponse = mTextResponse = ""; int pos = 0; int len = 0; const char* buf = 0; int lastLastChar = '\r'; int lastChar = '\n'; while (1) { len = SEND_BUFFER_SIZE; len = (len < aBufLen - pos) ? len : aBufLen - pos; if (len == 0) break; // Look for CR LF '.'. If it is found, then we have to copy the buffer // and stuff an extra '.'. int hasCrLfDot = 0; int tLastChar = lastChar; int tLastLastChar = lastLastChar; for (int i=0; i < len; ++i) { int ch = aBuf[pos+i]; if (tLastLastChar == '\r' && tLastChar == '\n' && ch == '.') { hasCrLfDot = 1; break; } tLastLastChar = tLastChar; tLastChar = ch; } if (! hasCrLfDot) { lastChar = tLastChar; lastLastChar = tLastLastChar; buf = &aBuf[pos]; pos += len; } // If CR LF '.' was found, copy the chars to a different buffer and stuff // the extra '.'. else /* (hasCrLfDot) */ { tLastChar = lastChar; tLastLastChar = lastLastChar; int iDst = 0; int iSrc = 0; // Implementation note: be careful to avoid overrunning the // destination buffer when CR LF '.' are the last three characters // of the source buffer. while (iDst < SEND_BUFFER_SIZE && iSrc < len) { int ch = aBuf[pos+iSrc]; if (tLastLastChar == '\r' && tLastChar == '\n' && ch == '.') { if (iDst == SEND_BUFFER_SIZE-1) { break; } mSendBuffer[iDst++] = '.'; } mSendBuffer[iDst++] = (char) ch; ++iSrc; tLastLastChar = tLastChar; tLastChar = ch; } lastChar = tLastChar; lastLastChar = tLastLastChar; len = iDst; buf = mSendBuffer; pos += iSrc; } // Send the buffer int numSent = PSend(buf, len); if (numSent != len) { mReplyCode = 0; return mReplyCode; } } // Send final '.' CR LF. If CR LF are not at the end of the buffer, then // send a CR LF '.' CR LF. if (lastLastChar == '\r' && lastChar == '\n') { PSend(".\r\n", 3); } else { PSend("\r\n.\r\n", 5); } // Get the server's response PGetStatusResponse(); return mReplyCode; } void DwNntpClient::PGetStatusResponse() { mReplyCode = 0; mStatusResponse = ""; char* ptr; int len; int err = PGetLine(&ptr, &len); if (! err) { mReplyCode = strtol(ptr, NULL, 10); mStatusResponse.assign(ptr, len); DBG_NNTP_STMT(char buffer[256];) DBG_NNTP_STMT(strncpy(buffer, ptr, len);) DBG_NNTP_STMT(buffer[len] = 0;) DBG_NNTP_STMT(cout << "S: " << buffer;) } } void DwNntpClient::PGetTextResponse() { mTextResponse = ""; // Get a line at a time until we get CR LF . CR LF while (1) { char* ptr; int len; int err = PGetLine(&ptr, &len); // Check for an error if (err) { mReplyCode = 0; return; } // Check for '.' on a line by itself, which indicates end of multiline // response if (len >= 3 && ptr[0] == '.' && ptr[1] == '\r' && ptr[2] == '\n') { break; } // Remove '.' at beginning of line if (*ptr == '.') ++ptr; // If an observer is assigned, notify it. // Implementation note: An observer is assumed to fetch the multiline // response one line at a time, therefore we assign to the string, // rather than append to it. if (mObserver) { mTextResponse.assign(ptr, len); mObserver->Notify(); } else { mTextResponse.append(ptr, len); } } } int DwNntpClient::PGetLine(char** aPtr, int* aLen) { // Restore the saved state int startPos = mRecvBufferPos; int pos = mRecvBufferPos; int lastChar = -1; // Keep trying until we get a complete line, detect an error, or // determine that the connection has been closed int isEndOfLineFound = 0; while (1) { // Search buffer for end of line chars. Stop when we find them or when // we exhaust the buffer. while (pos < mNumRecvBufferChars) { if (lastChar == '\r' && mRecvBuffer[pos] == '\n') { isEndOfLineFound = 1; ++pos; break; } lastChar = mRecvBuffer[pos]; ++pos; } if (isEndOfLineFound) { *aPtr = &mRecvBuffer[startPos]; *aLen = pos - startPos; mRecvBufferPos = pos; return 0; } // If the buffer has no room, return without an error; otherwise, // replenish the buffer. // Implementation note: The standard does not allow long lines, // however, that does not mean that they won't occur. The way // this function deals with long lines is to return a full buffer's // worth of characters as a line. The next call to this function // will start where this call left off. In essence, we have // *forced* a line break, but without putting in CR LF characters. if (startPos == 0 && pos == RECV_BUFFER_SIZE) { *aPtr = mRecvBuffer; *aLen = RECV_BUFFER_SIZE; mRecvBufferPos = pos; return 0; } memmove(mRecvBuffer, &mRecvBuffer[startPos], mNumRecvBufferChars-startPos); mNumRecvBufferChars -= startPos; mRecvBufferPos = mNumRecvBufferChars; int bufFreeSpace = RECV_BUFFER_SIZE - mRecvBufferPos; int n = PReceive(&mRecvBuffer[mRecvBufferPos], bufFreeSpace); if (n == 0) { // The connection has been closed or an error occurred return -1; } mNumRecvBufferChars += n; startPos = 0; pos = mRecvBufferPos; } } mimelib1-1.1.4/mimelib/README.mimepp0000644000175000017500000000361111175345261016406 0ustar resivoresivoThis is the README file for the MIME++ library. **** Important: Please read the file LICENSE for information about using mime++. mime++ may be used for non-commercial use without paying a license fee; however, by downloading or using the software, you agree to abide by the terms of the Non-Commercial License. **** MIME++ is a C++ class library for creating, parsing, and modifying messages in MIME format. See the file INSTALL for information about how to compile the library. The library classes themselves are somewhat low-level. The example programs use wrapper classes. This technique of using wrapper classes is the recommended way to use MIME++ for two reasons. First, it will isolate your application from the low-level, implementation details of the library. Second, it will help to isolate your application from future changes in the library classes. If you are familiar with the idea of design patterns, the wrapper classes implement the facade pattern. To learn the library, I suggest you first take a look at the text file "Tutorial", which contains a tutorial. Then, I suggest browsing the HTML man pages, which can all be referenced from doc/mimepp.html. If you do not have an HTML browser available, use your favorite editor to view the .h files. All the text of the man pages is embedded as comments in the .h files. Look especially at the man pages for DwString and DwMessageComponent, the base class of nearly all MIME components. Also, look at the example programs. As a starting point for your own application, I suggest you start with the source code for one or more of the wrapper classes (BasicMessage, declared and defined in basicmsg.*; MultipartMessage, declared and defined in multipar.*; and MessageWithAttachments, declared and defined in attach.*) and modify it for your own use. Please send me any comments, questions, bug reports, or whatever. Doug Sauder dwsauder@fwb.gulf.net mimelib1-1.1.4/mimelib/msgid.cpp0000644000175000017500000002266611175345261016062 0ustar resivoresivo//============================================================================= // File: msgid.cpp // Contents: Definitions for DwMsgId // Maintainer: Doug Sauder // WWW: http://www.fwb.gulf.net/~dwsauder/mimepp.html // // Copyright (c) 1996, 1997 Douglas W. Sauder // All rights reserved. // // IN NO EVENT SHALL DOUGLAS W. SAUDER BE LIABLE TO ANY PARTY FOR DIRECT, // INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF // THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF DOUGLAS W. SAUDER // HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // DOUGLAS W. SAUDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT // NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A // PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" // BASIS, AND DOUGLAS W. SAUDER HAS NO OBLIGATION TO PROVIDE MAINTENANCE, // SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. // //============================================================================= #define DW_IMPLEMENTATION #include #include #include #include #include // UNIX specific includes //#if defined(__unix__) || defined(__unix) #if defined(DW_UNIX) # include // When building with SS12 but *not* using RW stdcxx, need sysent.h; // the combination of sysent + stdcxx is fatal (and we don't really // seem to need sysent.h anyway). # if defined(__SUNPRO_CC) && !defined(_RWSTD_REENTRANT) # include # endif // defined(__SUNPRO_CC) #endif // defined (DW_UNIX) // WIN32 specific includes #if defined(DW_WIN32) # include #endif // defined(DW_WIN32) #include #include #include static void GetHostName(char* buf, int bufLen); static DwUint32 GetPid(); const char* const DwMsgId::sClassName = "DwMsgId"; const char* DwMsgId::sHostName = 0; DwMsgId* (*DwMsgId::sNewMsgId)(const DwString&, DwMessageComponent*) = 0; DwMsgId* DwMsgId::NewMsgId(const DwString& aStr, DwMessageComponent* aParent) { if (sNewMsgId) { return sNewMsgId(aStr, aParent); } else { return new DwMsgId(aStr, aParent); } } DwMsgId::DwMsgId() { mClassId = kCidMsgId; mClassName = sClassName; } DwMsgId::DwMsgId(const DwMsgId& aMsgId) : DwFieldBody(aMsgId), mLocalPart(aMsgId.mLocalPart), mDomain(aMsgId.mDomain) { mClassId = kCidMsgId; mClassName = sClassName; } DwMsgId::DwMsgId(const DwString& aStr, DwMessageComponent* aParent) : DwFieldBody(aStr, aParent) { mClassId = kCidMsgId; mClassName = sClassName; } DwMsgId::~DwMsgId() { } const DwMsgId& DwMsgId::operator = (const DwMsgId& aMsgId) { if (this == &aMsgId) return *this; DwFieldBody::operator = (aMsgId); mLocalPart = aMsgId.mLocalPart; mDomain = aMsgId.mDomain; return *this; } const DwString& DwMsgId::LocalPart() const { return mLocalPart; } void DwMsgId::SetLocalPart(const DwString& aLocalPart) { mLocalPart = aLocalPart; SetModified(); } const DwString& DwMsgId::Domain() const { return mDomain; } void DwMsgId::SetDomain(const DwString& aDomain) { mDomain = aDomain; SetModified(); } void DwMsgId::Parse() { mIsModified = 0; int ch; DwRfc822Tokenizer tokenizer(mString); // Advance to '<' int type = tokenizer.Type(); int found = 0; while (!found && type != eTkNull) { if (type == eTkSpecial && tokenizer.Token()[0] == '<') { found = 1; } ++tokenizer; type = tokenizer.Type(); } // Get the local part found = 0; while (type != eTkNull && !found) { switch (type) { case eTkSpecial: ch = tokenizer.Token()[0]; switch (ch) { case '@': found = 1; break; case '.': mLocalPart += tokenizer.Token(); break; } break; case eTkAtom: case eTkQuotedString: mLocalPart += tokenizer.Token(); break; } ++tokenizer; type = tokenizer.Type(); } // Get the domain found = 0; while (type != eTkNull && !found) { switch (type) { case eTkSpecial: ch = tokenizer.Token()[0]; switch (ch) { case '>': found = 1; break; case '.': mDomain += tokenizer.Token(); break; } break; case eTkAtom: mDomain += tokenizer.Token(); break; case eTkDomainLiteral: mDomain += tokenizer.Token(); break; } ++tokenizer; type = tokenizer.Type(); } } void DwMsgId::Assemble() { if (!mIsModified) return; mString = "<"; mString += mLocalPart; mString += "@"; mString += mDomain; mString += ">"; mIsModified = 0; } DwMessageComponent* DwMsgId::Clone() const { return new DwMsgId(*this); } static char base35chars[] = "0123456789ABCDEFGHIJKLMNPQRSTUVWXYZ"; void DwMsgId::CreateDefault() { char hostname[80]; hostname[0] = 0; GetHostName(hostname, 80); hostname[79] = 0; char scratch[80]; time_t tt = time(NULL); struct tm tms = *localtime(&tt); int pos = 0; scratch[pos++] = '<'; int n = tms.tm_year; scratch[pos++] = char(n / 10 % 10 + '0'); scratch[pos++] = char(n % 10 + '0'); n = tms.tm_mon + 1; scratch[pos++] = char(n / 10 % 10 + '0'); scratch[pos++] = char(n % 10 + '0'); n = tms.tm_mday; scratch[pos++] = char(n / 10 % 10 + '0'); scratch[pos++] = char(n % 10 + '0'); n = tms.tm_hour; scratch[pos++] = char(n / 10 % 10 + '0'); scratch[pos++] = char(n % 10 + '0'); n = tms.tm_min; scratch[pos++] = char(n / 10 % 10 + '0'); scratch[pos++] = char(n % 10 + '0'); n = tms.tm_sec; scratch[pos++] = char(n / 10 % 10 + '0'); scratch[pos++] = char(n % 10 + '0'); static int counter = 0; scratch[pos++] = base35chars[counter/35%35]; scratch[pos++] = base35chars[counter %35]; ++counter; scratch[pos++] = '.'; DwUint32 pid = GetPid(); scratch[pos++] = char(pid / 10000 % 10 + '0'); scratch[pos++] = char(pid / 1000 % 10 + '0'); scratch[pos++] = char(pid / 100 % 10 + '0'); scratch[pos++] = char(pid / 10 % 10 + '0'); scratch[pos++] = char(pid % 10 + '0'); scratch[pos++] = '@'; char* cp = hostname; while (*cp && pos < 79) { scratch[pos++] = *cp++; } scratch[pos++] = '>'; scratch[pos] = 0; mString = scratch; mIsModified = 0; Parse(); } #if defined (DW_DEBUG_VERSION) void DwMsgId::PrintDebugInfo(std::ostream& aStrm, int /*aDepth*/) const { aStrm << "----------------- Debug info for DwMsgId class -----------------\n"; _PrintDebugInfo(aStrm); } #else void DwMsgId::PrintDebugInfo(std::ostream& , int ) const {} #endif // defined (DW_DEBUG_VERSION) #if defined (DW_DEBUG_VERSION) void DwMsgId::_PrintDebugInfo(std::ostream& aStrm) const { DwFieldBody::_PrintDebugInfo(aStrm); aStrm << "Local part: " << mLocalPart << '\n'; aStrm << "Domain: " << mDomain << '\n'; } #else void DwMsgId::_PrintDebugInfo(std::ostream& ) const {} #endif // defined (DW_DEBUG_VERSION) void DwMsgId::CheckInvariants() const { #if defined (DW_DEBUG_VERSION) DwFieldBody::CheckInvariants(); mLocalPart.CheckInvariants(); mDomain.CheckInvariants(); #endif // defined (DW_DEBUG_VERSION) } //============================================================================ // Platform dependent code follows //============================================================================ //---------------------------------------------------------------------------- // WIN32 //---------------------------------------------------------------------------- #if defined(DW_WIN32) #if defined(WINSOCK) // Winsock version static void GetHostName(char* buf, int bufLen) { WORD wVersionRequested = MAKEWORD(1, 1); WSADATA wsaData; int err = WSAStartup(wVersionRequested, &wsaData); // check winsock version 1.1 if (LOBYTE(wsaData.wVersion) == 1 && HIBYTE(wsaData.wVersion) == 1 && err == 0) { buf[0] = '\0'; if (!gethostname(buf, bufLen)) buf[bufLen-1] = '\0'; } else { // cannot find winsock if (DwMsgId::sHostName) { strcpy(hostname, DwMsgId::sHostName); } else { strcpy(hostname, "noname"); } } WSACleanup(); } #else // !defined(WINSOCK) // Generic version (no Winsock). Requires that DwMsgId::sHostName be set. static void GetHostName(char* buf, int bufLen) { if (DwMsgId::sHostName) { strncpy(buf, DwMsgId::sHostName, bufLen); buf[bufLen-1] = 0; } else { strcpy(buf, "noname"); } } #endif // !defined(WINSOCK) #ifndef _PID_T_ typedef unsigned pid_t; #endif static DwUint32 GetPid() { return GetCurrentProcessId(); } #endif // defined(DW_WIN32) //---------------------------------------------------------------------------- // UNIX //---------------------------------------------------------------------------- #if defined(DW_UNIX) static void GetHostName(char* buf, int bufLen) { buf[0] = '\0'; if (!gethostname(buf, bufLen)) buf[bufLen-1] = '\0'; } static DwUint32 GetPid() { return getpid(); } #endif // defined(DW_UNIX) mimelib1-1.1.4/mimelib/param.cpp0000644000175000017500000001412711175345261016050 0ustar resivoresivo//============================================================================= // File: param.cpp // Contents: Definitions for DwParameter // Maintainer: Doug Sauder // WWW: http://www.fwb.gulf.net/~dwsauder/mimepp.html // // Copyright (c) 1996, 1997 Douglas W. Sauder // All rights reserved. // // IN NO EVENT SHALL DOUGLAS W. SAUDER BE LIABLE TO ANY PARTY FOR DIRECT, // INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF // THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF DOUGLAS W. SAUDER // HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // DOUGLAS W. SAUDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT // NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A // PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" // BASIS, AND DOUGLAS W. SAUDER HAS NO OBLIGATION TO PROVIDE MAINTENANCE, // SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. // //============================================================================= #define DW_IMPLEMENTATION #include #include #include #include #include #include #include #include const char* const DwParameter::sClassName = "DwParameter"; DwParameter* (*DwParameter::sNewParameter)(const DwString&, DwMessageComponent*) = 0; DwParameter* DwParameter::NewParameter(const DwString& aStr, DwMessageComponent* aParent) { if (sNewParameter) { return sNewParameter(aStr, aParent); } else { return new DwParameter(aStr, aParent); } } DwParameter::DwParameter() { mNext = 0; mClassId = kCidParameter; mClassName = sClassName; } DwParameter::DwParameter(const DwParameter& aParam) : DwMessageComponent(aParam), mAttribute(aParam.mAttribute), mValue(aParam.mValue), mForceNoQuotes(aParam.mForceNoQuotes) { mNext = 0; mClassId = kCidParameter; mClassName = sClassName; } DwParameter::DwParameter(const DwString& aStr, DwMessageComponent* aParent) : DwMessageComponent(aStr, aParent) { mNext = 0; mClassId = kCidParameter; mClassName = sClassName; mForceNoQuotes = false; } DwParameter::~DwParameter() { } const DwParameter& DwParameter::operator = (const DwParameter& aParam) { if (this == &aParam) return *this; DwMessageComponent::operator = (aParam); mAttribute = aParam.mAttribute; mValue = aParam.mValue; mForceNoQuotes = aParam.mForceNoQuotes; mNext = 0; return *this; } const DwString& DwParameter::Attribute() const { return mAttribute; } void DwParameter::SetAttribute(const DwString& aAttribute) { mAttribute = aAttribute; SetModified(); } const DwString& DwParameter::Value() const { return mValue; } void DwParameter::SetValue(const DwString& aValue, bool forceNoQuote) { mValue = aValue; mForceNoQuotes = forceNoQuote; SetModified(); } DwParameter* DwParameter::Next() const { return mNext; } void DwParameter::SetNext(DwParameter* aParam) { mNext = aParam; } void DwParameter::Parse() { mIsModified = 0; mAttribute = mValue = ""; if (mString.length() == 0) return; DwRfc1521Tokenizer tokenizer(mString); // Get attribute int found = 0; while (!found && tokenizer.Type() != eTkNull) { if (tokenizer.Type() == eTkToken) { mAttribute = tokenizer.Token(); found = 1; } ++tokenizer; } // Get '=' found = 0; while (!found && tokenizer.Type() != eTkNull) { if (tokenizer.Type() == eTkTspecial && tokenizer.Token()[0] == '=') { found = 1; } ++tokenizer; } // Get value found = 0; while (!found && tokenizer.Type() != eTkNull) { if (tokenizer.Type() == eTkToken) { mValue = tokenizer.Token(); found = 1; } else if (tokenizer.Type() == eTkQuotedString) { tokenizer.StripDelimiters(); mValue = tokenizer.Token(); found = 1; } ++tokenizer; } // Some nonstandard MIME implementations use single quotes to quote // the boundary string. This is incorrect, but we will try to detect // it and work with it. // // If the first character and last character of the boundary string // are single quote, strip them off. if (DwStrcasecmp(mAttribute, "boundary") == 0) { size_t len = mValue.length(); if (len > 2 && mValue[0] == '\'' && mValue[len-1] == '\'') { mValue = mValue.substr(1, len-2); } } } void DwParameter::Assemble() { if (mIsModified == 0) return; mString = ""; mString += mAttribute; bool noQuotes = mForceNoQuotes || (DwStrcasecmp(mAttribute, "micalg") == 0); if( noQuotes ) mString += "="; else mString += "=\""; mString += mValue; if( !noQuotes ) mString += "\""; mIsModified = 0; } DwMessageComponent* DwParameter::Clone() const { return new DwParameter(*this); } #if defined (DW_DEBUG_VERSION) void DwParameter::PrintDebugInfo(std::ostream& aStrm, int /*aDepth*/) const { aStrm << "--------------- Debug info for DwParameter class ---------------\n"; _PrintDebugInfo(aStrm); } #else void DwParameter::PrintDebugInfo(std::ostream& , int ) const {} #endif // defined (DW_DEBUG_VERSION) #if defined (DW_DEBUG_VERSION) void DwParameter::_PrintDebugInfo(std::ostream& aStrm) const { DwMessageComponent::_PrintDebugInfo(aStrm); aStrm << "Attribute: " << mAttribute << '\n'; aStrm << "Value: " << mValue << '\n'; if (mNext) { aStrm << "Next parameter: " << mNext->ObjectId() << '\n'; } else { aStrm << "Next parameter: " << "(none)\n"; } } #else void DwParameter::_PrintDebugInfo(std::ostream& ) const {} #endif // defined (DW_DEBUG_VERSION) void DwParameter::CheckInvariants() const { #if defined (DW_DEBUG_VERSION) DwMessageComponent::CheckInvariants(); mAttribute.CheckInvariants(); mValue.CheckInvariants(); #endif // defined (DW_DEBUG_VERSION) } mimelib1-1.1.4/mimelib/body.cpp0000644000175000017500000004507211175345261015710 0ustar resivoresivo//============================================================================= // File: body.cpp // Contents: Definitions for DwBody // Maintainer: Doug Sauder // WWW: http://www.fwb.gulf.net/~dwsauder/mimepp.html // // Copyright (c) 1996, 1997 Douglas W. Sauder // All rights reserved. // // IN NO EVENT SHALL DOUGLAS W. SAUDER BE LIABLE TO ANY PARTY FOR DIRECT, // INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF // THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF DOUGLAS W. SAUDER // HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // DOUGLAS W. SAUDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT // NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A // PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" // BASIS, AND DOUGLAS W. SAUDER HAS NO OBLIGATION TO PROVIDE MAINTENANCE, // SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. // //============================================================================= #define DW_IMPLEMENTATION #include #include #include #include #include #include #include #include #include #include #include #include #include #include enum { kParseSuccess, kParseFail }; struct DwBodyPartStr { DwBodyPartStr(const DwString& aStr) : mString(aStr), mNext(0) {} DwString mString; DwBodyPartStr* mNext; }; class DwBodyParser { friend class DwBody; public: ~DwBodyParser(); private: DwBodyParser(const DwString& aStr, const DwString& aBoundaryStr); const DwString& Preamble() const { return mPreamble; } const DwString& Epilogue() const { return mEpilogue; } DwBodyPartStr* FirstBodyPart() const { return mFirstBodyPartStr; } int Parse(); int FindBoundary(size_t aStartPos, size_t* aBoundaryStart, size_t* aBoundaryEnd, size_t* isFinal) const; void AddPart(size_t start, size_t len); void DeleteParts(); const DwString mString; const DwString mBoundary; DwString mPreamble; DwBodyPartStr* mFirstBodyPartStr; DwString mEpilogue; }; DwBodyParser::DwBodyParser(const DwString& aStr, const DwString& aBoundary) : mString(aStr), mBoundary(aBoundary) { mFirstBodyPartStr = 0; Parse(); } DwBodyParser::~DwBodyParser() { DeleteParts(); } int DwBodyParser::Parse() { DeleteParts(); // Find the preamble size_t pos = 0; size_t boundaryStart, boundaryEnd, isFinal; int result; result = FindBoundary(pos, &boundaryStart, &boundaryEnd, &isFinal); if (result == kParseFail) { mPreamble = mEpilogue = ""; mFirstBodyPartStr = 0; return kParseFail; } int start = pos; int len = boundaryStart - pos; mPreamble = mString.substr(start, len); if ( boundaryStart < mString.size() && mString[boundaryStart] != '-' ) mPreamble += DW_EOL; // contrary to normal behaviour of // DwBody::Parse(), we _do_ want a newline // before the first boundary here. This is // necessary since FindBoundary() can't // make up it's mind on where the boundary // starts - on the leading \n or the first // '-'.. // Find the body parts pos = boundaryEnd; while (1) { result = FindBoundary(pos, &boundaryStart, &boundaryEnd, &isFinal); // NOTE: For enhanced fault tolerance we *accept* a missing last // boundary. // If no last boundary is found (but at leat a first one was // there) we just assume the end of the text ebing the end // of the last part. // By doing so we can safely parse some buggy MS Outlook // clients' messages. (khz, 12.06.2002) start = pos; if (result == kParseFail) { isFinal = true; len = mString.length() - pos; } else { len = boundaryStart - pos; } AddPart(start, len); if (result == kParseFail) { pos = mString.length(); } else { pos = boundaryEnd; } if (isFinal) { break; } } // Find the epilogue start = pos; len = mString.length() - pos; if( len ) mEpilogue = mString.substr(start, len); return kParseSuccess; } // checks whether [cur,end[ matches -*[\r\t ]*(\n|$) static bool isOnlyWhiteSpaceOrDashesUntilEndOfLine( const char * cur, const char * end ) { bool dashesStillAllowed = true; while ( cur < end ) switch( *cur ) { case ' ': case '\t': case '\r': dashesStillAllowed = false; ++cur; continue; case '\n': return true; case '-': if ( !dashesStillAllowed ) return false; ++cur; continue; default: return false; } // end of buffer is ok, too: return true; } int DwBodyParser::FindBoundary(size_t aStartPos, size_t* aBoundaryStart, size_t* aBoundaryEnd, size_t* aIsFinal) const { // Assume the starting position is the beginning of a line const char* buf = mString.data(); size_t pos = aStartPos; size_t endPos = mString.length(); size_t blen = mBoundary.length(); // Search for the first boundary. // The leading CR LF ('\n') is part of the boundary, but if there is // no preamble, there may be no leading CR LF ('\n'). // The case of no leading CR LF ('\n') is a special case that will occur // only when '-' is the first character of the body. if (buf[pos] == '-' && pos+blen+1 < endPos && buf[pos+1] == '-' && strncmp(&buf[pos+2], mBoundary.data(), blen) == 0 && isOnlyWhiteSpaceOrDashesUntilEndOfLine( buf + pos + blen + 2, buf + endPos ) ) { *aBoundaryStart = pos; pos += blen + 2; // Check for final boundary if (pos+1 < endPos && buf[pos] == '-' && buf[pos+1] == '-') { pos += 2; *aIsFinal = 1; } else { *aIsFinal = 0; } // Advance position past end of line while (pos < endPos) { if (buf[pos] == '\n') { ++pos; break; } ++pos; } *aBoundaryEnd = pos; return kParseSuccess; } int isFound = 0; while (pos+blen+2 < endPos) { // Case of leading LF if (buf[pos] == '\n' && buf[pos+1] == '-' && buf[pos+2] == '-' && strncmp(&buf[pos+3], mBoundary.data(), blen) == 0 && isOnlyWhiteSpaceOrDashesUntilEndOfLine( buf + pos + blen + 3, buf + endPos ) ) { *aBoundaryStart = pos; pos += blen + 3; isFound = 1; } // Case of leading CR LF else if (buf[pos] == '\r' && buf[pos+1] == '\n' && buf[pos+2] == '-' && pos+blen+3 < endPos && buf[pos+3] == '-' && strncmp(&buf[pos+4], mBoundary.data(), blen) == 0 && isOnlyWhiteSpaceOrDashesUntilEndOfLine( buf + pos + blen + 4, buf + endPos ) ) { *aBoundaryStart = pos; pos += blen + 4; isFound = 1; } if (isFound) { // Check for final boundary if (pos < endPos && buf[pos] == '-') { // NOTE: Since we must be fault tolerant for being able to // understand messaged that were damaged during // transportation we now accept final boundaries // ending with "-" instead of "--". // (khz, 12.06.2002) pos += 1; *aIsFinal = 1; // if there *is* the 2nd '-' we of course process it if (pos+1 < endPos && buf[pos+1] == '-') { pos += 1; } } else { *aIsFinal = 0; } // Advance position past end of line while (pos < endPos) { if (buf[pos] == '\n') { ++pos; break; } ++pos; } *aBoundaryEnd = pos; return kParseSuccess; } ++pos; } // Exceptional case: no boundary found *aBoundaryStart = *aBoundaryEnd = mString.length(); *aIsFinal = 1; return kParseFail; } void DwBodyParser::AddPart(size_t start, size_t len) { DwBodyPartStr* toAdd = new DwBodyPartStr(mString.substr(start, len)); if (toAdd != 0) { DwBodyPartStr* curr = mFirstBodyPartStr; if (curr == 0) { mFirstBodyPartStr = toAdd; return; } while (curr->mNext != 0) { curr = curr->mNext; } curr->mNext = toAdd; } } void DwBodyParser::DeleteParts() { DwBodyPartStr* curr = mFirstBodyPartStr; while (curr) { DwBodyPartStr* next = curr->mNext; delete curr; curr = next; } mFirstBodyPartStr = 0; } //========================================================================== const char* const DwBody::sClassName = "DwBody"; DwBody* (*DwBody::sNewBody)(const DwString&, DwMessageComponent*) = 0; DwBody* DwBody::NewBody(const DwString& aStr, DwMessageComponent* aParent) { if (sNewBody) { DwBody* newBody = sNewBody(aStr, aParent); //if( newBody ) // newBody->mFirstBodyPart = 0; return newBody; } else { return new DwBody(aStr, aParent); } } DwBody::DwBody() { mFirstBodyPart = 0; mMessage = 0; mClassId = kCidBody; mClassName = sClassName; } DwBody::DwBody(const DwBody& aBody) : DwMessageComponent(aBody), mBoundaryStr(aBody.mBoundaryStr), mPreamble(aBody.mPreamble), mEpilogue(aBody.mEpilogue) { mFirstBodyPart = 0; const DwBodyPart* firstPart = aBody.mFirstBodyPart; if (firstPart) { CopyBodyParts(firstPart); } mMessage = 0; const DwMessage* message = aBody.mMessage; if (message) { DwMessage* msg = (DwMessage*) message->Clone(); _SetMessage(msg); } mClassId = kCidBody; mClassName = sClassName; } DwBody::DwBody(const DwString& aStr, DwMessageComponent* aParent) : DwMessageComponent(aStr, aParent) { mFirstBodyPart = 0; mMessage = 0; mClassId = kCidBody; mClassName = sClassName; } DwBody::~DwBody() { if (mFirstBodyPart) { DeleteBodyParts(); } if (mMessage) { delete mMessage; } } const DwBody& DwBody::operator = (const DwBody& aBody) { if (this == &aBody) return *this; mBoundaryStr = aBody.mBoundaryStr; mPreamble = aBody.mPreamble; mEpilogue = aBody.mEpilogue; if (mFirstBodyPart) { DeleteBodyParts(); } const DwBodyPart* firstPart = aBody.FirstBodyPart(); if (firstPart) { CopyBodyParts(firstPart); } if (mMessage) { delete mMessage; } const DwMessage* message = aBody.Message(); if (message) { DwMessage* msg = (DwMessage*) message->Clone(); _SetMessage(msg); } if (mParent) { mParent->SetModified(); } return *this; } void DwBody::Parse() { mIsModified = 0; // Only types "multipart" and "message" need to be parsed, and // we cannot determine the type if there is no header. if (!mParent) { return; } // Get the content type from the headers DwEntity* entity = (DwEntity*) mParent; if (entity->Headers().HasContentType()) { const DwMediaType& contentType = entity->Headers().ContentType(); int type = contentType.Type(); int subtype = contentType.Subtype(); if (type == DwMime::kTypeMultipart) { mBoundaryStr = contentType.Boundary(); // Now parse body into body parts DwBodyParser parser(mString, mBoundaryStr); mPreamble = parser.Preamble(); mEpilogue = parser.Epilogue(); DwBodyPartStr* partStr = parser.FirstBodyPart(); while (partStr) { DwBodyPart* part = DwBodyPart::NewBodyPart(partStr->mString, this); part->Parse(); _AddBodyPart(part); partStr = partStr->mNext; } } else if (type == DwMime::kTypeMessage && subtype == DwMime::kSubtypeRfc822) { if (mMessage) mMessage->FromString(mString); else mMessage = DwMessage::NewMessage(mString, this); mMessage->Parse(); } } } void DwBody::Assemble() { if (!mIsModified) return; if (!mFirstBodyPart && !mMessage) return; if (!mParent) return; DwEntity* entity = (DwEntity*) mParent; /* DwString partStr; */ const DwMediaType& contentType = entity->Headers().ContentType(); int type = contentType.Type(); int subtype = contentType.Subtype(); if (type == DwMime::kTypeMultipart) { /* int len; */ mBoundaryStr = contentType.Boundary(); mString = ""; mString += mPreamble; DwBodyPart* part = mFirstBodyPart; while (part) { part->Assemble(); /* partStr = part->AsString(); len = mString.length(); if( ! ( ( (1 < len) && ('\n' == mString.at(len-1) ) && ('\n' == mString.at(len-2) ) ) || ( (2 < len) && ('\n' == mString.at(len-1) ) && ('\r' == mString.at(len-2) ) && ('\n' == mString.at(len-3) ) ) ) ) */ if ( part != mFirstBodyPart ) mString += DW_EOL; mString += "--"; mString += mBoundaryStr; /* len = partStr.length(); if( ! ( (0 < len) && ( ('\n' == partStr.at(0) ) || ('\r' == partStr.at(0) ) ) ) ) */ mString += DW_EOL; /* mString += partStr; */ mString += part->AsString(); part = part->Next(); } /* if( ! ( ( (1 < len) && ('\n' == mString.at(len-1) ) && ('\n' == mString.at(len-2) ) ) || ( (2 < len) && ('\n' == mString.at(len-1) ) && ('\r' == mString.at(len-2) ) && ('\n' == mString.at(len-3) ) ) ) ) */ mString += DW_EOL; mString += "--"; mString += mBoundaryStr; mString += "--"; mString += DW_EOL; mString += mEpilogue; mIsModified = 0; } else if (type == DwMime::kTypeMessage && subtype == DwMime::kSubtypeRfc822 && mMessage) { mMessage->Assemble(); mString = mMessage->AsString(); } else { // Empty block } } DwMessageComponent* DwBody::Clone() const { return new DwBody(*this); } DwBodyPart* DwBody::FirstBodyPart() const { return mFirstBodyPart; } void DwBody::AddBodyPart(DwBodyPart* aPart) { _AddBodyPart(aPart); SetModified(); } void DwBody::RemoveBodyPart(DwBodyPart* aPart) { _RemoveBodyPart(aPart); SetModified(); } DwMessage* DwBody::Message() const { return mMessage; } void DwBody::SetMessage(DwMessage* aMessage) { _SetMessage(aMessage); SetModified(); } void DwBody::_AddBodyPart(DwBodyPart* aPart) { aPart->SetParent(this); if (!mFirstBodyPart) { mFirstBodyPart = aPart; return; } DwBodyPart* part = mFirstBodyPart; while (part->Next()) { part = part->Next(); } part->SetNext(aPart); } void DwBody::_RemoveBodyPart(DwBodyPart* aPart) { if ( aPart->Parent() != this ) return; // caller error if ( !mFirstBodyPart ) return; // impossible if ( mFirstBodyPart == aPart ) { mFirstBodyPart = mFirstBodyPart->Next(); return; } DwBodyPart* part = mFirstBodyPart; while (part->Next()) { if ( part->Next() == aPart ) { part->SetNext(aPart->Next()); break; } part = part->Next(); } } void DwBody::_SetMessage(DwMessage* aMessage) { aMessage->SetParent(this); if (mMessage && mMessage != aMessage) { delete mMessage; } mMessage = aMessage; } void DwBody::DeleteBodyParts() { DwBodyPart* part = mFirstBodyPart; while (part) { DwBodyPart* nextPart = part->Next(); delete part; part = nextPart; } mFirstBodyPart = 0; } void DwBody::CopyBodyParts(const DwBodyPart* aFirst) { const DwBodyPart* part = aFirst; while (part) { DwBodyPart* newPart = (DwBodyPart*) part->Clone(); AddBodyPart(newPart); part = part->Next(); } } #if defined(DW_DEBUG_VERSION) void DwBody::PrintDebugInfo(std::ostream& aStrm, int /*aDepth*/) const { aStrm << "------------------ Debug info for DwBody class -----------------\n"; _PrintDebugInfo(aStrm); } #else void DwBody::PrintDebugInfo(std::ostream&, int) const {} #endif // defined(DW_DEBUG_VERSION) #if defined(DW_DEBUG_VERSION) void DwBody::_PrintDebugInfo(std::ostream& aStrm) const { DwMessageComponent::_PrintDebugInfo(aStrm); aStrm << "Boundary: " << mBoundaryStr << '\n'; aStrm << "Preamble: " << mPreamble << '\n'; aStrm << "Epilogue: " << mEpilogue << '\n'; aStrm << "Body Parts: "; int count = 0; DwBodyPart* bodyPart = mFirstBodyPart; if (bodyPart) { while (bodyPart) { if (count > 0) aStrm << ' '; aStrm << bodyPart->ObjectId(); bodyPart = (DwBodyPart*) bodyPart->Next(); ++count; } aStrm << '\n'; } else { aStrm << "(none)\n"; } aStrm << "Message: "; if (mMessage) { aStrm << mMessage->ObjectId() << '\n'; } else { aStrm << "(none)\n"; } } #else void DwBody::_PrintDebugInfo(std::ostream& ) const {} #endif // defined(DW_DEBUG_VERSION) void DwBody::CheckInvariants() const { #if defined(DW_DEBUG_VERSION) DwMessageComponent::CheckInvariants(); mBoundaryStr.CheckInvariants(); mPreamble.CheckInvariants(); mEpilogue.CheckInvariants(); DwBodyPart* bodyPart = mFirstBodyPart; while (bodyPart) { bodyPart->CheckInvariants(); bodyPart = (DwBodyPart*) bodyPart->Next(); } if (mMessage) { mMessage->CheckInvariants(); } #endif // defined(DW_DEBUG_VERSION) } mimelib1-1.1.4/mimelib/mechansm.cpp0000644000175000017500000001143111175345261016536 0ustar resivoresivo//============================================================================= // File: mechansm.cpp // Contents: Definitions for DwMechanism // Maintainer: Doug Sauder // WWW: http://www.fwb.gulf.net/~dwsauder/mimepp.html // // Copyright (c) 1996, 1997 Douglas W. Sauder // All rights reserved. // // IN NO EVENT SHALL DOUGLAS W. SAUDER BE LIABLE TO ANY PARTY FOR DIRECT, // INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF // THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF DOUGLAS W. SAUDER // HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // DOUGLAS W. SAUDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT // NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A // PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" // BASIS, AND DOUGLAS W. SAUDER HAS NO OBLIGATION TO PROVIDE MAINTENANCE, // SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. // //============================================================================= #define DW_IMPLEMENTATION #include #include #include #include #include const char* const DwMechanism::sClassName = "DwMechanism"; DwMechanism* (*DwMechanism::sNewMechanism)(const DwString&, DwMessageComponent*) = 0; DwMechanism* DwMechanism::NewMechanism(const DwString& aStr, DwMessageComponent* aParent) { if (sNewMechanism) { return sNewMechanism(aStr, aParent); } else { return new DwMechanism(aStr, aParent); } } DwMechanism::DwMechanism() { mCteEnum = DwMime::kCteNull; mClassId = kCidMechanism; mClassName = sClassName; } DwMechanism::DwMechanism(const DwMechanism& aMech) : DwFieldBody(aMech) { mCteEnum = aMech.mCteEnum; mClassId = kCidMechanism; mClassName = sClassName; } DwMechanism::DwMechanism(const DwString& aStr, DwMessageComponent* aParent) : DwFieldBody(aStr, aParent) { mCteEnum = DwMime::kCteNull; mClassId = kCidMechanism; mClassName = sClassName; } DwMechanism::~DwMechanism() { } const DwMechanism& DwMechanism::operator = (const DwMechanism& aCte) { if (this == &aCte) return *this; DwFieldBody::operator = (aCte); mCteEnum = aCte.mCteEnum; return *this; } int DwMechanism::AsEnum() const { return mCteEnum; } void DwMechanism::FromEnum(int aEnum) { mCteEnum = aEnum; EnumToString(); SetModified(); } void DwMechanism::Parse() { mIsModified = 0; StringToEnum(); } void DwMechanism::Assemble() { mIsModified = 0; } DwMessageComponent* DwMechanism::Clone() const { return new DwMechanism(*this); } void DwMechanism::EnumToString() { switch (mCteEnum) { case DwMime::kCte7bit: mString = "7bit"; break; case DwMime::kCte8bit: mString = "8bit"; break; case DwMime::kCteBinary: mString = "binary"; break; case DwMime::kCteBase64: mString = "base64"; break; case DwMime::kCteQuotedPrintable: mString = "quoted-printable"; break; } } void DwMechanism::StringToEnum() { if (mString.length() == 0) { mCteEnum = DwMime::kCteNull; return; } int ch = mString[0]; switch (ch) { case '7': if( DwStrcasecmp(mString, "7bit") == 0 ) { mCteEnum = DwMime::kCte7bit; } break; case '8': if (DwStrcasecmp(mString, "8bit") == 0) { mCteEnum = DwMime::kCte8bit; } break; case 'B': case 'b': if (DwStrcasecmp(mString, "base64") == 0) { mCteEnum = DwMime::kCteBase64; } else if (DwStrcasecmp(mString, "binary") == 0) { mCteEnum = DwMime::kCteBinary; } break; case 'Q': case 'q': if (DwStrcasecmp(mString, "quoted-printable") == 0) { mCteEnum = DwMime::kCteQuotedPrintable; } break; default: mCteEnum = DwMime::kCteUnknown; break; } } #if defined (DW_DEBUG_VERSION) void DwMechanism::PrintDebugInfo(std::ostream& aStrm, int /*aDepth*/) const { aStrm << "--------------- Debug info for DwMechanism class ---------------\n"; _PrintDebugInfo(aStrm); } #else void DwMechanism::PrintDebugInfo(std::ostream& , int ) const {} #endif // defined (DW_DEBUG_VERSION) #if defined (DW_DEBUG_VERSION) void DwMechanism::_PrintDebugInfo(std::ostream& aStrm) const { DwFieldBody::_PrintDebugInfo(aStrm); aStrm << "Cte enum: " << mCteEnum << '\n'; } #else void DwMechanism::_PrintDebugInfo(std::ostream& ) const {} #endif // defined (DW_DEBUG_VERSION) void DwMechanism::CheckInvariants() const { #if defined (DW_DEBUG_VERSION) DwFieldBody::CheckInvariants(); #endif // defined (DW_DEBUG_VERSION) } mimelib1-1.1.4/mimelib/basicmsg.cpp0000644000175000017500000002336611175345261016545 0ustar resivoresivo//============================================================================= // File: basicmsg.cpp // Contents: Definitions for BasicMessage // Maintainer: Doug Sauder // WWW: http://www.fwb.gulf.net/~dwsauder/mimepp.html // // Copyright (c) 1996, 1997 Douglas W. Sauder // All rights reserved. // // IN NO EVENT SHALL DOUGLAS W. SAUDER BE LIABLE TO ANY PARTY FOR DIRECT, // INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF // THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF DOUGLAS W. SAUDER // HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // DOUGLAS W. SAUDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT // NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A // PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" // BASIS, AND DOUGLAS W. SAUDER HAS NO OBLIGATION TO PROVIDE MAINTENANCE, // SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. // //============================================================================= #include #include #include "basicmsg.h" BasicMessage::BasicMessage() { mMessage = DwMessage::NewMessage(mEmptyString, 0); } BasicMessage::BasicMessage(DwMessage* aMsg) { mMessage = aMsg; } BasicMessage::~BasicMessage() { if (mMessage != 0) { delete mMessage; } } void BasicMessage::TakeMessage(DwMessage* aMsg) { // Delete the old DwMessage if (mMessage) { delete mMessage; } // Assign the new DwMessage mMessage = aMsg; } const DwString& BasicMessage::AsString() { // Assemble the DwMessage mMessage->Assemble(); // Return its string contents return mMessage->AsString(); } void BasicMessage::SetAutomaticFields() { DwHeaders& headers = mMessage->Headers(); headers.MimeVersion().FromString("1.0"); headers.MessageId().CreateDefault(); } const DwString& BasicMessage::DateStr() const { // Access the 'Date' header field and return its contents as a string DwHeaders& headers = mMessage->Headers(); if (headers.HasDate()) { return headers.Date().AsString(); } else { return mEmptyString; } } DwUint32 BasicMessage::Date() const { // Access the 'Date' header field and return its contents as a UNIX // time (i.e. POSIX time) DwHeaders& headers = mMessage->Headers(); if (headers.HasDate()) { return headers.Date().AsUnixTime(); } else { return (DwUint32) -1; } } void BasicMessage::SetDate(DwUint32 aUnixTime) { // Access the 'Date' header field and set its contents from a UNIX // time (i.e. POSIX time) mMessage->Headers().Date().FromUnixTime(aUnixTime); } const DwString& BasicMessage::To() const { // Access the 'To' header field and return its contents as a string DwHeaders& headers = mMessage->Headers(); if (headers.HasTo()) { return headers.To().AsString(); } else { return mEmptyString; } } void BasicMessage::SetTo(const DwString& aStr) { // Access the 'To' header field and set its contents from a string mMessage->Headers().To().FromString(aStr); } const DwString& BasicMessage::Cc() const { // Access the 'Cc' header field and return its contents as a string DwHeaders& headers = mMessage->Headers(); if (headers.HasCc()) { return headers.Cc().AsString(); } else { return mEmptyString; } } void BasicMessage::SetCc(const DwString& aStr) { // Access the 'Cc' header field and set its contents from a string mMessage->Headers().Cc().FromString(aStr); } const DwString& BasicMessage::Bcc() const { // Access the 'Bcc' header field and return its contents as a string DwHeaders& headers = mMessage->Headers(); if (headers.HasBcc()) { return headers.Bcc().AsString(); } else { return mEmptyString; } } void BasicMessage::SetBcc(const DwString& aStr) { // Access the 'Bcc' header field and set its contents from a string mMessage->Headers().Bcc().FromString(aStr); } const DwString& BasicMessage::From() const { // Access the 'From' header field and return its contents as a string DwHeaders& headers = mMessage->Headers(); if (headers.HasFrom()) { return headers.From().AsString(); } else { return mEmptyString; } } void BasicMessage::SetFrom(const DwString& aStr) { // Access the 'From' header field and set its contents from a string mMessage->Headers().From().FromString(aStr); } const DwString& BasicMessage::Subject() const { // Access the 'Subject' header field and return its contents as a string DwHeaders& headers = mMessage->Headers(); if (headers.HasSubject()) { return headers.Subject().AsString(); } else { return mEmptyString; } } void BasicMessage::SetSubject(const DwString& aStr) { // Access the 'Subject' header field and set its contents from a string mMessage->Headers().Subject().FromString(aStr); } const DwString& BasicMessage::TypeStr() const { // Access the 'Content-Type' header field and return its 'type' // as a string DwHeaders& headers = mMessage->Headers(); if (headers.HasContentType()) { return headers.ContentType().TypeStr(); } else { return mEmptyString; } } int BasicMessage::Type() const { // Access the 'Content-Type' header field and return its 'type' // as an enumerated type DwHeaders& headers = mMessage->Headers(); if (headers.HasContentType()) { return headers.ContentType().Type(); } else { return DwMime::kTypeNull; } } void BasicMessage::SetTypeStr(const DwString& aStr) { // Access the 'Content-Type' header field and set its 'type' // from a string mMessage->Headers().ContentType().SetTypeStr(aStr); } void BasicMessage::SetType(int aType) { // Access the 'Content-Type' header field and set its 'type' // from an enumerated type mMessage->Headers().ContentType().SetType(aType); } const DwString& BasicMessage::SubtypeStr() const { // Access the 'Content-Type' header field and return its 'subtype' // as a string DwHeaders& headers = mMessage->Headers(); if (headers.HasContentType()) { return headers.ContentType().SubtypeStr(); } else { return mEmptyString; } } int BasicMessage::Subtype() const { // Access the 'Content-Type' header field and return its 'subtype' // as an enumerated type DwHeaders& headers = mMessage->Headers(); if (headers.HasContentType()) { return headers.ContentType().Subtype(); } else { return DwMime::kSubtypeNull; } } void BasicMessage::SetSubtypeStr(const DwString& aStr) { // Access the 'Content-Type' header field and set its 'subtype' // from a string mMessage->Headers().ContentType().SetSubtypeStr(aStr); } void BasicMessage::SetSubtype(int aSubtype) { // Access the 'Content-Type' header field and set its 'subtype' // from an enumerated type mMessage->Headers().ContentType().SetSubtype(aSubtype); } const DwString& BasicMessage::ContentTransferEncodingStr() const { // Access the 'Content-Transfer-Encoding' header field and return // its contents as a string DwHeaders& headers = mMessage->Headers(); if (headers.HasContentTransferEncoding()) { return headers.ContentTransferEncoding().AsString(); } else { return mEmptyString; } } int BasicMessage::ContentTransferEncoding() const { // Access the 'Content-Transfer-Encoding' header field and return // its contents as an enumerated type DwHeaders& headers = mMessage->Headers(); if (headers.HasContentTransferEncoding()) { return headers.ContentTransferEncoding().AsEnum(); } else { return DwMime::kCteNull; } } void BasicMessage::SetContentTransferEncodingStr(const DwString& aStr) { // Access the 'Content-Transfer-Encoding' header field and set // its contents from a string mMessage->Headers().ContentTransferEncoding().FromString(aStr); } void BasicMessage::SetContentTransferEncoding(int aCte) { // Access the 'Content-Transfer-Encoding' header field and set // its contents from an enumerated type mMessage->Headers().ContentTransferEncoding().FromEnum(aCte); } const DwString& BasicMessage::CteStr() const { // Access the 'Content-Transfer-Encoding' header field and return // its contents as a string DwHeaders& headers = mMessage->Headers(); if (headers.HasContentTransferEncoding()) { return headers.ContentTransferEncoding().AsString(); } else { return mEmptyString; } } int BasicMessage::Cte() const { // Access the 'Content-Transfer-Encoding' header field and return // its contents as an enumerated type DwHeaders& headers = mMessage->Headers(); if (headers.HasContentTransferEncoding()) { return headers.ContentTransferEncoding().AsEnum(); } else { return DwMime::kCteNull; } } void BasicMessage::SetCteStr(const DwString& aStr) { // Access the 'Content-Transfer-Encoding' header field and set // its contents from a string mMessage->Headers().ContentTransferEncoding().FromString(aStr); } void BasicMessage::SetCte(int aCte) { // Access the 'Content-Transfer-Encoding' header field and set // its contents from an enumerated type mMessage->Headers().ContentTransferEncoding().FromEnum(aCte); } const DwString& BasicMessage::Body() const { // Access the message body and return its contents as a string const DwString& body = mMessage->Body().AsString(); return body; } void BasicMessage::SetBody(const DwString& aStr) { // Access the message body and set its contents from a string mMessage->Body().FromString(aStr); } mimelib1-1.1.4/mimelib/addrlist.cpp0000644000175000017500000002247411175345261016562 0ustar resivoresivo//============================================================================= // File: addrlist.cpp // Contents: Definitions for DwAddressList // Maintainer: Doug Sauder // WWW: http://www.fwb.gulf.net/~dwsauder/mimepp.html // // Copyright (c) 1996, 1997 Douglas W. Sauder // All rights reserved. // // IN NO EVENT SHALL DOUGLAS W. SAUDER BE LIABLE TO ANY PARTY FOR DIRECT, // INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF // THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF DOUGLAS W. SAUDER // HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // DOUGLAS W. SAUDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT // NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A // PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" // BASIS, AND DOUGLAS W. SAUDER HAS NO OBLIGATION TO PROVIDE MAINTENANCE, // SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. // //============================================================================= #define DW_IMPLEMENTATION #include #include #include #include #include #include #include #include #include #include #include const char* const DwAddressList::sClassName = "DwAddressList"; DwAddressList* (*DwAddressList::sNewAddressList)(const DwString&, DwMessageComponent*) = 0; DwAddressList* DwAddressList::NewAddressList(const DwString& aStr, DwMessageComponent* aParent) { if (sNewAddressList) { return sNewAddressList(aStr, aParent); } else { return new DwAddressList(aStr, aParent); } } DwAddressList::DwAddressList() { mFirstAddress = 0; mClassId = kCidAddressList; mClassName = sClassName; } DwAddressList::DwAddressList(const DwAddressList& aList) : DwFieldBody(aList) { mFirstAddress = 0; const DwAddress* addr = aList.mFirstAddress; if (addr) { CopyList(addr); } mClassId = kCidAddressList; mClassName = sClassName; } DwAddressList::DwAddressList(const DwString& aStr, DwMessageComponent* aParent) : DwFieldBody(aStr, aParent) { mFirstAddress = 0; mClassId = kCidAddressList; mClassName = sClassName; } DwAddressList::~DwAddressList() { if (mFirstAddress) { DeleteAll(); } } const DwAddressList& DwAddressList::operator = (const DwAddressList& aList) { if (this == &aList) return *this; DwFieldBody::operator = (aList); if (mFirstAddress) { DeleteAll(); } const DwAddress* addr = aList.mFirstAddress; if (addr) { CopyList(addr); } return *this; } DwMessageComponent* DwAddressList::Clone() const { return new DwAddressList(*this); } DwAddress* DwAddressList::FirstAddress() const { return mFirstAddress; } void DwAddressList::Add(DwAddress* aAddr) { aAddr->SetNext(0); aAddr->SetParent(this); if (!mFirstAddress) { mFirstAddress = aAddr; } else { DwAddress* addr = mFirstAddress; while (addr->Next()) { addr = (DwAddress*) addr->Next(); } addr->SetNext(aAddr); } SetModified(); } void DwAddressList::Remove(DwAddress* aAddr) { DwAddress* addr = mFirstAddress; if (addr == aAddr) { mFirstAddress = (DwAddress*) addr->Next(); aAddr->SetNext(0); return; } while (addr) { if (addr->Next() == aAddr) { addr->SetNext(aAddr->Next()); aAddr->SetNext(0); break; } } SetModified(); } void DwAddressList::DeleteAll() { DwAddress* addr = mFirstAddress; while (addr) { DwAddress* nextAddr = (DwAddress*) addr->Next(); delete addr; addr = nextAddr; } mFirstAddress = 0; } void DwAddressList::Parse() { mIsModified = 0; if (mFirstAddress) { DeleteAll(); } DwAddressListParser parser(mString); DwAddress* address; while (1) { switch (parser.AddrType()) { case DwAddressListParser::eAddrError: case DwAddressListParser::eAddrEnd: goto LOOP_EXIT; case DwAddressListParser::eAddrMailbox: address = DwMailbox::NewMailbox(parser.AddrString(), this); address->Parse(); if (address->IsValid()) { Add(address); } else { delete address; } break; case DwAddressListParser::eAddrGroup: address = DwGroup::NewGroup(parser.AddrString(), this); address->Parse(); if (address->IsValid()) { Add(address); } else { delete address; } break; case DwAddressListParser::eAddrNull: break; } ++parser; } LOOP_EXIT: return; } void DwAddressList::Assemble() { if (!mIsModified) return; mString = ""; int count = 0; DwAddress* addr = mFirstAddress; while (addr) { addr->Assemble(); if (addr->IsValid()) { if (count > 0){ if (IsFolding()) { mString += "," DW_EOL " "; } else { mString += ", "; } } mString += addr->AsString(); ++count; } addr = (DwAddress*) addr->Next(); } mIsModified = 0; } void DwAddressList::CopyList(const DwAddress* aFirstAddr) { const DwAddress* addr = aFirstAddr; while (addr) { DwAddress* newAddr = (DwAddress*) addr->Clone(); Add(newAddr); addr = (const DwAddress*) addr->Next(); } } #if defined (DW_DEBUG_VERSION) void DwAddressList::PrintDebugInfo(std::ostream& aStrm, int aDepth/*=0*/) const { aStrm << "-------------- Debug info for DwAddressList class --------------\n"; _PrintDebugInfo(aStrm); int depth = aDepth - 1; depth = (depth >= 0) ? depth : 0; if (aDepth == 0 || depth > 0) { DwAddress* addr = mFirstAddress; while (addr) { addr->PrintDebugInfo(aStrm, depth); addr = addr->Next(); } } } #else void DwAddressList::PrintDebugInfo(std::ostream&, int) const {} #endif // defined (DW_DEBUG_VERSION) #if defined (DW_DEBUG_VERSION) void DwAddressList::_PrintDebugInfo(std::ostream& aStrm) const { DwFieldBody::_PrintDebugInfo(aStrm); aStrm << "Address objects: "; DwAddress* addr = mFirstAddress; if (addr) { int count = 0; while (addr) { if (count > 0) aStrm << ' '; aStrm << addr->ObjectId(); addr = addr->Next(); ++count; } aStrm << '\n'; } else { aStrm << "(none)\n"; } } #else void DwAddressList::_PrintDebugInfo(std::ostream&) const {} #endif // defined (DW_DEBUG_VERSION) void DwAddressList::CheckInvariants() const { #if defined (DW_DEBUG_VERSION) DwAddress* addr = mFirstAddress; while (addr) { addr->CheckInvariants(); assert((DwMessageComponent*) this == addr->Parent()); addr = addr->Next(); } #endif // defined (DW_DEBUG_VERSION) } //------------------------------------------------------------------------- DwAddressListParser::DwAddressListParser(const DwString& aStr) : mTokenizer(aStr), mAddrString(aStr) { mAddrType = eAddrError; ParseNextAddress(); } DwAddressListParser::~DwAddressListParser() { } int DwAddressListParser::Restart() { mTokenizer.Restart(); ParseNextAddress(); return mAddrType; } int DwAddressListParser::operator ++ () { ParseNextAddress(); return mAddrType; } void DwAddressListParser::ParseNextAddress() { mAddrString.SetFirst(mTokenizer); mAddrType = eAddrEnd; int type = mTokenizer.Type(); if (type == eTkNull) { return; } enum { eTopLevel, eInGroup, eInRouteAddr } state; state = eTopLevel; // The type will be a mailbox, unless we discover otherwise mAddrType = eAddrMailbox; int done = 0; while (!done) { if (type == eTkNull) { mAddrString.ExtendTo(mTokenizer); break; } else if (type == eTkSpecial) { int ch = mTokenizer.Token()[0]; switch (state) { case eTopLevel: switch (ch) { case ',': mAddrString.ExtendTo(mTokenizer); done = 1; break; case '<': state = eInRouteAddr; break; case ':': mAddrType = eAddrGroup; state = eInGroup; break; } break; case eInRouteAddr: switch (ch) { case '>': state = eTopLevel; break; } break; case eInGroup: switch (ch) { case ';': state = eTopLevel; break; } break; } } ++mTokenizer; type = mTokenizer.Type(); } if (mAddrString.Tokens().length() == 0) { mAddrType = eAddrNull; } } mimelib1-1.1.4/mimelib/doc/0000755000175000017500000000000011175345261015004 5ustar resivoresivomimelib1-1.1.4/mimelib/doc/mimepp.html0000644000175000017500000000416611175345261017170 0ustar resivoresivo MIME++ Man Page

NAME

MIME++ -- C++ class library for creating, parsing, or modifying messages in MIME format

SYNOPSIS

#include <mimepp/mimepp.h>

DESCRIPTION

MIME++ is a C++ class library for creating, parsing, or modifying messages in Multipurpose Internet Mail Extensions (MIME) format. For information on the MIME standards, see RFC-822, RFC-1123, RFC-1521, RFC-1522, and RFC-1523.

Class Inheritance

  • DwString
  • DwMessageComponent
  • DwProtocolClient
  • DwBinhex
  • DwUuencode
  • DwBoyerMoore

    Utility Functions

    mimelib1-1.1.4/mimelib/doc/util.html0000644000175000017500000001135411175345261016653 0ustar resivoresivo MIME++ Utility Functions

    NAME

    MIME++ Utilities

    SYNOPSIS

    #include &ltmimepp/mimepp.h>
    
    void DwInitialize();
    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);
    int DwEncodeBase64(const DwString& aSrcStr, DwString& aDestStr);
    int DwDecodeBase64(const DwString& aSrcStr, DwString& aDestStr);
    int DwEncodeQuotedPrintable(const DwString& aSrcStr, DwString& aDestStr);
    int DwEncodeQuotedPrintable(const DwString& aSrcStr, DwString& aDestStr);
    

    DESCRIPTION

    void DwInitialize();

    Initializes the class library. Call this member function before creating any objects from MIME++ classes.

    int DwToCrLfEol(const DwString& aSrcStr, DwString& aDestStr);

    Converts all end-of-line markers in aSrcStr to CR LF and puts the result in aDestStr. The contract explicitly allows aSrcStr and aDestStr to be references to the same string.

    int DwToLfEol(const DwString& aSrcStr, DwString& aDestStr);

    Converts all end-of-line markers in aSrcStr to LF ('\n') and puts the result in aDestStr. The contract explicitly allows aSrcStr and aDestStr to be references to the same string.

    int DwToCrEol(const DwString& aSrcStr, DwString& aDestStr);

    Converts all end-of-line markers in aSrcStr to CR ('\r') and puts the result in aDestStr. The contract explicitly allows aSrcStr and aDestStr to be references to the same string.

    int DwToLocalEol(const DwString& aSrcStr, DwString& aDestStr);

    Converts all end-of-line markers in aSrcStr to the end-of-line marker native to the operating system and puts the result in aDestStr. The contract explicitly allows aSrcStr and aDestStr to be references to the same string.

    The end-of-line markers for various operating systems are the following:

       MS-DOS, WIN32     CR LF
       UNIX              LF
       Macintosh         CR
    

    int DwEncodeBase64(const DwString& aSrcStr, DwString& aDestStr);

    Encodes the characters in aSrcStr using the base64 encoding and puts the result into aDestStr. The contract explicitly allows aSrcStr and aDestStr to be references to the same string.

    int DwDecodeBase64(const DwString& aSrcStr, DwString& aDestStr);

    Decodes the characters in aSrcStr from the base64 encoding and puts the result into aDestStr. The contract explicitly allows aSrcStr and aDestStr to be references to the same string.

    int DwEncodeQuotedPrintable(const DwString& aSrcStr, DwString& aDestStr);

    Encodes the characters in aSrcStr using the quoted-printable encoding and puts the result into aDestStr. The contract explicitly allows aSrcStr and aDestStr to be references to the same string.

    int DwDecodeQuotedPrintable(const DwString& aSrcStr, DwString& aDestStr);

    Decodes the characters in aSrcStr from the quoted-printable encoding and puts the result into aDestStr. The contract explicitly allows aSrcStr and aDestStr to be references to the same string. mimelib1-1.1.4/mimelib/doc/addrlist.html0000644000175000017500000002171111175345261017502 0ustar resivoresivo DwAddressList Man Page

    NAME

    DwAddressList -- Class representing a list of RFC-822 addresses

    SYNOPSIS

    class DW_EXPORT DwAddressList : public DwFieldBody {
    
    public:
    
        DwAddressList();
        DwAddressList(const DwAddressList& aList);
        DwAddressList(const DwString& aStr, DwMessageComponent* aParent=0);
        virtual ~DwAddressList();
        const DwAddressList& operator = (const DwAddressList& aList);
        virtual void Parse();
        virtual void Assemble();
        virtual DwMessageComponent* Clone() const;
        DwAddress* FirstAddress() const;
        void Add(DwAddress* aAddr);
        void Remove(DwAddress* aAddr);
        void DeleteAll();
        static DwAddressList* NewAddressList(const DwString& aStr,
            DwMessageComponent* aParent);
        static DwAddressList* (*sNewAddressList)(const DwString&,
            DwMessageComponent*);
    
    protected:
    
        DwAddress* mFirstAddress;
    
    public:
    
        virtual void PrintDebugInfo(ostream& aStrm, int aDepth=0) const;
        virtual void CheckInvariants() const;
    
    protected:
    
        void _PrintDebugInfo(ostream& aStrm) const;
    };
    

    DESCRIPTION

    DwAddressList represents a list of addresses as described in RFC-822. In MIME++, DwAddressList is a container for objects of type DwAddress, and it contains various member functions to manage its contained objects. DwAddressList is also a DwFieldBody. This reflects the fact that certain RFC-822 header fields, such as the ``To'' header field, have a list of addresses as their field bodies.

    Public Member Functions

    DwAddressList()
    DwAddressList(const DwAddressList& aList)
    DwAddressList(const DwString& aStr, DwMessageComponent* aParent=0)

    The first constructor is the default constructor, which sets the DwAddressList object's string representation to the empty string and sets its parent to NULL.

    The second constructor is the copy constructor, which copies the string representation and all DwAddress objects from aList. The parent of the new DwAddressList object is set to NULL.

    The third constructor copies aStr to the DwAddressList object's string representation and sets aParent as its parent. The virtual member function Parse() should be called immediately after this constructor in order to parse the string representation. Unless it is NULL, aParent should point to an object of a class derived from DwField.

    const DwAddressList& operator = (const DwAddressList& aList)

    This is the assignment operator, which performs a deep copy of aList. The parent node of the DwAddressList object is not changed.

    virtual void Parse()

    This virtual function, inherited from DwMessageComponent, executes the parse method for DwAddressList objects. The parse method creates or updates the broken-down representation from the string representation. For DwAddressList objects, the parse method parses the string representation to create a list of DwAddress objects. This member function also calls the Parse() member function of each DwAddress object in its list.

    You should call this member function after you set or modify the string representation, and before you access any of the contained DwAddress objects.

    This function clears the is-modified flag.

    virtual void Assemble()

    This virtual function, inherited from DwMessageComponent, executes the assemble method for DwAddressList objects. The assemble method creates or updates the string representation from the broken-down representation. That is, the assemble method builds the string representation from its list of DwAddress objects. Before it builds the string representation for the DwAddressList object, this function first calls the Assemble() member function of each DwAddress object in its list.

    You should call this member function after you set or modify any of the contained DwAddress objects, and before you retrieve the string representation.

    This function clears the is-modified flag.

    virtual DwMessageComponent* Clone() const

    This virtual function, inherited from DwMessageComponent, creates a new DwAddressList on the free store that has the same value as this DwAddressList object. The basic idea is that of a virtual copy constructor.

    DwAddress* FirstAddress() const

    Gets the first DwAddress object in the list. Use the member function DwAddress::Next() to iterate. Returns NULL if the list is empty.

    void Add(DwAddress* aAddr)

    Adds aAddr to the end of the list of DwAddress objects maintained by this DwAddressList object.

    void Remove(DwAddress* aAddr)

    Removes aAddr from the list of DwAddress objects maintained by this DwAddressList object. The DwAddress object is not deleted by this member function.

    void DeleteAll()

    Removes and deletes all DwAddress objects from the list maintained by this DwAddressList object.

    static DwAddressList* NewAddressList(const DwString& aStr, DwMessageComponent* aParent)

    Creates a new DwAddressList object on the free store. If the static data member sNewAddressList is NULL, this member function will create a new DwAddressList and return it. Otherwise, NewAddressList() will call the user-supplied function pointed to by sNewAddressList, which is assumed to return an object from a class derived from DwAddressList, and return that object.

    virtual void PrintDebugInfo(ostream& aStrm, int aDepth=0) const

    This virtual function, inherited from DwMessageComponent, prints debugging information about this object to aStrm. It will also call PrintDebugInfo() for any of its child components down to a level of aDepth.

    This member function is available only in the debug version of the library.

    virtual void CheckInvariants() const

    Aborts if one of the invariants of the object fails. Use this member function to track down bugs.

    This member function is available only in the debug version of the library.

    Public Data Members

    static DwAddressList* (*sNewAddressList)(const DwString&, DwMessageComponent*)

    If sNewAddressList is not NULL, it is assumed to point to a user-supplied function that returns a pointer to an object from a class derived from DwAddressList.

    Protected Data Members

    DwAddress* mFirstAddress

    Points to first DwMailbox object in list.

    mimelib1-1.1.4/mimelib/doc/disptype.html0000644000175000017500000002275511175345261017546 0ustar resivoresivo DwDispositionType Man Page

    NAME

    DwDispositionType -- Class representing a MIME content-disposition field body

    SYNOPSIS

    class DW_EXPORT DwDispositionType : public DwFieldBody {
    
    public:
    
        DwDispositionType();
        DwDispositionType(const DwDispositionType& aDispType);
        DwDispositionType(const DwString& aStr, DwMessageComponent* aParent=0);
        virtual ~DwDispositionType();
        const DwDispositionType& operator = (const DwDispositionType& aDispType);
        virtual void Parse();
        virtual void Assemble();
        virtual DwMessageComponent* Clone() const;
        int DispositionType() const;
        void SetDispositionType(int aType);
        const DwString& DispositionTypeStr() const;
        void SetDispositionTypeStr(const DwString& aStr);
        const DwString& Filename() const;
        void SetFilename(const DwString& aStr);
        DwParameter* FirstParameter() const;
        void AddParameter(DwParameter* aParam);
        static DwDispositionType* NewDispositionType(const DwString& aStr,
            DwMessageComponent* aParent);
        static DwDispositionType* (*sNewDispositionType)(const DwString&,
            DwMessageComponent*);
    
    protected:
    
        void _AddParameter(DwParameter* aParam);
        virtual void EnumToStr();
        virtual void StrToEnum();
        void DeleteParameterList();
        void CopyParameterList(DwParameter* aFirst);
        int mDispositionType;
        DwString mDispositionTypeStr;
        DwString mFilenameStr;
        DwParameter* mFirstParameter;
    
    public:
    
        virtual void PrintDebugInfo(ostream& aStrm, int aDepth=0) const;
        virtual void CheckInvariants() const;
    
    protected:
    
        void _PrintDebugInfo(ostream& aStrm) const;
    };
    

    DESCRIPTION

    DwDispositionType represents a field body for the Content-Disposition header field as described in RFC-1806. This header field specifies whether the content of a message or body part should be displayed automatically to a user. A disposition-type of inline indicates that the content should be displayed; a disposition-type of attachment indicates that it should not be. RFC-1806 specifies that a filename parameter may be optionally included in the field body; the filename parameter suggests a file name for saving the message or body part's content.

    DwDispositionType provides convenience functions that allow you to set or get the disposition-type as an enumerated value, to set or get the filename parameter, or to manage a list of parameters.

    RFC-1806 specifically states that the Content-Disposition header field is experimental and not a proposed standard.

    Public Member Functions

    DwDispositionType()
    DwDispositionType(const DwDispositionType& aDispType)
    DwDispositionType(const DwString& aStr, DwMessageComponent* aParent=0)

    The first constructor is the default constructor, which sets the DwDispositionType object's string representation to the empty string and sets its parent to NULL.

    The second constructor is the copy constructor, which performs deep copy of aDispType. The parent of the new DwDispositionType object is set to NULL.

    The third constructor copies aStr to the DwDispositionType object's string representation and sets aParent as its parent. The virtual member function Parse() should be called immediately after this constructor in order to parse the string representation. Unless it is NULL, aParent should point to an object of a class derived from DwField.

    const DwDispositionType& operator = (const DwDispositionType& aDispType)

    This is the assignment operator, which performs a deep copy of aDispType. The parent node of the DwDipositionType object is not changed.

    virtual void Parse()

    This virtual function, inherited from DwMessageComponent, executes the parse method for DwDispositionType objects. It should be called immediately after the string representation is modified and before the parts of the broken-down representation are accessed.

    This function clears the is-modified flag.

    virtual void Assemble()

    This virtual function, inherited from DwMessageComponent, executes the assemble method for DwDispositionType objects. It should be called whenever one of the object's attributes is changed in order to assemble the string representation from its broken-down representation. It will be called automatically for this object by the parent object's Assemble() member function if the is-modified flag is set.

    This function clears the is-modified flag.

    virtual DwMessageComponent* Clone() const

    This virtual function, inherited from DwMessageComponent, creates a new DwDispositionType object on the free store that has the same value as this DwDispositionType object. The basic idea is that of a virtual copy constructor.

    int DispositionType() const

    Returns the disposition-type as an enumerated value. Valid enumerated types, which are defined in enum.h, include DwMime::kDispTypeNull, DwMime::kDispTypeUnknown, DwMime::kDispTypeInline, and DwMime::kDispTypeAttachment.

    void SetDispositionType(int aType)

    Sets the disposition-type from the enumerated value aType. Valid enumerated types, which are defined in enum.h, include DwMime::kDispTypeNull, DwMime::kDispTypeUnknown, DwMime::kDispTypeInline, and DwMime::kDispTypeAttachment.

    const DwString& DispositionTypeStr() const

    Returns the disposition-type as a string.

    void SetDispositionTypeStr(const DwString& aStr)

    Sets the disposition-type from a string.

    const DwString& Filename() const

    This convenience function returns the value from the filename parameter, if present. If no filename parameter is present, an empty string is returned.

    void SetFilename(const DwString& aStr)

    This convenience function sets the value of the filename parameter to aStr.

    DwParameter* FirstParameter() const

    Returns the first DwParameter object in the list managed by this DwDispositionType object, or NULL if no parameters are present. Use DwParameter::Next() to iterate through the list.

    void AddParameter(DwParameter* aParam)

    Adds a DwParameter object to the list managed by this DwDispositionType object.

    static DwDispositionType* NewDispositionType(const DwString& aStr, DwMessageComponent* aParent)

    Creates a new DwDispositionType object on the free store. If the static data member sNewDispositionType is NULL, this member function will create a new DwDispositionType and return it. Otherwise, NewDispositionType() will call the user-supplied function pointed to by sNewDispositionType, which is assumed to return an object from a class derived from DwDispositionType, and return that object.

    Public Data Members

    static DwDispositionType* (*sNewDispositionType)(const DwString&, DwMessageComponent*)

    If sNewDispositionType is not NULL, it is assumed to point to a user-supplied function that returns an object from a class derived from DwDispositionType.

    mimelib1-1.1.4/mimelib/doc/group.html0000644000175000017500000002202211175345261017024 0ustar resivoresivo DwGroup Man Page

    NAME

    DwGroup -- Class representing an RFC-822 address group

    SYNOPSIS

    class DW_EXPORT DwGroup : public DwAddress {
    
    public:
    
        DwGroup();
        DwGroup(const DwGroup& aGroup);
        DwGroup(const DwString& aStr, DwMessageComponent* aParent=0);
        virtual ~DwGroup();
        const DwGroup& operator = (const DwGroup& aGroup);
        virtual void Parse();
        virtual void Assemble();
        virtual DwMessageComponent* Clone() const;
        const DwString& GroupName() const;
        const DwString& Phrase() const;
        void SetGroupName(const DwString& aName);
        void SetPhrase(const DwString& aPhrase);
        DwMailboxList& MailboxList() const;
        static DwGroup* NewGroup(const DwString& aStr,
            DwMessageComponent* aParent);
        static DwGroup* (*sNewGroup)(const DwString&, DwMessageComponent*);
    
    protected:
    
        DwMailboxList* mMailboxList;
    
    public:
    
        virtual void PrintDebugInfo(ostream& aStrm, int aDepth=0) const;
        virtual void CheckInvariants() const;
    
    protected:
    
        void _PrintDebugInfo(ostream& aStrm) const;
    };
    

    DESCRIPTION

    DwGroup represents a group as described in RFC-822. A group contains a group name and a (possibly empty) list of mailboxes. In MIME++, a DwGroup object contains a string for the group name and a DwMailboxList object for the list of mailboxes.

    In the tree (broken-down) representation of message, a DwGroup object may be only an intermediate node, having both a parent and a single child node. Its parent node must be a DwField or a DwAddressList. Its child is a DwMailboxList.

    A DwGroup is a DwAddress, and therefore it can be included in a list of DwAddress objects. To get the next DwAddress object in a list, use the inherited member function DwAddress::Next().

    Public Member Functions

    DwGroup()
    DwGroup(const DwGroup& aGroup)
    DwGroup(const DwString& aStr, DwMessageComponent* aParent=0)

    The first constructor is the default constructor, which sets the DwGroup object's string representation to the empty string and sets its parent to NULL.

    The second constructor is the copy constructor, which performs a deep copy of aGroup. The parent of the new DwGroup object is set to NULL.

    The third constructor copies aStr to the DwGroup object's string representation and sets aParent as its parent. The virtual member function Parse() should be called immediately after this constructor in order to parse the string representation. Unless it is NULL, aParent should point to an object of a class derived from DwField or DwAddressList.

    const DwGroup& operator = (const DwGroup& aGroup)

    This is the assignment operator, which performs a deep copy of aGroup. The parent node of the DwGroup object is not changed.

    virtual void Parse()

    This virtual function, inherited from DwMessageComponent, executes the parse method for DwGroup objects. The parse method creates or updates the broken-down representation from the string representation. For DwGroup objects, the parse method parses the string representation to extract the group name and to create a DwMailboxList object from the list of mailboxes. This member function also calls the Parse() member function of the DwMailboxList object it creates.

    You should call this member function after you set or modify the string representation, and before you access the group name or the mailbox list.

    This function clears the is-modified flag.

    virtual void Assemble()

    This virtual function, inherited from DwMessageComponent, executes the assemble method for DwGroup objects. The assemble method creates or updates the string representation from the broken-down representation. That is, the assemble method builds the string representation from its group name and mailbox list. Before it builds the string representation, this function calls the Assemble() member function of its contained DwMailboxList object.

    You should call this member function after you set or modify either the group name or the contained DwMailboxList object, and before you retrieve the string representation.

    This function clears the is-modified flag.

    virtual DwMessageComponent* Clone() const

    This virtual function, inherited from DwMessageComponent, creates a new DwGroup on the free store that has the same value as this DwGroup object. The basic idea is that of a virtual copy constructor.

    const DwString& GroupName() const

    Returns the name of the group.

    const DwString& Phrase() const

    Returns the name of the phrase part of a group as described in RFC-822. The phrase is the same as the group name.

    void SetGroupName(const DwString& aName)

    Sets the name of the group.

    void SetPhrase(const DwString& aPhrase)

    Sets the name of the phrase part of a group as described in RFC-822. The phrase is the same as the group name.

    DwMailboxList& MailboxList() const

    Provides access to the list of mailboxes that is part of a group as described in RFC-822.

    static DwGroup* NewGroup(const DwString& aStr, DwMessageComponent* aParent)

    Creates a new DwGroup object on the free store. If the static data member sNewGroup is NULL, this member function will create a new DwGroup and return it. Otherwise, NewGroup() will call the user-supplied function pointed to by sNewGroup, which is assumed to return an object from a class derived from DwGroup, and return that object.

    virtual void PrintDebugInfo(ostream& aStrm, int aDepth=0) const

    This virtual function, inherited from DwMessageComponent, prints debugging information about this object to aStrm. It will also call PrintDebugInfo() for any of its child components down to a level of aDepth.

    This member function is available only in the debug version of the library.

    virtual void CheckInvariants() const

    Aborts if one of the invariants of the object fails. Use this member function to track down bugs.

    This member function is available only in the debug version of the library.

    Public Data Members

    static DwGroup* (*sNewGroup)(const DwString&, DwMessageComponent*)

    If sNewGroup is not NULL, it is assumed to point to a user-supplied function that returns an object from a class derived from DwGroup.

    Protected Data Members

    DwMailboxList* mMailboxList

    Points to the DwMailboxList object.

    mimelib1-1.1.4/mimelib/doc/fieldbdy.html0000644000175000017500000001331711175345261017461 0ustar resivoresivo DwFieldBody Man Page

    NAME

    DwFieldBody -- Class representing a MIME header field body

    SYNOPSIS

    class DW_EXPORT DwFieldBody : public DwMessageComponent {
    
        friend class DwField;
    
    public:
    
        DwFieldBody();
        DwFieldBody(const DwFieldBody& aFieldBody);
        DwFieldBody(const DwString& aStr, DwMessageComponent* aParent=0);
        virtual ~DwFieldBody();
        const DwFieldBody& operator = (const DwFieldBody& aFieldBody);
        void SetOffset(int aOffset);
        void SetFolding(DwBool aTrueOrFalse);
        DwBool IsFolding() const;
    
    protected:
    
        int mLineOffset;
        DwBool mDoFolding;
    
    public:
    
        virtual void PrintDebugInfo(ostream& aStrm, int aDepth=0) const;
        virtual void CheckInvariants() const;
    
    protected:
    
        void _PrintDebugInfo(ostream& aStrm) const;
    };
    

    DESCRIPTION

    DwFieldBody represents the field-body element in the BNF grammar specified by RFC-822. It is an abstract base class that defines the interface common to all structured field bodies.

    In the tree (broken-down) representation of a message, a DwFieldBody object may be either a leaf node, having a parent but no child nodes, or an intermediate node, having a parent and one or more child nodes. The parent node is the DwField object that contains it. Child nodes, if present, depend on the particular subclass of DwFieldBody that is instantiated. A DwAddressList object, for example, has DwAddress objects as its child nodes.

    Since DwFieldBody is an abstract base class, you cannot create instances of it directly. Normally, objects of classes derived from DwFieldBody are obtained by calling convenience member functions in the class DwHeaders.

    Some MIME parsers are broken in that they do not handle the folding of some fields properly. DwFieldBody folds its string representation by default. You can disable folding, however, by calling the SetFolding() member function. To determine if folding is enabled, call IsFolding().

    Public Member Functions

    DwFieldBody()
    DwFieldBody(const DwFieldBody& aFieldBody)
    DwFieldBody(const DwString& aStr, DwMessageComponent* aParent=0)

    The first constructor is the default constructor, which sets the DwFieldBody object's string representation to the empty string and sets its parent to NULL.

    The second constructor is the copy constructor, which performs a deep copy of aFieldBody. The parent of the new DwFieldBody object is set to NULL.

    The third constructor copies aStr to the DwFieldBody object's string representation and sets aParent as its parent. The virtual member function Parse() should be called immediately after this constructor in order to parse the string representation. Unless it is NULL, aParent should point to an object of a class derived from DwField.

    const DwFieldBody& operator = (const DwFieldBody& aFieldBody)

    This is the assignment operator, which performs a deep copy of aFieldBody. The parent node of the DwFieldBody object is not changed.

    void SetOffset(int aOffset)

    Sets the offset to aOffset. The offset is used when folding lines. It indicates how much the first line should be offset to account for the field name, colon, and initial white space.

    void SetFolding(DwBool aTrueOrFalse)

    Enables (aTrueOrFalse = DwTrue) or disables (aTrueOrFalse = DwFalse) the folding of fields. The default is to fold fields. Unfortunately, some parsers are broke and do not handle folded lines properly. This function allows a kludge to deal with these broken parsers.

    DwBool IsFolding() const

    Returns a boolean indicating if folding of fields is enabled.

    virtual void PrintDebugInfo(ostream& aStrm, int aDepth=0) const

    This virtual function, inherited from DwMessageComponent, prints debugging information about this object to aStrm. It will also call PrintDebugInfo() for any of its child components down to a level of aDepth.

    This member function is available only in the debug version of the library.

    virtual void CheckInvariants() const

    Aborts if one of the invariants of the object fails. Use this member function to track down bugs.

    This member function is available only in the debug version of the library.

    mimelib1-1.1.4/mimelib/doc/mediatyp.html0000644000175000017500000003314711175345261017516 0ustar resivoresivo DwMediaType Man Page

    NAME

    DwMediaType -- Class representing a MIME media-type

    SYNOPSIS

    class DW_EXPORT DwMediaType : public DwFieldBody {
    
    public:
    
        DwMediaType();
        DwMediaType(const DwMediaType& aMediaType);
        DwMediaType(const DwString& aStr, DwMessageComponent* aParent=0);
        virtual ~DwMediaType();
        const DwMediaType& operator = (const DwMediaType& aMediaType);
        virtual void Parse();
        virtual void Assemble();
        virtual DwMessageComponent* Clone() const;
        int Type() const;
        void SetType(int aType);
        const DwString& TypeStr() const;
        void SetTypeStr(const DwString& aStr);
        int Subtype() const;
        void SetSubtype(int aSubtype);
        const DwString& SubtypeStr() const;
        void SetSubtypeStr(const DwString& aStr);
        const DwString& Boundary() const;
        void SetBoundary(const DwString& aStr);
        virtual void CreateBoundary(unsigned aLevel=0);
        const DwString& Name() const;
        void SetName(const DwString& aStr);
        DwParameter* FirstParameter() const;
        void AddParameter(DwParameter* aParam);
        static DwMediaType* NewMediaType(const DwString& aStr,
            DwMessageComponent* aParent);
        static DwMediaType* (*sNewMediaType)(const DwString&,
            DwMessageComponent*);
    
    protected:
    
        void _AddParameter(DwParameter* aParam);
        virtual void TypeEnumToStr();
        virtual void TypeStrToEnum();
        virtual void SubtypeEnumToStr();
        virtual void SubtypeStrToEnum();
        void DeleteParameterList();
        void CopyParameterList(DwParameter* aFirst);
        int mType;
        int mSubtype;
        DwString mTypeStr;
        DwString mSubtypeStr;
        DwString mBoundaryStr;
        DwString mNameStr;
        DwParameter* mFirstParameter;
    
    public:
    
        virtual void PrintDebugInfo(ostream& aStrm, int aDepth=0) const;
        virtual void CheckInvariants() const;
    
    protected:
    
        void _PrintDebugInfo(ostream& aStrm) const;
    };
    

    DESCRIPTION

    DwMediaType represents a field body for the Content-Type header field as described in RFC-2045. This field body specifies the kind of data contained in the body of a message or a body part. A media type is described by two keywords: a primary type (or just type) and a subtype. RFC-2046 specifies the seven primary types text, multipart, message, image, audio, video, and application. RFC-2077 adds the new primary type model.

    DwMediaType has member functions that allow you to set or get the type and subtype as either enumerated values or as strings. It also contains a list of DwParameter objects that represent the parameters of the field body. You can use convenience functions to directly access the boundary parameter of a multipart media type, or to access the name parameter that is often used with several media types, such as application/octet-stream.

    Some MIME parsers have problems with folded header fields, and this especially seems to be a problem with the Content-Type field. To disable folding when the DwMediaType object is assembled, call the inherited member function DwFieldBody::SetFolding() with an argument of DwFalse.

    Public Member Functions

    DwMediaType()
    DwMediaType(const DwMediaType& aMediaType)
    DwMediaType(const DwString& aStr, DwMessageComponent* aParent=0)

    The first constructor is the default constructor, which sets the DwMediaType object's string representation to the empty string and sets its parent to NULL.

    The second constructor is the copy constructor, which performs deep copy of aMediaType. The parent of the new DwMediaType object is set to NULL.

    The third constructor copies aStr to the DwMediaType object's string representation and sets aParent as its parent. The virtual member function Parse() should be called immediately after this constructor in order to parse the string representation. Unless it is NULL, aParent should point to an object of a class derived from DwField.

    const DwMediaType& operator = (const DwMediaType& aMediaType)

    This is the assignment operator, which performs a deep copy of aMediaType. The parent node of the DwMediaType object is not changed.

    virtual void Parse()

    This virtual function, inherited from DwMessageComponent, executes the parse method for DwMediaType objects. It should be called immediately after the string representation is modified and before the parts of the broken-down representation are accessed.

    This function clears the is-modified flag.

    virtual void Assemble()

    This virtual function, inherited from DwMessageComponent, executes the assemble method for DwMediaType objects. It should be called whenever one of the object's attributes is changed in order to assemble the string representation from its broken-down representation. It will be called automatically for this object by the parent object's Assemble() member function if the is-modified flag is set.

    This function clears the is-modified flag.

    virtual DwMessageComponent* Clone() const

    This virtual function, inherited from DwMessageComponent, creates a new DwMediaType object on the free store that has the same value as this DwMediaType object. The basic idea is that of a virtual copy constructor.

    int Type() const

    Returns the primary type as an enumerated value. Enumerated values are defined for all standard types in the file enum.h. If the type is non-standard, DwMime::kTypeUnknown is returned. The member function TypeStr() may be used to get the value of any type, standard or non-standard, as a string.

    void SetType(int aType)

    Sets the primary type from the enumerated value aType. Enumerated values are defined for all standard types in the file enum.h. The member function SetTypeStr() may be used to set the value of any type, standard or non-standard, from a string.

    const DwString& TypeStr() const

    Returns the primary type as a string.

    void SetTypeStr(const DwString& aStr)

    Sets the primary type from a string.

    int Subtype() const

    Returns the subtype as an enumerated value. Enumerated values are defined for all standard subtypes in the file enum.h. If the subtype is non-standard, DwMime::kSubtypeUnknown is returned. The member function SubtypeStr() may be used to get the value of any subtype, standard or non-standard, as a string.

    void SetSubtype(int aSubtype)

    Sets the subtype from the enumerated value aSubtype. Enumerated values are defined for all standard subtypes in the file enum.h. The member function SetSubtypeStr() may be used to set the value of any subtype, standard or non-standard, from a string.

    const DwString& SubtypeStr() const

    Returns the subtype as a string.

    void SetSubtypeStr(const DwString& aStr)

    Sets the subtype from a string.

    const DwString& Boundary() const

    For the multipart type only, returns the value of the boundary parameter. This member function is a convenience function that searches the list of DwParameter objects.

    void SetBoundary(const DwString& aStr)

    For the multipart type only, sets the value of the boundary parameter. This member function is a convenience function that accesses the list of DwParameter objects.

    virtual void CreateBoundary(unsigned aLevel=0)

    For the multipart type only, creates a boundary string. aLevel indicates the level of a nested multipart body part; if it is positive, it is used to form part of the created boundary string. This member function is a convenience function that accesses the list of child DwParameter objects.

    const DwString& Name() const

    Returns the value of the "name" parameter, if such a parameter is present. The name parameter is often found in several media types, including the application/octet-stream media type; it suggests a file name for saving to a disk file. (The filename parameter in the Content-Disposition header field is an alternative way to indicate a file name.) This member function is a convenience function that searches the list of DwParameter objects.

    void SetName(const DwString& aStr)

    Sets the value of the "name" parameter. If a name parameter is not already present, it is added. The name parameter is often found in several media types, including the application/octet-stream media type; it suggests a file name for saving to a disk file. (The filename parameter in the Content-Disposition header field is an alternative way to indicate a file name.) This member function is a convenience function that accesses the list of DwParameter objects.

    DwParameter* FirstParameter() const

    Returns the first DwParameter object in the list managed by this DwMediaType object. Use DwParameter::Next() to iterate through the list.

    void AddParameter(DwParameter* aParam)

    Adds a DwParameter object to the list managed by this DwMediaType object.

    static DwMediaType* NewMediaType(const DwString& aStr, DwMessageComponent* aParent)

    Creates a new DwMediaType object on the free store. If the static data member sNewMediaType is NULL, this member function will create a new DwMediaType and return it. Otherwise, NewMediaType() will call the user-supplied function pointed to by sNewMediaType, which is assumed to return an object from a class derived from DwMediaType, and return that object.

    virtual void PrintDebugInfo(ostream& aStrm, int aDepth=0) const

    This virtual function, inherited from DwMessageComponent, prints debugging information about this object to aStrm. It will also call PrintDebugInfo() for any of its child components down to a level of aDepth.

    This member function is available only in the debug version of the library.

    virtual void CheckInvariants() const

    Aborts if one of the invariants of the object fails. Use this member function to track down bugs.

    This member function is available only in the debug version of the library.

    Public Data Members

    static DwMediaType* (*sNewMediaType)(const DwString&, DwMessageComponent*)

    If sNewMediaType is not NULL, it is assumed to point to a user-supplied function that returns an object from a class derived from DwMediaType. mimelib1-1.1.4/mimelib/doc/datetime.html0000644000175000017500000003335611175345261017500 0ustar resivoresivo DwDateTime Man Page

    NAME

    DwDateTime -- Class representing an RFC-822 date-time

    SYNOPSIS

    class DW_EXPORT DwDateTime : public DwFieldBody {
    
    public:
    
        DwDateTime();
        DwDateTime(const DwDateTime& aDateTime);
        DwDateTime(const DwString& aStr, DwMessageComponent* aParent=0);
        virtual ~DwDateTime();
        const DwDateTime& operator = (const DwDateTime& aDateTime);
        virtual void Parse();
        virtual void Assemble();
        virtual DwMessageComponent* Clone() const;
        DwUint32 AsUnixTime() const;
        void FromUnixTime(DwUint32 aTime);
        time_t AsCalendarTime() const;
        void FromCalendarTime(time_t aTime);
        DwInt32 DateAsJulianDayNum() const;
        void DateFromJulianDayNum(DwInt32 aJdn);
        DwInt32 TimeAsSecsPastMidnight() const;
        void TimeFromSecsPastMidnight(DwInt32 aSecs);
        int Year() const;
        void SetYear(int aYear);
        int Month() const;
        void SetMonth(int aMonth);
        int Day() const;
        void SetDay(int aDay);
        int Hour() const;
        void SetHour(int aHour);
        int Minute() const;
        void SetMinute(int aMinute);
        int Second() const;
        void SetSecond(int aSecond);
        int Zone() const;
        void SetZone(int aZone);
        static void SetDefaultZone(int aZone);
        static DwDateTime* NewDateTime(const DwString&, DwMessageComponent*);
        static DwDateTime* (*sNewDateTime)(const DwString&, DwMessageComponent*);
    
    protected:
    
        void _FromUnixTime(DwUint32 aTime);
        void _FromCalendarTime(time_t aTime);
        int  mYear;
        int  mMonth;
        int  mDay;
        int  mHour;
        int  mMinute;
        int  mSecond;
        int  mZone;
        static int sDefaultZone;
        static int sIsDefaultZoneSet;
    
    public:
    
        virtual void PrintDebugInfo(ostream& aStrm, int aDepth=0) const;
        virtual void CheckInvariants() const;
    
    protected:
    
        void _PrintDebugInfo(ostream& aStrm) const;
    };
    

    DESCRIPTION

    DwDatetime represents a date-time as described in RFC-822 and RFC-1123. The parse method for DwDateTime parses the string representation to extract the year, month, day, hour, minute, second, and time zone. DwDateTime provides member functions to set or get the individual components of the date-time.

    Public Member Functions

    DwDateTime()
    DwDateTime(const DwDateTime& aDateTime)
    DwDateTime(const DwString& aStr, DwMessageComponent* aParent=0)

    The first constructor is the default constructor, which assigns the current date and time as reported by the operating system.

    The second constructor is the copy constructor. The parent of the new DwDateTime object is set to NULL.

    The third constructor sets aStr as the DwDateTime object's string representation and sets aParent as its parent. The virtual member function Parse() should be called after this constructor to extract the date and time information from the string representation. Unless it is NULL, aParent should point to an object of a class derived from DwField.

    const DwDateTime& operator = (const DwDateTime& aDateTime)

    This is the assignment operator, which sets this DwDateTime object to the same value as aDateTime.

    virtual void Parse()

    This virtual function, inherited from DwMessageComponent, executes the parse method for DwDateTime objects. The parse method creates or updates the broken-down representation from the string representation. For DwDateTime objects, the parse method parses the string representation to extract the year, month, day, hour, minute, second, and time zone.

    This function clears the is-modified flag.

    virtual void Assemble()

    This virtual function, inherited from DwMessageComponent, executes the assemble method for DwDateTime objects. It should be called whenever one of the object's attributes is changed in order to assemble the string representation from its broken-down representation. It will be called automatically for this object by the parent object's Assemble() member function if the is-modified flag is set.

    This function clears the is-modified flag.

    virtual DwMessageComponent* Clone() const

    This virtual function, inherited from DwMessageComponent, creates a new DwDateTime on the free store that has the same value as this DwDateTime object. The basic idea is that of a virtual copy constructor.

    DwUint32 AsUnixTime() const

    Returns the date and time as a UNIX (POSIX) time, defined as the number of seconds elapsed since 1 Jan 1970 00:00:00 UTC.

    void FromUnixTime(DwUint32 aTime)

    Sets the date and time from aTime, interpreted as the number of of seconds elapsed since 1 Jan 1970 00:00:00 UTC.

    time_t AsCalendarTime() const

    Returns the date and time as a value of type time_t that conforms to the native format returned by the time() ANSI C function. On most UNIX systems, this function returns the same value as AsUnixTime(). (For efficiency, use AsUnixTime() instead of AsCalendarTime() if possible).

    void FromCalendarTime(time_t aTime)

    Sets the date and time from aTime, which is assumed to be in a format compatible with the native time() ANSI C function. For most UNIX systems, this function is the same as the function FromUnixTime(). (For efficiency, use FromUnixTime() instead of FromCalendarTime() if possible).

    DwInt32 DateAsJulianDayNum() const

    Returns the Julian Day Number, defined as the number of days elapsed since 1 Jan 4713 BC. The JDN is calculated directly from the values of the year, month, and day; time zone information is ignored.

    void DateFromJulianDayNum(DwInt32 aJdn)

    Sets the year, month, and day from aJdn, interpreted as a Julian Day Number. By definition, the JDN is the number of days elapsed since 1 Jan 4713 BC. This member function ignores time zone information.

    DwInt32 TimeAsSecsPastMidnight() const

    Returns the number of seconds past midnight. The value is calculated directly from the values of the hour, minute, and second; time zone information is ignored.

    void TimeFromSecsPastMidnight(DwInt32 aSecs)

    Sets the hour, minute, and second from aSecs, interpreted as the number of seconds elapsed since midnight. This member function ignores time zone information. The argument aSecs should be in the range 0 to 86399, inclusive.

    int Year() const

    Returns the four digit year, e.g. 1997.

    void SetYear(int aYear)

    Sets the year from aYear, which should be a four digit year.

    int Month() const

    Returns the month. Values range from 1 to 12.

    void SetMonth(int aMonth)

    Sets the month from aMonth, which should be in the range 1 to 12.

    int Day() const

    Returns the day of the month. Values range from 1 to 31.

    void SetDay(int aDay)

    Sets the day of the month from aDay.

    int Hour() const

    Returns the hour according to the 24 hour clock. Values range from 0 to 23.

    void SetHour(int aHour)

    Sets the hour from aHour based on the 24-hour clock. aHour should be in the range 0 to 23.

    int Minute() const

    Returns the minute. Values range from 0 to 59.

    void SetMinute(int aMinute)

    Sets the minute from aMinute, which should be in the range 0 to 59.

    int Second() const

    Returns the second. Values range from 0 to 59.

    void SetSecond(int aSecond)

    Sets the second from aSecond, which should be in the range 0 to 59.

    int Zone() const

    Returns the time zone as the diffence in minutes between local time and Coordinated Universal Time (UTC or GMT).

    void SetZone(int aZone)

    Sets the time zone from aZone, interpreted as the time difference in minutes between local time and Coordinated Universal Time (UTC, or GMT).

    static void SetDefaultZone(int aZone)

    Sets the default time zone. aZone should be the time difference in minutes between local time and Coordinated Universal Time (UTC, or GMT). The value is used to set the time zone for any objects created using the default constructor.

    static DwDateTime* NewDateTime(const DwString&, DwMessageComponent*)

    Creates a new DwDateTime object on the free store. If the static data member sNewDateTime is NULL, this member function will create a new DwDateTime and return it. Otherwise, NewDateTime() will call the user-supplied function pointed to by sNewDateTime, which is assumed to return an object from a class derived from DwDateTime, and return that object.

    virtual void PrintDebugInfo(ostream& aStrm, int aDepth=0) const

    This virtual function, inherited from DwMessageComponent, prints debugging information about this object to aStrm.

    This member function is available only in the debug version of the library.

    virtual void CheckInvariants() const

    Aborts if one of the invariants of the object fails. Use this member function to track down bugs.

    This member function is available only in the debug version of the library.

    Public Data Members

    static DwDateTime* (*sNewDateTime)(const DwString&, DwMessageComponent*)

    If sNewDateTime is not NULL, it is assumed to point to a user-supplied function that returns an object from a class derived from DwDateTime.

    Protected Member Functions

    void _FromUnixTime(DwUint32 aTime)

    Like FromUnixTime(), but doesn't set the is-modified flag.

    void _FromCalendarTime(time_t aTime)

    Like FromCalendarTime(), but doesn't set the is-modified flag.

    mimelib1-1.1.4/mimelib/doc/mboxlist.html0000644000175000017500000002317411175345261017542 0ustar resivoresivo DwMailboxList Man Page

    NAME

    DwMailboxList -- Class representing a list of RFC-822 mailboxes

    SYNOPSIS

    class DW_EXPORT DwMailboxList : public DwFieldBody {
    
    public:
    
        DwMailboxList();
        DwMailboxList(const DwMailboxList& aList);
        DwMailboxList(const DwString& aStr, DwMessageComponent* aParent=0);
        virtual ~DwMailboxList();
        const DwMailboxList& operator = (const DwMailboxList& aList);
        virtual void Parse();
        virtual void Assemble();
        virtual DwMessageComponent* Clone() const;
        DwMailbox* FirstMailbox() const;
        void Add(DwMailbox* aMailbox);
        void Remove(DwMailbox* aMailbox);
        void DeleteAll();
        static DwMailboxList* NewMailboxList(const DwString& aStr,
            DwMessageComponent* aParent);
        static DwMailboxList* (*sNewMailboxList)(const DwString&,
            DwMessageComponent*);
    
    protected:
    
        DwMailbox* mFirstMailbox;
        void _AddMailbox(DwMailbox* aMailbox);
        void _DeleteAll();
    
    public:
    
        virtual void PrintDebugInfo(ostream& aStrm, int aDepth=0) const;
        virtual void CheckInvariants() const;
    
    protected:
    
        void _PrintDebugInfo(ostream& aStrm) const;
    };
    

    DESCRIPTION

    DwMailboxList represents a list of mailboxes as described in RFC-822. In MIME++, DwMailboxList is a container for objects of type DwMailbox, and it contains various member functions to manage its contained objects. DwAddressList is also a DwFieldBody. This reflects the fact that certain RFC-822 header fields, such as the "From" header field, have a list of mailboxes as their field bodies.

    Public Member Functions

    DwMailboxList()
    DwMailboxList(const DwMailboxList& aList)
    DwMailboxList(const DwString& aStr, DwMessageComponent* aParent=0)

    The first constructor is the default constructor, which sets the DwMailboxList object's string representation to the empty string and sets its parent to NULL.

    The second constructor is the copy constructor, which copies the string representation and all DwMailbox objects from aList. The parent of the new DwMailboxList object is set to NULL.

    The third constructor copies aStr to the DwMailboxList object's string representation and sets aParent as its parent. The virtual member function Parse() should be called immediately after this constructor in order to parse the string representation. Unless it is NULL, aParent should point to an object of a class derived from DwField.

    const DwMailboxList& operator = (const DwMailboxList& aList)

    This is the assignment operator, which performs a deep copy of aList. The parent node of the DwMailboxList object is not changed.

    virtual void Parse()

    This virtual function, inherited from DwMessageComponent, executes the parse method for DwMailboxList objects. The parse method creates or updates the broken-down representation from the string representation. For DwMailboxList objects, the parse method parses the string representation to create a list of DwMailbox objects. This member function also calls the Parse() member function of each DwMailbox object in its list.

    You should call this member function after you set or modify the string representation, and before you access any of the contained DwMailbox objects.

    This function clears the is-modified flag.

    virtual void Assemble()

    This virtual function, inherited from DwMessageComponent, executes the assemble method for DwMailboxList objects. The assemble method creates or updates the string representation from the broken-down representation. For DwMailboxList objects, the assemble method builds the string representation from its list of DwMailbox objects. Before it builds the string representation for the DwMailboxList object, this function first calls the Assemble() member function of each DwMailbox object in its list.

    You should call this member function after you set or modify any of the contained DwMailbox objects, and before you retrieve the string representation.

    This function clears the is-modified flag.

    virtual DwMessageComponent* Clone() const

    This virtual function, inherited from DwMessageComponent, creates a new DwMailboxList on the free store that has the same value as this DwMailboxList object. The basic idea is that of a virtual copy constructor.

    DwMailbox* FirstMailbox() const

    Gets the first DwMailbox object in the list. Use the member function DwMailbox::Next() to iterate. Returns NULL if the list is empty.

    void Add(DwMailbox* aMailbox)

    Adds aMailbox to the end of the list of DwMailbox objects maintained by this DwMailboxList object.

    void Remove(DwMailbox* aMailbox)

    Removes aMailbox from the list of DwMailbox objects maintained by this DwMailboxList object. The DwMailbox object is not deleted by this member function.

    void DeleteAll()

    Removes and deletes all DwMailbox objects from the list maintained by this DwMailboxList object.

    static DwMailboxList* NewMailboxList(const DwString& aStr, DwMessageComponent* aParent)

    Creates a new DwMailboxList object on the free store. If the static data member sNewMailboxList is NULL, this member function will create a new DwMailboxList and return it. Otherwise, NewMailboxList() will call the user-supplied function pointed to by sNewMailboxList, which is assumed to return an object from a class derived from DwMailboxList, and return that object.

    virtual void PrintDebugInfo(ostream& aStrm, int aDepth=0) const

    This virtual function, inherited from DwMessageComponent, prints debugging information about this object to aStrm. It will also call PrintDebugInfo() for any of its child components down to a level of aDepth.

    This member function is available only in the debug version of the library.

    virtual void CheckInvariants() const

    Aborts if one of the invariants of the object fails. Use this member function to track down bugs.

    This member function is available only in the debug version of the library.

    Public Data Members

    static DwMailboxList* (*sNewMailboxList)(const DwString&, DwMessageComponent*)

    If sNewMailboxList is not NULL, it is assumed to point to a user-supplied function that returns an object from a class derived from DwMailboxList.

    Protected Member Functions

    void _AddMailbox(DwMailbox* aMailbox)

    Adds a mailbox, but does not set the is-modified flag.

    void _DeleteAll()

    Removes and deletes all DwMailbox objects from the list maintained by this DwMailboxList object. Doesn't set the is-modified flag.

    Protected Data Members

    DwMailbox* mFirstMailbox

    Points to first DwMailbox object in list.

    mimelib1-1.1.4/mimelib/doc/boyermor.html0000644000175000017500000000353711175345261017540 0ustar resivoresivo DwBoyerMoore Man Page

    NAME

    DwBoyerMoore -- Class for executing Boyer-Moore string search algorithm

    SYNOPSIS

    class DW_EXPORT DwBoyerMoore {
    
    public:
    
        DwBoyerMoore(const char* aCstr);
        DwBoyerMoore(const DwString& aStr);
        virtual ~DwBoyerMoore();
        void Assign(const char* aCstr);
        void Assign(const DwString& aStr);
        size_t FindIn(const DwString& aStr, size_t aPos);
    };
    

    DESCRIPTION

    DwBoyerMoore implements the Boyer-Moore algorithm for searching for a string. The Boyer-Moore algorithm is fast, but requires a bit of start-up overhead compared to a brute force algorithm.

    Public Member Functions

    DwBoyerMoore(const char* aCstr)
    DwBoyerMoore(const DwString& aStr)

    Constructs a DwBoyerMoore object for searching for a particular string.

    void Assign(const char* aCstr)
    void Assign(const DwString& aStr)

    Sets the string to search for.

    size_t FindIn(const DwString& aStr, size_t aPos)

    Searches for the search string in aStr starting at position aPos. If found, the function returns the first position in aStr where the search string was found. If not found, the function returns DwString::npos. mimelib1-1.1.4/mimelib/doc/param.html0000644000175000017500000001741011175345261016775 0ustar resivoresivo DwParameter Man Page

    NAME

    DwParameter -- Class representing a MIME field body parameter

    SYNOPSIS

    class DW_EXPORT DwParameter : public DwMessageComponent {
    
        friend class DwMediaType;
    
    public:
    
        DwParameter();
        DwParameter(const DwParameter& aParam);
        DwParameter(const DwString& aStr, DwMessageComponent* aParent=0);
        virtual ~DwParameter();
        const DwParameter& operator = (const DwParameter& aParam);
        virtual void Parse();
        virtual void Assemble();
        virtual DwMessageComponent* Clone() const;
        const DwString& Attribute() const;
        void SetAttribute(const DwString& aAttribute);
        const DwString& Value() const;
        void SetValue(const DwString& aValue);
        DwParameter* Next() const ;
        void SetNext(DwParameter* aParam);
        static DwParameter* NewParameter(const DwString& aStr,
            DwMessageComponent* aParent);
        static DwParameter* (*sNewParameter)(const DwString&, DwMessageComponent*);
    
    public:
    
        virtual void PrintDebugInfo(ostream& aStrm, int aDepth=0) const;
        virtual void CheckInvariants() const;
    
    protected:
    
        void _PrintDebugInfo(ostream& aStrm) const;
    };
    

    DESCRIPTION

    DwParameter represents the parameter component of the Content-Type header field as described in RFC-2045. A parameter consists of an attribute/value pair. DwParameter has member functions for getting or setting a parameter's attribute and value.

    A DwParameter object may be included in a list of DwParameter objects. You can get the next DwParameter object in the list by calling the member function Next().

    Public Member Functions

    DwParameter()
    DwParameter(const DwParameter& aParam)
    DwParameter(const DwString& aStr, DwMessageComponent* aParent=0)

    The first constructor is the default constructor, which sets the DwParameter object's string representation to the empty string and sets its parent to NULL.

    The second constructor is the copy constructor, which copies the string representation, attribute, and value from aParam. The parent of the new DwParameter object is set to NULL.

    The third constructor copies aStr to the DwParameter object's string representation and sets aParent as its parent. The virtual member function Parse() should be called immediately after this constructor in order to parse the string representation. Unless it is NULL, aParent should point to an object of a class derived from DwMediaType.

    const DwParameter& operator = (const DwParameter& aParam)

    This is the assignment operator.

    virtual void Parse()

    This virtual function, inherited from DwMessageComponent, executes the parse method for DwParameter objects. It should be called immediately after the string representation is modified and before the parts of the broken-down representation are accessed.

    virtual void Assemble()

    This virtual function, inherited from DwMessageComponent, executes the assemble method for DwParameter objects. It should be called whenever one of the object's attributes is changed in order to assemble the string representation from its broken-down representation. It will be called automatically for this object by the parent object's Assemble() member function if the is-modified flag is set.

    virtual DwMessageComponent* Clone() const

    This virtual function, inherited from DwMessageComponent, creates a new DwParameter on the free store that has the same value as this DwParameter object. The basic idea is that of a ``virtual copy constructor.''

    const DwString& Attribute() const

    Returns the attribute contained by this parameter.

    void SetAttribute(const DwString& aAttribute)

    Sets the attribute contained by this parameter.

    const DwString& Value() const

    Returns the value contained by this parameter.

    void SetValue(const DwString& aValue)

    Sets the value contained by this parameter.

    DwParameter* Next() const

    Returns the next DwParameter object in the list.

    void SetNext(DwParameter* aParam)

    Returns the next DwParameter object in the list. Since DwMediaType has member functions for adding DwParameter objects to its list, you should avoid using this function.

    static DwParameter* NewParameter(const DwString& aStr, DwMessageComponent* aParent)

    Creates a new DwParameter object on the free store. If the static data member sNewParameter is NULL, this member function will create a new DwParameter and return it. Otherwise, NewParameter() will call the user-supplied function pointed to by sNewParameter, which is assumed to return an object from a class derived from DwParameter, and return that object.

    virtual void PrintDebugInfo(ostream& aStrm, int aDepth=0) const

    This virtual function, inherited from DwMessageComponent, prints debugging information about this object to aStrm. It will also call PrintDebugInfo() for any of its child components down to a level of aDepth.

    This member function is available only in the debug version of the library.

    virtual void CheckInvariants() const

    Aborts if one of the invariants of the object fails. Use this member function to track down bugs.

    This member function is available only in the debug version of the library.

    Public Data Members

    static DwParameter* (*sNewParameter)(const DwString&, DwMessageComponent*)

    If sNewParameter is not NULL, it is assumed to point to a user-supplied function that returns an object from a class derived from DwParameter. mimelib1-1.1.4/mimelib/doc/address.html0000644000175000017500000001330311175345261017317 0ustar resivoresivo DwAddress Man Page

    NAME

    DwAddress -- Abstract class representing an RFC-822 address

    SYNOPSIS

    class DW_EXPORT DwAddress : public DwFieldBody {
    
        friend class DwAddressList;
    
    public:
    
        virtual ~DwAddress();
        DwBool IsMailbox() const;
        DwBool IsGroup() const;
        inline DwBool IsValid() const;
        DwAddress* Next() const;
        void SetNext(DwAddress* aAddress);
    
    protected:
    
        DwAddress();
        DwAddress(const DwAddress& aAddr);
        DwAddress(const DwString& aStr, DwMessageComponent* aParent=0);
        const DwAddress& operator = (const DwAddress& aAddr);
        int mIsValid;
    
    public:
    
        virtual void PrintDebugInfo(ostream& aStrm, int aDepth=0) const;
        virtual void CheckInvariants() const;
    
    protected:
    
        void _PrintDebugInfo(ostream& aStrm) const;
    };
    

    DESCRIPTION

    DwAddress represents an address as described in RFC-822. You may not instantiate objects of type DwAddress, since DwAddress is an abstract base class. Instead, you must instantiate objects of type DwMailbox or DwGroup, which are subclasses of DwAddress.

    To determine the actual type of a DwAddress object, you can use the member functions IsMailbox() and IsGroup().

    If the string representation assigned to a DwAddress is improperly formed, the parse method will fail. To determine if the parse method failed, call the member function IsValid().

    A DwAddress object can be contained in list. To get the next DwAddress object in the list, call the member function Next()

    Public Member Functions

    DwBool IsMailbox() const

    Returns true value if this object is a DwMailbox.

    DwBool IsGroup() const

    Returns true value if this object is a DwGroup.

    inline DwBool IsValid() const

    Returns true value if the last parse was successful. Returns false if the last parse failed (bad address) or the Parse() member function was never called.

    DwAddress* Next() const

    Returns the next DwAddress object in the list when the object is included in a list of addresses. The function is used when iterating a list.

    void SetNext(DwAddress* aAddress)

    Sets the next DwAddress object in the list. This member function generally should not be used, since DwAddressList has member functions to manage its list of DwAddress objects.

    virtual void PrintDebugInfo(ostream& aStrm, int aDepth=0) const

    This virtual function, inherited from DwMessageComponent, prints debugging information about this object to aStrm. It will also call PrintDebugInfo() for any of its child components down to a level of aDepth.

    This member function is available only in the debug version of the library.

    virtual void CheckInvariants() const

    Aborts if one of the invariants of the object fails. Use this member function to track down bugs.

    This member function is available only in the debug version of the library.

    Protected Member Functions

    DwAddress()
    DwAddress(const DwAddress& aAddr)
    DwAddress(const DwString& aStr, DwMessageComponent* aParent=0)

    The first constructor is the default constructor, which sets the DwAddress object's string representation to the empty string and sets its parent to NULL.

    The second constructor is the copy constructor, which copies the string representation and all attributes from aAddress. The parent of the new DwAddress object is set to NULL.

    The third constructor copies aStr to the DwAddress object's string representation and sets aParent as its parent. The virtual member function Parse() should be called immediately after this constructor in order to parse the string representation. Unless it is NULL, aParent should point to an object of a class derived from DwField.

    const DwAddress& operator = (const DwAddress& aAddr)

    This is the assignment operator, which performs a deep copy of aAddr. The parent node of the DwAddress object is not changed.

    mimelib1-1.1.4/mimelib/doc/headers.html0000644000175000017500000006353111175345261017315 0ustar resivoresivo DwHeaders Man Page

    NAME

    DwHeaders -- Class representing the collection of header fields in a message or body part

    SYNOPSIS

    class DW_EXPORT DwHeaders : public DwMessageComponent {
    
    public:
    
        DwHeaders();
        DwHeaders(const DwHeaders& aHeaders);
        DwHeaders(const DwString& aStr, DwMessageComponent* aParent=0);
        virtual ~DwHeaders();
        const DwHeaders& operator = (const DwHeaders& aHeaders);
        virtual void Parse();
        virtual void Assemble();
        virtual DwMessageComponent* Clone() const;
        DwBool HasBcc() const;
        DwBool HasCc() const;
        DwBool HasComments() const;
        DwBool HasDate() const;
        DwBool HasEncrypted() const;
        DwBool HasFrom() const;
        DwBool HasInReplyTo() const;
        DwBool HasKeywords() const;
        DwBool HasMessageId() const;
        DwBool HasReceived() const;
        DwBool HasReferences() const;
        DwBool HasReplyTo() const;
        DwBool HasResentBcc() const;
        DwBool HasResentCc() const;
        DwBool HasResentDate() const;
        DwBool HasResentFrom() const;
        DwBool HasResentMessageId() const;
        DwBool HasResentReplyTo() const;
        DwBool HasResentSender() const;
        DwBool HasResentTo() const;
        DwBool HasReturnPath() const;
        DwBool HasSender() const;
        DwBool HasSubject() const;
        DwBool HasTo() const;
        DwBool HasApproved() const;
        DwBool HasControl() const;
        DwBool HasDistribution() const;
        DwBool HasExpires() const;
        DwBool HasFollowupTo() const;
        DwBool HasLines() const;
        DwBool HasNewsgroups() const;
        DwBool HasOrganization() const;
        DwBool HasPath() const;
        DwBool HasSummary() const;
        DwBool HasXref() const;
        DwBool HasContentDescription() const;
        DwBool HasContentId() const;
        DwBool HasContentTransferEncoding() const;
        DwBool HasCte() const;
        DwBool HasContentType() const;
        DwBool HasMimeVersion() const;
        DwBool HasContentDisposition() const;
        DwBool HasField(const char* aFieldName) const;
        DwBool HasField(const DwString& aFieldName) const;
        DwAddressList&  Bcc();
        DwAddressList&  Cc();
        DwText&         Comments();
        DwDateTime&     Date();
        DwText&         Encrypted();
        DwMailboxList&  From();
        DwText&         InReplyTo();
        DwText&         Keywords();
        DwMsgId&        MessageId();
        DwText&         Received();
        DwText&         References();
        DwAddressList&  ReplyTo();
        DwAddressList&  ResentBcc();
        DwAddressList&  ResentCc();
        DwDateTime&     ResentDate();
        DwMailboxList&  ResentFrom();
        DwMsgId&        ResentMessageId();
        DwAddressList&  ResentReplyTo();
        DwMailbox&      ResentSender();
        DwAddressList&  ResentTo();
        DwAddress&      ReturnPath();
        DwMailbox&      Sender();
        DwText&         Subject();
        DwAddressList&  To();
        DwText& Approved();
        DwText& Control();
        DwText& Distribution();
        DwText& Expires();
        DwText& FollowupTo();
        DwText& Lines();
        DwText& Newsgroups();
        DwText& Organization();
        DwText& Path();
        DwText& Summary();
        DwText& Xref();
        DwText&         ContentDescription();
        DwMsgId&        ContentId();
        DwMechanism&    ContentTransferEncoding();
        DwMechanism&    Cte();
        DwMediaType&    ContentType();
        DwText&         MimeVersion();
        DwDispositionType& ContentDisposition();
        DwFieldBody& FieldBody(const DwString& aFieldName);
        int NumFields() const;
        DwField* FirstField() const;
        DwField* FindField(const char* aFieldName) const;
        DwField* FindField(const DwString& aFieldName) const;
        void AddOrReplaceField(DwField* aField);
        void AddField(DwField* aField);
        void AddFieldAt(int aPos, DwField* aField);
        void RemoveField(DwField* aField);
        void DeleteAllFields();
        static DwHeaders* NewHeaders(const DwString& aStr,
            DwMessageComponent* aParent);
        static DwHeaders* (*sNewHeaders)(const DwString&, DwMessageComponent*);
    
    protected:
    
        void _AddField(DwField* aField);
        DwField* mFirstField;
    
    protected:
    
        static const char* const sClassName;
        void CopyFields(DwField* aFirst);
    
    public:
    
        virtual void PrintDebugInfo(ostream& aStrm, int aDepth=0) const;
        virtual void CheckInvariants() const;
    };
    

    DESCRIPTION

    DwHeaders represents the collection of header fields (often called just headers) in an entity (either a message or body part), as described in RFC-822 and RFC-2045. A DwHeaders object manages a list of DwField objects, which represent the individual header fields.

    In the tree (broken-down) representation of a message, a DwHeaders object is an intermediate node, having both a parent node and several child nodes. The parent node is the DwEntity object that contains it. The child nodes are the DwField objects in the list it manages. (See the man page for DwMessageComponent for a discussion of the tree representation of a message.)

    Normally, you do not create a DwHeaders object directly, but you access it through the Headers() member function of DwEntity, which creates the DwHeaders object for you.

    While DwHeaders has public member functions for managing the list of DwField objects it contains, you will normally use convenience functions to access the field bodies of the header fields directly. You can access the field body for a specific well-known header field by using the member function <Field>(), where <Field> is the field name of the header field with hyphens removed and the first word following a hyphen capitalized. For example, to access the field body for the "MIME-version" header field, use MimeVersion(). The member function <Field>() will create a header field with field name <Field> if such a header field does not already exist. You can check for the existence of a particular well-known header field by using the member function Has<Field>(). For example, to check for the existence of the MIME-version header field, use HasMimeVersion(). Well-known header fields are those documented in RFC-822 (standard email), RFC-1036 (USENET messages), RFC-2045 (MIME messages), and possibly other RFCs.

    In the case of an extension field or user-defined field, you can access the field body of the header field by calling the member function FieldBody() with the field name as its argument. If the extension field or user-defined field does not exist, FieldBody() will create it. You can check for the existence of an extension field or user-defined field by using the member function HasField() with the field name as its argument.

    DwHeaders has several other member functions provided for the sake of completeness that are not required for most applications. These functions are documented below.

    Public Member Functions

    DwHeaders()
    DwHeaders(const DwHeaders& aHeaders)
    DwHeaders(const DwString& aStr, DwMessageComponent* aParent=0)

    The first constructor is the default constructor, which sets the DwHeaders object's string representation to the empty string and sets its parent to NULL.

    The second constructor is the copy constructor, which performs a deep copy of aHeaders. The parent of the new DwHeaders object is set to NULL.

    The third constructor copies aStr to the DwHeaders object's string representation and sets aParent as its parent. The virtual member function Parse() should be called immediately after this constructor in order to parse the string representation. Unless it is NULL, aParent should point to an object of a class derived from DwEntity.

    const DwHeaders& operator = (const DwHeaders& aHeaders)

    This is the assignment operator, which performs a deep copy of aHeaders. The parent node of the DwHeaders object is not changed.

    virtual void Parse()

    This virtual function, inherited from DwMessageComponent, executes the parse method for DwHeaders objects. The parse method creates or updates the broken-down representation from the string representation. For DwHeaders objects, DwHeaders::Parse() parses the string representation to create a list of DwField objects. This member function also calls the Parse() member function of each DwField object in its list.

    You should call this member function after you set or modify the string representation, and before you access any of the header fields.

    This function clears the is-modified flag.

    virtual void Assemble()

    This virtual function, inherited from DwMessageComponent, executes the assemble method for DwHeaders objects. The assemble method creates or updates the string representation from the broken-down representation. That is, the assemble method builds the string representation from its list of DwField objects. Before it builds the string representation, this function first calls the Assemble() member function of each DwField object in its list.

    You should call this member function after you set or modify any of the header fields, and before you retrieve the string representation.

    This function clears the is-modified flag.

    virtual DwMessageComponent* Clone() const

    This virtual function, inherited from DwMessageComponent, creates a new DwHeaders on the free store that has the same value as this DwHeaders object. The basic idea is that of a virtual copy constructor.

    DwBool HasBcc() const
    DwBool HasCc() const
    DwBool HasComments() const
    DwBool HasDate() const
    DwBool HasEncrypted() const
    DwBool HasFrom() const
    DwBool HasInReplyTo() const
    DwBool HasKeywords() const
    DwBool HasMessageId() const
    DwBool HasReceived() const
    DwBool HasReferences() const
    DwBool HasReplyTo() const
    DwBool HasResentBcc() const
    DwBool HasResentCc() const
    DwBool HasResentDate() const
    DwBool HasResentFrom() const
    DwBool HasResentMessageId() const
    DwBool HasResentReplyTo() const
    DwBool HasResentSender() const
    DwBool HasResentTo() const
    DwBool HasReturnPath() const
    DwBool HasSender() const
    DwBool HasSubject() const
    DwBool HasTo() const
    DwBool HasApproved() const
    DwBool HasControl() const
    DwBool HasDistribution() const
    DwBool HasExpires() const
    DwBool HasFollowupTo() const
    DwBool HasLines() const
    DwBool HasNewsgroups() const
    DwBool HasOrganization() const
    DwBool HasPath() const
    DwBool HasSummary() const
    DwBool HasXref() const
    DwBool HasContentDescription() const
    DwBool HasContentId() const
    DwBool HasContentTransferEncoding() const
    DwBool HasCte() const
    DwBool HasContentType() const
    DwBool HasMimeVersion() const
    DwBool HasContentDisposition() const

    Each member function in this group returns a boolean value indicating whether a particular well-known header field is present in this object's collection of header fields.

    DwBool HasField(const char* aFieldName) const
    DwBool HasField(const DwString& aFieldName) const

    Returns true if the header field specified by aFieldName is present in this object's collection of header fields. These member functions are used for extension fields or user-defined fields.

    DwAddressList& Bcc()
    DwAddressList& Cc()
    DwText& Comments()
    DwDateTime& Date()
    DwText& Encrypted()
    DwMailboxList& From()
    DwText& InReplyTo()
    DwText& Keywords()
    DwMsgId& MessageId()
    DwText& Received()
    DwText& References()
    DwAddressList& ReplyTo()
    DwAddressList& ResentBcc()
    DwAddressList& ResentCc()
    DwDateTime& ResentDate()
    DwMailboxList& ResentFrom()
    DwMsgId& ResentMessageId()
    DwAddressList& ResentReplyTo()
    DwMailbox& ResentSender()
    DwAddressList& ResentTo()
    DwAddress& ReturnPath()
    DwMailbox& Sender()
    DwText& Subject()
    DwAddressList& To()
    DwText& Approved()
    DwText& Control()
    DwText& Distribution()
    DwText& Expires()
    DwText& FollowupTo()
    DwText& Lines()
    DwText& Newsgroups()
    DwText& Organization()
    DwText& Path()
    DwText& Summary()
    DwText& Xref()
    DwText& ContentDescription()
    DwMsgId& ContentId()
    DwMechanism& ContentTransferEncoding()
    DwMechanism& Cte()
    DwMediaType& ContentType()
    DwText& MimeVersion()
    DwDispositionType& ContentDisposition()

    Each member function in this group returns a reference to a DwFieldBody object for a particular header field. If the header field does not already exist, it is created. Use the corresponding Has<Field>() function to test if the header field already exists without creating it.

    DwFieldBody& FieldBody(const DwString& aFieldName)

    Returns a reference to the DwFieldBody object for a particular header field with field name aFieldName. If the header field does not already exist, it is created. Use HasField() to test if the header field already exists without creating it. This member function allows access to extension fields or user-defined fields.

    int NumFields() const

    Returns the number of DwField objects contained by this DwHeaders object.

    DwField* FirstField() const

    Returns a pointer to the first DwField object contained by this DwHeaders object. Use this member function to begin an iteration over the entire list of DwField objects. Continue the iteration by calling DwField::Next() on each DwField object.

    DwField* FindField(const char* aFieldName) const
    DwField* FindField(const DwString& aFieldName) const

    Searches for a header field by its field name. Returns NULL if the field is not found. This is an advanced function: most applications should use the <Field>() or Has<Field>() family of functions.

    void AddOrReplaceField(DwField* aField)

    Adds a DwField object to the list. If a header field with the same field name already exists, it is replaced by the new header field.

    DwHeaders takes responsibility for deleting the added DwField object.

    This is an advanced function. Consider using the member functions <Field>() (e.g. To(), ContentType(), and so on) and FieldBody() to add header fields.

    void AddField(DwField* aField)

    Adds a DwField object to the list. If a header field with the same field name already exists, it is not replaced; thus, duplicate header fields may occur when using this member function. (This is what you want for some header fields, such as the "Received" header field).

    DwHeaders takes responsibility for deleting the added DwField object.

    This is an advanced function. Consider using the member functions <Field>() (e.g. To(), ContentType(), and so on) and FieldBody() for adding header fields.

    void AddFieldAt(int aPos, DwField* aField)

    This member functions follows the semantics of AddField() except that aPos specifies a position for adding the field. A position of 1 indicates the beginning of the list. A position of 0 indicates the end of the list.

    This is an advanced function. Consider using the member functions <Field>() (e.g. To(), ContentType(), and so on) and FieldBody() for adding header fields.

    void RemoveField(DwField* aField)

    Removes the DwField object from the list. The DwField object is not deleted.

    void DeleteAllFields()

    Removes all DwField objects from the list and deletes them.

    static DwHeaders* NewHeaders(const DwString& aStr, DwMessageComponent* aParent)

    Creates a new DwHeaders object on the free store. If the static data member sNewHeaders is NULL, this member function will create a new DwHeaders and return it. Otherwise, NewHeaders() will call the user-supplied function pointed to by sNewHeaders, which is assumed to return an object from a class derived from DwHeaders, and return that object.

    virtual void PrintDebugInfo(ostream& aStrm, int aDepth=0) const

    This virtual function, inherited from DwMessageComponent, prints debugging information about this object to aStrm. It will also call PrintDebugInfo() for any of its child components down to a level of aDepth.

    This member function is available only in the debug version of the library.

    virtual void CheckInvariants() const

    Aborts if one of the invariants of the object fails. Use this member function to track down bugs.

    This member function is available only in the debug version of the library.

    Public Data Members

    static DwHeaders* (*sNewHeaders)(const DwString&, DwMessageComponent*)

    If sNewHeaders is not NULL, it is assumed to point to a user-supplied function that returns an object from a class derived from DwHeaders.

    mimelib1-1.1.4/mimelib/doc/body.html0000644000175000017500000003234011175345261016631 0ustar resivoresivo DwBody Man Page

    NAME

    DwBody -- Class representing a MIME message body

    SYNOPSIS

    class DW_EXPORT DwBody : public DwMessageComponent {
    
        friend class DwHeaders;
        friend class DwEntity;
        friend class DwBodyPart;
    
    public:
    
        DwBody();
        DwBody(const DwBody& aBody);
        DwBody(const DwString& aStr, DwMessageComponent* aParent=0);
        virtual ~DwBody();
        const DwBody& operator = (const DwBody& aBody);
        virtual void Parse();
        virtual void Assemble();
        virtual DwMessageComponent* Clone() const;
        DwBodyPart* FirstBodyPart() const;
        void AddBodyPart(DwBodyPart* aPart);
        DwMessage* Message() const;
        void SetMessage(DwMessage* aMessage);
        static DwBody* NewBody(const DwString& aStr, DwMessageComponent* aParent);
        static DwBody* (*sNewBody)(const DwString&, DwMessageComponent*);
    
    protected:
    
        DwString    mBoundaryStr;
        DwString    mPreamble;
        DwString    mEpilogue;
        DwBodyPart* mFirstBodyPart;
        DwMessage*  mMessage;
        static const char* const sClassName;
        void _AddBodyPart(DwBodyPart*);
        void _SetMessage(DwMessage*);
        void DeleteBodyParts();
        void CopyBodyParts(const DwBodyPart* aFirst);
    
    public:
    
        virtual void PrintDebugInfo(ostream& aStrm, int aDepth=0) const;
        virtual void CheckInvariants() const;
    
    protected:
    
        void _PrintDebugInfo(ostream& aStrm) const;
    };
    

    DESCRIPTION

    DwBody represents a body, as described in RFC-2045. A body is always part of an entity, which could be either a message or a body part. An entity has a collection of header fields and a body. If the content type of a body is ``multipart,'' then the body contains one or more body parts. If the content type is ``message,'' then the body contains an encapsulated message. In all content types, the body contains a string of characters.

    In MIME++, a DwBody object is contained in a DwEntity object. The DwBody object may contain a discrete body consisting only of a string of characters, or it may be a composite body, consisting of several contained DwBodyPart objects or a single contained DwMessage object. The only reliable way to determine the type of DwBody is to access the Content-Type header field from the DwHeaders object of the DwEntity that contains it. For this reason, a DwBody should always be part of a DwEntity.

    In the tree (broken-down) representation of a message, a DwBody object can be an intermediate node, having both a parent node and one or more child nodes, or a leaf node, having a parent but no child nodes. In either case, the parent node is the DwEntity object that contains it. If it is an intermediate node, it must be of type multipart with DwBodyPart objects as child nodes, or of type message with a single DwMessage object as its child node.

    Normally, you do not create a DwBody object directly, but you access it through the Body() member function of DwEntity, which creates the DwBody object for you.

    To add a DwBodyPart to a multipart DwBody, use the member function AddBodyPart(). To iterate over the DwBodyParts contained in multipart DwBody, get the first DwBodyPart by calling FirstBodyPart(). Then get the following DwBodyParts by calling DwBodyPart::Next() on the current DwBodyPart. To get the DwMessage contained in a Body with message content type, call Message().

    Public Member Functions

    DwBody()
    DwBody(const DwBody& aBody)
    DwBody(const DwString& aStr, DwMessageComponent* aParent=0)

    The first constructor is the default constructor, which sets the DwBody object's string representation to the empty string and sets its parent to NULL.

    The second constructor is the copy constructor, which performs a deep copy of aBody. The parent of the new DwBody object is set to NULL.

    The third constructor copies aStr to the DwBody object's string representation and sets aParent as its parent. The virtual member function Parse() should be called immediately after this constructor in order to parse the string representation. Unless it is NULL, aParent should point to an object of a class derived from DwEntity.

    const DwBody& operator = (const DwBody& aBody)

    This is the assignment operator, which performs a deep copy of aBody. The parent node of the DwBody object is not changed.

    virtual void Parse()

    This virtual function, inherited from DwMessageComponent, executes the parse method for DwBody objects. The parse method creates or updates the broken-down representation from the string representation. For a multipart DwBody object, the parse method creates a collection of DwBodyPart objects. For a message DwBody, the parse method creates a single DwMessage object. For any other type of DwBody, the parse method does nothing. This member function calls the Parse() member function of any objects it creates.

    Note: If the DwBody object has no parent node -- that is, it is not contained by a DwEntity object -- then the parse method does nothing, since it is unable to determine the type of body.

    You should call this member function after you set or modify the string representation, and before you access a contained DwBodyPart or DwMessage.

    This function clears the is-modified flag.

    virtual void Assemble()

    This virtual function, inherited from DwMessageComponent, executes the assemble method for DwBody objects. The assemble method creates or updates the string representation from the broken-down representation. Only DwBody objects with content type of multipart or message require assembling. In either case, the DwBody object must be able to find the headers of the message or body part that contains it. Therefore, if the DwBody object is not the child of a DwEntity (i.e., DwMessage or DwBodyPart) object, the DwBody cannot be assembled because the content type cannot be determined.

    This function calls the Parse() member function of any DwBodyPart or DwMessage object it contains.

    You should call this member function after you add a DwBodyPart object to a multipart body, or add a DwMessage object to a message body, and before you access the object's string representation.

    This function clears the is-modified flag.

    virtual DwMessageComponent* Clone() const

    This virtual function, inherited from DwMessageComponent, creates a new DwBody on the free store that has the same value as this DwBody object. The basic idea is that of a virtual copy constructor.

    DwBodyPart* FirstBodyPart() const

    For a multipart DwBody, this member function returns the first contained DwBodyPart object. Use DwBodyPart::Next() to iterate through the list of DwBodyParts.

    void AddBodyPart(DwBodyPart* aPart)

    For a multipart DwBody, this member function appends a DwBodyPart object to the list. Any DwBodyPart objects added to a DwBody object's list will be deleted by the DwBody object's destructor.

    DwMessage* Message() const

    For a DwBody with content type of message, this member function returns the DwMessage encapsulated in it.

    void SetMessage(DwMessage* aMessage)

    For a DwBody with content type of message, this member function sets the DwMessage object it contains.

    static DwBody* NewBody(const DwString& aStr, DwMessageComponent* aParent)

    Creates a new DwBody object on the free store. If the static data member sNewBody is NULL, this member function will create a new DwBody and return it. Otherwise, NewBody() will call the user-supplied function pointed to by sNewBody, which is assumed to return an object from a class derived from DwBody, and return that object.

    virtual void PrintDebugInfo(ostream& aStrm, int aDepth=0) const

    This virtual function, inherited from DwMessageComponent, prints debugging information about this object to aStrm. It will also call PrintDebugInfo() for any of its child components down to a level of aDepth.

    This member function is available only in the debug version of the library.

    virtual void CheckInvariants() const

    Aborts if one of the invariants of the object fails. Use this member function to track down bugs.

    This member function is available only in the debug version of the library.

    Public Data Members

    static DwBody* (*sNewBody)(const DwString&, DwMessageComponent*)

    If sNewBody is not NULL, it is assumed to point to a user-supplied function that returns an object from a class derived from DwBody.

    Protected Member Functions

    void _AddBodyPart(DwBodyPart*)

    Adds a body part to a multipart body. This function differs from AddBodyPart in that it does not set the is-modified flag.

    void _SetMessage(DwMessage*)

    Sets a message to a body. This function differs from SetMessage() in that it does not set the is-modified flag.

    Protected Data Members

    DwString mBoundaryStr

    A cache for the boundary string, which is obtained from the headers associated with this body.

    DwString mPreamble

    Contains the preamble -- the text preceding the first boundary -- in a ``multipart/*'' media type.

    DwString mEpilogue

    Contains the epilogue -- the text following the last boundary -- in a ``multipart/*'' media type.

    DwBodyPart* mFirstBodyPart

    Points to the first body part in a ``multipart/*'' media type. Is NULL if there are no body parts.

    DwMessage* mMessage

    Points to the contained message, in a ``message/*'' media type.

    mimelib1-1.1.4/mimelib/doc/string.html0000644000175000017500000010336011175345261017203 0ustar resivoresivo DwString Man Page

    NAME

    DwString -- String class

    SYNOPSIS

    class DW_EXPORT DwString {
    
    public:
    
        static const size_t npos;
        DwString();
        DwString(const DwString& aStr, size_t aPos=0, size_t aLen=npos);
        DwString(const char* aBuf, size_t aLen);
        DwString(const char* aCstr);
        DwString(size_t aLen, char aChar);
        DwString(char* aBuf, size_t aSize, size_t aStart, size_t aLen);
        virtual ~DwString();
        DwString& operator = (const DwString& aStr);
        DwString& operator = (const char* aCstr);
        DwString& operator = (char aChar);
        size_t size() const;
        size_t length() const;
        size_t max_size() const;
        void resize(size_t aLen, char aChar);
        void resize(size_t aLen);
        size_t capacity() const;
        void reserve(size_t aSize);
        void clear();
        DwBool empty() const;
        const char& operator [] (size_t aPos) const;
        char& operator [] (size_t aPos);
        const char& at(size_t aPos) const;
        char& at(size_t aPos);
        DwString& operator += (const DwString& aStr);
        DwString& operator += (const char* aCstr);
        DwString& operator += (char aChar);
        DwString& append(const DwString& aStr);
        DwString& append(const DwString& aStr, size_t aPos, size_t aLen);
        DwString& append(const char* aBuf, size_t aLen);
        DwString& append(const char* aCstr);
        DwString& append(size_t aLen, char aChar);
        DwString& assign(const DwString& aStr);
        DwString& assign(const DwString& aStr, size_t aPos, size_t aLen);
        DwString& assign(const char* aBuf, size_t aLen);
        DwString& assign(const char* aCstr);
        DwString& assign(size_t aLen, char aChar);
        DwString& insert(size_t aPos1, const DwString& aStr);
        DwString& insert(size_t aPos1, const DwString& aStr, size_t aPos2,
            size_t aLen2);
        DwString& insert(size_t aPos1, const char* aBuf, size_t aLen2);
        DwString& insert(size_t aPos1, const char* aCstr);
        DwString& insert(size_t aPos1, size_t aLen2, char aChar);
        DwString& erase(size_t aPos=0, size_t aLen=npos);
        DwString& replace(size_t aPos1, size_t aLen1, const DwString& aStr);
        DwString& replace(size_t aPos1, size_t aLen1, const DwString& aStr,
            size_t aPos2, size_t aLen2);
        DwString& replace(size_t aPos1, size_t aLen1, const char* aBuf,
            size_t aLen2);
        DwString& replace(size_t aPos1, size_t aLen1, const char* aCstr);
        DwString& replace(size_t aPos1, size_t aLen1, size_t aLen2, char aChar);
        size_t copy(char* aBuf, size_t aLen, size_t aPos=0) const;
        void swap(DwString& aStr);
        const char* c_str() const;
        const char* data() const;
        size_t find(const DwString& aStr, size_t aPos=0) const;
        size_t find(const char* aBuf, size_t aPos, size_t aLen) const;
        size_t find(const char* aCstr, size_t aPos=0) const;
        size_t find(char aChar, size_t aPos=0) const;
        size_t rfind(const DwString& aStr, size_t aPos=npos) const;
        size_t rfind(const char* aBuf, size_t aPos, size_t aLen) const;
        size_t rfind(const char* aCstr, size_t aPos=npos) const;
        size_t rfind(char aChar, size_t aPos=npos) const;
        size_t find_first_of(const DwString& aStr, size_t aPos=0) const;
        size_t find_first_of(const char* aBuf, size_t aPos, size_t aLen) const;
        size_t find_first_of(const char* aCstr, size_t aPos=0) const;
        size_t find_last_of(const DwString& aStr, size_t aPos=npos) const;
        size_t find_last_of(const char* aBuf, size_t aPos, size_t aLen) const;
        size_t find_last_of(const char* aCstr, size_t aPos=npos) const;
        size_t find_first_not_of(const DwString& aStr, size_t aPos=0) const;
        size_t find_first_not_of(const char* aBuf, size_t aPos, size_t aLen) const;
        size_t find_first_not_of(const char* aCstr, size_t aPos=0) const;
        size_t find_last_not_of(const DwString& aStr, size_t aPos=npos) const;
        size_t find_last_not_of(const char* aBuf, size_t aPos, size_t aLen) const;
        size_t find_last_not_of(const char* aCstr, size_t aPos=npos) const;
        DwString substr(size_t aPos=0, size_t aLen=npos) const;
        int compare(const DwString& aStr) const;
        int compare(size_t aPos1, size_t aLen1, const DwString& aStr) const;
        int compare(size_t aPos1, size_t aLen1, const DwString& aStr,
            size_t aPos2, size_t aLen2) const;
        int compare(const char* aCstr) const;
        int compare(size_t aPos1, size_t aLen1, const char* aBuf,
            size_t aLen2=npos) const;
        virtual const char* ClassName() const;
        int ObjectId() const;
        void ConvertToLowerCase();
        void ConvertToUpperCase();
        void Trim();
        void WriteTo(ostream& aStrm) const;
        int RefCount() const;
        void TakeBuffer(char* aBuf, size_t aSize, size_t aStart, size_t aLen);
        void ReleaseBuffer(char** aBuf, size_t* aSize, size_t* aStart, size_t* aLen);
        void CopyTo(DwString* aStr) const;
    
    protected:
    
        DwStringRep* mRep;
        size_t  mStart;
        size_t  mLength;
        void _copy();
        void _replace(size_t aPos1, size_t aLen1, const char* aBuf, size_t aLen2);
        void _replace(size_t aPos1, size_t aLen1, size_t aLen2, char aChar);
        friend void mem_free(char*);
    
    public:
    
        virtual void PrintDebugInfo(ostream& aStrm) const;
        virtual void CheckInvariants() const;
    };
    

    DESCRIPTION

    DwString is the workhorse of the MIME++ library. Creating, parsing, or otherwise manipulating MIME messages is basically a matter of manipulating strings. DwString provides all the basic functionality required of a string object, including copying, comparing, concatenating, and so on.

    DwString is similar to the string class that is part of the proposed ANSI standard C++ library. Some of the member functions present in the ANSI string are not present in DwString: mostly these are the functions that deal with iterators. DwString also includes some member functions and class utility functions that are not a part of the ANSI string class. These non-ANSI functions are easy to distinguish: they all begin with upper-case letters, and all ANSI functions begin with lower-case letters. The library classes themselves use only the ANSI string functions. At some point in the future, MIME++ will probably allow the option to substitute the ANSI string class for DwString.

    DwString makes extensive use of copy-on-write, even when extracting substrings. It is this feature that distiguishes DwString from most other string classes. DwString also handles binary data, which can contain embedded NUL characters.

    Public Member Functions

    DwString()
    DwString(const DwString& aStr, size_t aPos=0, size_t aLen=npos)
    DwString(const char* aBuf, size_t aLen)
    DwString(const char* aCstr)
    DwString(size_t aLen, char aChar)
    DwString(char* aBuf, size_t aSize, size_t aStart, size_t aLen)

    The first constructor is the default constructor, which sets the DwString object's contents to be empty.

    The second constructor is the copy constructor, which copies at most aLen characters beginning at position aPos from aStr to the new DwString object. It will not copy more characters than what are available in aStr. aPos must be less than or equal to aStr.size().

    The third constructor copies aLen characters from the buffer aBuf into the new DwString object. aBuf need not be NUL-terminated and may contain NUL characters.

    The fourth constructor copies the contents of the NUL-terminated string aCstr into the new DwString object.

    The fifth constructor sets the contents of the new DwString object to be the character aChar repeated aLen times.

    The sixth constructor is an advanced constructor that sets the contents of the new DwString object to the aLen characters starting at offset aStart in the buffer aBuf. aSize is the allocated size of aBuf. This constructor is provided for efficiency in setting a new DwString's contents from a large buffer. It is efficient because no copying takes place. Instead, aBuf becomes the buffer used internally by the DwString object, which takes responsibility for deleting the buffer. Because DwString will free the buffer using delete [], the buffer should have been allocated using new. See also: TakeBuffer(), and ReleaseBuffer().

    DwString& operator = (const DwString& aStr)
    DwString& operator = (const char* aCstr)
    DwString& operator = (char aChar)

    Assigns the contents of the operand to this string. aCstr must point to a NUL-terminated array of characters (a C string). Returns *this.

    size_t size() const

    Returns the number of characters in this string's contents. This member function is identical to length()

    size_t length() const

    Returns the number of characters in this string's contents. This member function is identical to size()

    size_t max_size() const

    Returns the maximum length that this string can ever attain.

    void resize(size_t aLen, char aChar)
    void resize(size_t aLen)

    Changes the length of this string. If the string shortened, the final characters are truncated. If the string is expanded, the added characters will be NULs or the character specified by aChar.

    size_t capacity() const

    Returns the size of the internal buffer used for this string, which will always be greater than or equal to the length of the string.

    void reserve(size_t aSize)

    If aSize is greater than the current capacity of this string, this member function will increase the capacity to be at least aSize.

    void clear()

    Sets this string's contents to be empty.

    DwBool empty() const

    Returns a true value if and only if the contents of this string are empty.

    const char& operator [] (size_t aPos) const
    char& operator [] (size_t aPos)

    Returns DwString::at(aPos) const or DwString::at(aPos). Note that the non-const version always assumes that the contents will be modified and therefore always copies a shared internal buffer before it returns.

    const char& at(size_t aPos) const
    char& at(size_t aPos)

    Returns the character at position aPos in the string's contents. The non-const version returns an lvalue that may be assigned to. Note that the non-const version always assumes that the contents will be modified and therefore always copies a shared internal buffer before it returns.

    DwString& operator += (const DwString& aStr)
    DwString& operator += (const char* aCstr)
    DwString& operator += (char aChar)

    Appends the contents of the operand to this string. aCstr must point to a NUL-terminated array of characters (a C string). Returns *this.

    DwString& append(const DwString& aStr)
    DwString& append(const DwString& aStr, size_t aPos, size_t aLen)
    DwString& append(const char* aBuf, size_t aLen)
    DwString& append(const char* aCstr)
    DwString& append(size_t aLen, char aChar)

    Appends characters to (the end of) this string. Returns *this.

    The first version appends all of the characters from aStr.

    The second version appends at most aLen characters from aStr beginning at position aPos. aPos must be less than or equal to aStr.size(). The function will not append more characters than what are available in aStr.

    The third version appends aLen characters from aBuf, which is not assumed to be NUL-terminated and can contain embedded NULs.

    The fourth version appends characters from the NUL-terminated string aCstr.

    The fifth version appends aChar repeated aLen times.

    DwString& assign(const DwString& aStr)
    DwString& assign(const DwString& aStr, size_t aPos, size_t aLen)
    DwString& assign(const char* aBuf, size_t aLen)
    DwString& assign(const char* aCstr)
    DwString& assign(size_t aLen, char aChar)

    Assigns characters to this string. Returns *this.

    The first version assigns all of the characters from aStr.

    The second version assigns at most aLen characters from aStr beginning at position aPos. aPos must be less than or equal to aStr.size(). The function will not assign more characters than what are available in aStr.

    The third version assigns aLen characters from aBuf, which is not assumed to be NUL-terminated and can contain embedded NULs.

    The fourth version assigns characters from the NUL-terminated string aCstr.

    The fifth version assigns aChar repeated aLen times.

    DwString& insert(size_t aPos1, const DwString& aStr)
    DwString& insert(size_t aPos1, const DwString& aStr, size_t aPos2, size_t aLen2)
    DwString& insert(size_t aPos1, const char* aBuf, size_t aLen2)
    DwString& insert(size_t aPos1, const char* aCstr)
    DwString& insert(size_t aPos1, size_t aLen2, char aChar)

    Inserts characters into this string beginning at position aPos1. Returns *this.

    The first version inserts all of the characters from aStr.

    The second version inserts at most aLen2 characters from aStr beginning at position aPos2. aPos1 must be less than or equal to aStr.size(). The function will not assign more characters than what are available in aStr.

    The third version inserts aLen2 characters from aBuf, which is not assumed to be NUL-terminated and can contain embedded NULs.

    The fourth version inserts characters from the NUL-terminated string aCstr.

    The fifth version inserts aChar repeated aLen2 times.

    DwString& erase(size_t aPos=0, size_t aLen=npos)

    Erases (removes) at most aLen characters beginning at position aPos from this string. The function will not erase more characters than what are available. Returns *this.

    DwString& replace(size_t aPos1, size_t aLen1, const DwString& aStr)
    DwString& replace(size_t aPos1, size_t aLen1, const DwString& aStr, size_t aPos2, size_t aLen2)
    DwString& replace(size_t aPos1, size_t aLen1, const char* aBuf, size_t aLen2)
    DwString& replace(size_t aPos1, size_t aLen1, const char* aCstr)
    DwString& replace(size_t aPos1, size_t aLen1, size_t aLen2, char aChar)

    Removes aLen1 characters beginning at position aPos1 and inserts other characters. Returns *this.

    The first version inserts all of the characters from aStr.

    The second version inserts at most aLen2 characters from aStr beginning at position aPos2. aPos1 must be less than or equal to aStr.size(). The function will not assign more characters than what are available in aStr.

    The third version inserts aLen2 characters from aBuf, which is not assumed to be NUL-terminated and can contain embedded NULs.

    The fourth version inserts characters from the NUL-terminated string aCstr.

    The fifth version inserts aChar repeated aLen2 times.

    size_t copy(char* aBuf, size_t aLen, size_t aPos=0) const

    Copies at most aLen characters beginning at position aPos from this string to the buffer pointed to by aBuf. Returns the number of characters copied.

    void swap(DwString& aStr)

    Swaps the contents of this string and aStr.

    const char* c_str() const

    const char* data() const

    These member functions permit access to the internal buffer used by the DwString object. c_str() returns a NUL-terminated string suitable for use in C library functions. data() returns a pointer to the internal buffer, which may not be NUL-terminated.

    c_str() may copy the internal buffer in order to place the terminating NUL. This is not a violation of the const declaration: it is a logical const, not a bit-representation const. It could have the side effect of invalidating a pointer previously returned by c_str() or data().

    The characters in the returned string should not be modified, and should be considered invalid after any call to a non-const member function or another call to c_str().

    size_t find(const DwString& aStr, size_t aPos=0) const
    size_t find(const char* aBuf, size_t aPos, size_t aLen) const
    size_t find(const char* aCstr, size_t aPos=0) const
    size_t find(char aChar, size_t aPos=0) const

    Performs a forward search for a sequence of characters in the DwString object. The return value is the position of the sequence in the string if found, or DwString::npos if not found.

    The first version searches beginning at position aPos for the sequence of characters in aStr.

    The second version searches beginning at position aPos for the sequence of aLen characters in aBuf, which need not be NUL-terminated and can contain embedded NULs.

    The third version searches beginning at position aPos for the sequence of characters in the NUL-terminated string aCstr.

    The fourth version searches beginning at position aPos for the character aChar.

    size_t rfind(const DwString& aStr, size_t aPos=npos) const
    size_t rfind(const char* aBuf, size_t aPos, size_t aLen) const
    size_t rfind(const char* aCstr, size_t aPos=npos) const
    size_t rfind(char aChar, size_t aPos=npos) const

    Performs a reverse search for a sequence of characters in the DwString object. The return value is the position of the sequence in the string if found, or DwString::npos if not found.

    The first version searches beginning at position aPos for the sequence of characters in aStr.

    The second version searches beginning at position aPos for the sequence of aLen characters in aBuf, which need not be NUL-terminated and can contain embedded NULs.

    The third version searches beginning at position aPos for the sequence of characters in the NUL-terminated string aCstr.

    The fourth version searches beginning at position aPos for the character aChar.

    size_t find_first_of(const DwString& aStr, size_t aPos=0) const
    size_t find_first_of(const char* aBuf, size_t aPos, size_t aLen) const
    size_t find_first_of(const char* aCstr, size_t aPos=0) const

    Performs a forward search beginning at position aPos for the first occurrence of any character from a specified set of characters. The return value is the position of the character if found, or DwString::npos if not found.

    The first version searches for any character in the string aStr.

    The second version searches for any of the aLen characters in aBuf.

    The third version searches for any character in the NUL-terminated string aCstr.

    size_t find_last_of(const DwString& aStr, size_t aPos=npos) const
    size_t find_last_of(const char* aBuf, size_t aPos, size_t aLen) const
    size_t find_last_of(const char* aCstr, size_t aPos=npos) const

    Performs a reverse search beginning at position aPos for the first occurrence of any character from a specified set of characters. If aPos is greater than or equal to the number of characters in the string, then the search starts at the end of the string. The return value is the position of the character if found, or DwString::npos if not found.

    The first version searches for any character in the string aStr.

    The second version searches for any of the aLen characters in aBuf.

    The third version searches for any character in the NUL-terminated string aCstr.

    size_t find_first_not_of(const DwString& aStr, size_t aPos=0) const
    size_t find_first_not_of(const char* aBuf, size_t aPos, size_t aLen) const
    size_t find_first_not_of(const char* aCstr, size_t aPos=0) const

    Performs a forward search beginning at position aPos for the first occurrence of any character not in a specified set of characters. The return value is the position of the character if found, or DwString::npos if not found.

    The first version searches for any character not in the string aStr.

    The second version searches for any character not among the aLen characters in aBuf.

    The third version searches for any character not in the NUL-terminated string aCstr.

    size_t find_last_not_of(const DwString& aStr, size_t aPos=npos) const
    size_t find_last_not_of(const char* aBuf, size_t aPos, size_t aLen) const
    size_t find_last_not_of(const char* aCstr, size_t aPos=npos) const

    Performs a reverse search beginning at position aPos for the first occurrence of any character not in a specified set of characters. If aPos is greater than or equal to the number of characters in the string, then the search starts at the end of the string. The return value is the position of the character if found, or DwString::npos if not found.

    The first version searches for any character not in the string aStr.

    The second version searches for any character not among the aLen characters in aBuf.

    The third version searches for any character not in the NUL-terminated string aCstr.

    DwString substr(size_t aPos=0, size_t aLen=npos) const

    Returns a string that contains at most aLen characters from the DwString object beginning at position aPos. The returned substring will not contain more characters than what are available in the superstring DwString object.

    int compare(const DwString& aStr) const
    int compare(size_t aPos1, size_t aLen1, const DwString& aStr) const
    int compare(size_t aPos1, size_t aLen1, const DwString& aStr, size_t aPos2, size_t aLen2) const
    int compare(const char* aCstr) const
    int compare(size_t aPos1, size_t aLen1, const char* aBuf, size_t aLen2=npos) const

    These member functions compare a sequence of characters to this DwString object, or a segment of this DwString object. They return -1, 0, or 1, depending on whether this DwString object is less than, equal to, or greater than the compared sequence of characters, respectively.

    The first version compares aStr to this string.

    The second version compares aStr to the segment of this string of length aLen beginning at position aPos.

    The third version compares the {tt aLen2} characters beginning at position aPos2 in aStr with the aLen1 characters beginning at position aPos1 in this DwString object.

    The fourth version compares the NUL-terminated string aCstr to this DwString.

    The fifth version compares the aLen2 characters in aBuf with this DwString.

    virtual const char* ClassName() const

    This virtual function returns the name of the class as a NUL-terminated char string.

    int ObjectId() const

    Returns the unique object id for this DwString.

    void ConvertToLowerCase()
    void ConvertToUpperCase()

    Converts this DwString object's characters to all lower case or all upper case.

    void Trim()

    Removes all white space from the beginning and the end of this DwString object. White space characters include ASCII HT, LF, and SPACE.

    void WriteTo(ostream& aStrm) const

    Writes the contents of this DwString object to the stream aStrm.

    int RefCount() const

    This advanced member function returns the number of references to the internal buffer used by the DwString object.

    void TakeBuffer(char* aBuf, size_t aSize, size_t aStart, size_t aLen)

    This advanced member function sets the contents of the DwString object to the aLen characters starting at offset aStart in the buffer aBuf. aSize is the allocated size of aBuf. This member function is provided for efficiency in setting a DwString's contents from a large buffer. It is efficient because no copying takes place. Instead, aBuf becomes the buffer used internally by the DwString object, which takes responsibility for deleting the buffer. Because DwString will free the buffer using delete [], the buffer should have been allocated using new. See also: ReleaseBuffer().

    void ReleaseBuffer(char** aBuf, size_t* aSize, size_t* aStart, size_t* aLen)

    This advanced member function is the symmetric opposite of TakeBuffer(), to the extent that such an opposite is possible. It provides a way to ``export'' the buffer used internally by the DwString object. Note, however, that because of the copy-on-modify feature of DwString, the DwString object may not have sole ownership of its internal buffer. When that is case, ReleaseBuffer() will return a copy of the buffer. You can check to see if the internal buffer is shared by calling RefCount(). On return from this member function, the DwString object will have valid, but empty, contents. It is recommended that you use this function only on rare occasions where you need to export efficiently a large buffer.

    void CopyTo(DwString* aStr) const

    This advanced member function copies this DwString object to aStr. This member function is different from the assignment operator, because it physically copies the buffer instead of just duplicating a reference to it.

    virtual void PrintDebugInfo(ostream& aStrm) const

    Prints debugging information about the object to aStrm.

    This member function is available only in the debug version of the library.

    virtual void CheckInvariants() const

    Aborts if one of the invariants of the object fails. Use this member function to track down bugs.

    This member function is available only in the debug version of the library.

    Public Data Members

    static const size_t npos

    npos is assigned the value (size_t)-1. mimelib1-1.1.4/mimelib/doc/pop.html0000644000175000017500000003257411175345261016503 0ustar resivoresivo DwPopClient Man Page

    NAME

    DwPopClient -- Class for handling the client side of a POP session

    SYNOPSIS

    class DW_EXPORT DwPopClient : public DwProtocolClient {
    
    public:
    
        enum {
            kCmdNoCommand=0,
            kCmdUser,
            kCmdPass,
            kCmdQuit,
            kCmdStat,
            kCmdList,
            kCmdRetr,
            kCmdDele,
            kCmdNoop,
            kCmdRset,
            kCmdApop,
            kCmdTop,
            kCmdUidl
        };
        DwPopClient();
        virtual ~DwPopClient();
        virtual int Open(const char* aServer, DwUint16 aPort=110);
        DwObserver* SetObserver(DwObserver* aObserver);
        int StatusCode() const;
        const DwString& SingleLineResponse() const;
        const DwString& MultiLineResponse() const;
        int User(const char* aName);
        int Pass(const char* aPasswd);
        int Quit();
        int Stat();
        int List();
        int List(int aMsg);
        int Retr(int aMsg);
        int Dele(int aMsg);
        int Noop();
        int Rset();
        int Apop(const char* aName, const char* aDigest);
        int Top(int aMsg, int aNumLines);
        int Uidl();
        int Uidl(int aMsg);
    };
    

    DESCRIPTION

    DwPopClient is a class that handles the client side of a POP session. Specifically, DwPopClient provides facilities for opening a connection to a POP server, sending commands to the server, receiving responses from the server, and closing the connection. The protocol implemented is the Post Office Protocol version 3, as specified in RFC-1939.

    DwPopClient is derived from DwProtocolClient. For information about inherited member functions, especially member functions for detecting failures or errors, see the man page for DwProtocolClient.

    In a POP session, the client sends commands to the server and receives responses from the server. A client command consists of a command word and zero or more argument words. A server response consists of a single line status response, which may be followed immediately by a multi-line response. The first word of the status response is either +OK or -ERR, indicating the success or failure of the command. The status line may also contain other information requested by the client.

    DwPopClient has only a default constructor. On Win32 platforms, it is possible for the constructor to fail. (It calls WSAStartup().) You should verify that the constructor succeeded by calling the inherited member function DwProtocolClient::LastError() and checking for a zero return value.

    To open a connection to the server, call the member function Open() with the name of the server as an argument. Open() accepts an optional argument that specifies the TCP port that the server listens to. The default port is the standard POP port (110). Open() may fail, so you should check the return value to verify that it succeeded. To close the connection, call the inherited member function DwProtocolClient::Close(). To check if a connection is open, call the inherited member function DwProtocolClient::IsOpen(). IsOpen() returns a boolean value that indicates whether or not a call to Open() was successful; it will not detect failure in the network or a close operation by the remote host.

    For each POP command, DwPopClient has a member function that sends that command and receives the server's response. If the command takes any arguments, then those arguments are passed as function arguments to the command function. The command functions return the first character of the server's response, which will be '+' if the command succeeded or '-' if the command failed. In some cases, because of a communications error or some other error, it is not possible for the command function to send the command or receive the response. When this happens, the command function will return 0. You can determine the precise error or failure by calling the inherited member functions DwProtocolClient::LastError() or DwProtocolClient::LastFailure().

    After each command is sent, DwPopClient receives the server's response and remembers it. The member function StatusCode() returns the first character of the server's status response; it will be '+' or '-', indicating success or failure, or zero if no response was received from the server. SingleLineResponse() returns the entire single line status response from the server, including the initial "+OK" or "-ERR" status word.

    The server sends a single-line response, including a status code, for all POP commands. For some commands, such as when the client requests a mail message, the server sends a multi-line text response immediately following the single-line status response. Multi-line text responses can be received in either of two ways. The simplest way is to call the member function MultiLineResponse() after a command completes successfully. This simple method works fine for non-interactive applications. It can be a problem in interactive applications, however, because there is no data to display to a user until the entire multi-line response is retrieved. An alternative method allows your program to retrieve the multi-line response one line at a time as it is received. To use this method, you must define a subclass of DwObserver and assign an object of that class to the DwPopClient object using the member function SetObserver(). DwObserver is an abstract class, declared in protocol.h, that has just one pure virtual member function Notify(). After each line of the multi-line response is received, DwPopClient will call the Notify() member function of its assigned DwObserver object. Each invocation of Notify() should call the DwPopClient member function MultiLineResponse() to retrieve the next line of the text response. Note that you cannot use both of these methods at the same time: if an observer is assigned, MultiLineResponse() returns only the last line received, not the entire multi-line response.

    Public Member Functions

    DwPopClient()

    Initializes the DwPopClient object. It is possible for the constructor to fail. To verify that the constructor succeeded, call the member function LastError() and check that it returns zero. (In the Win32 implementation, the constructor calls the Winsock function WSAStartup(), which may fail.)

    virtual int Open(const char* aServer, DwUint16 aPort=110)

    Opens a TCP connection to the server aServer at port aPort. aServer may be either a host name, such as "news.acme.com" or an IP number in dotted decimal format, such as "147.81.64.60". The default value for aPort is 110, the well-known port for POP3 assigned by the Internet Assigned Numbers Authority (IANA).

    If the connection attempt succeeds, the server sends a response. Open() returns the server's status code ('+' or '-'). The full response from the server can be retrieved by calling SingleLineResponse().

    If the connection attempt fails, Open() returns 0. To determine what error occurred when a connection attempt fails, call the inherited member function DwProtocolClient::LastError(). To determine if a failure also occurred, call the inherited member function DwProtocolClient::LastFailure().

    DwObserver* SetObserver(DwObserver* aObserver)

    Sets the observer object that interacts with the DwPopClient object to retrieve a multi-line response. If an observer is set, DwPopClient will call the observer's Notify() method after each line of the multi-line response is received. To remove an observer, call SetObserver() with a NULL argument. SetObserver() returns the previously set observer, or NULL if no observer was previously set.

    int StatusCode() const

    Returns the status code received from the server in response to the last client command. The status codes in POP3 are '+', indicating success, and '-', indicating failure. If no response was received, StatusCode() returns zero.

    const DwString& SingleLineResponse() const

    Returns the single line status response last received from the server. If no response was received, perhaps because of a communications failure, SingleLineResponse() returns an empty string.

    const DwString& MultiLineResponse() const

    If no observer is set for this object, MultiLineResponse() returns a string that comprises the entire sequence of lines received from the server. Otherwise, if an observer is set for this object, MultiLineResponse() returns only the most recent line received.

    int User(const char* aName)

    Sends the USER command and returns the status code received from the server. If no response is received, the function returns zero. aName is the name of the user, which is sent in the command.

    int Pass(const char* aPasswd)

    Sends the PASS command and returns the status code received from the server. If no response is received, the function returns zero. aPasswd is the password, which is sent in the command.

    int Quit()

    Sends the QUIT command and returns the status code received from the server. If no response is received, the function returns zero.

    int Stat()

    Sends the STAT command and returns the status code received from the server. If no response is received, the function returns zero.

    int List()
    int List(int aMsg)

    Sends the LIST command, with or without a message number, and returns the status code received from the server. If no response is received, the function returns zero.

    int Retr(int aMsg)

    Sends the RETR command and returns the status code received from the server. If no response is received, the function returns zero. aMsg is the message number, which is sent in the command.

    int Dele(int aMsg)

    Sends the DELE command and returns the status code received from the server. If no response is received, the function returns zero. aMsg is the message number, which is sent in the command.

    int Noop()

    Sends the NOOP command and returns the status code received from the server. If no response is received, the function returns zero.

    int Rset()

    Sends the RSET command and returns the status code received from the server. If no response is received, the function returns zero.

    int Apop(const char* aName, const char* aDigest)

    Sends the APOP command and returns the status code received from the server. If no response is received, the function returns zero. aName is the name of the user, which is sent in the command. aDigest is the digest argument for the command.

    int Top(int aMsg, int aNumLines)

    Sends the TOP command and returns the status code received from the server. If no response is received, the function returns zero. aMsg is the message number. aNumLines is the number of lines to send.

    int Uidl()
    int Uidl(int aMsg)

    Sends the TOP command, with or without a message number, and returns the status code received from the server. If no response is received, the function returns zero. mimelib1-1.1.4/mimelib/doc/mechansm.html0000644000175000017500000001643711175345261017500 0ustar resivoresivo DwMechanism Man Page

    NAME

    DwMechanism -- Class representing a MIME content-transfer-encoding field-body

    SYNOPSIS

    class DW_EXPORT DwMechanism : public DwFieldBody {
    
    public:
    
        DwMechanism();
        DwMechanism(const DwMechanism& aCte);
        DwMechanism(const DwString& aStr, DwMessageComponent* aParent=0);
        virtual ~DwMechanism();
        const DwMechanism& operator = (const DwMechanism& aCte);
        virtual void Parse();
        virtual void Assemble();
        virtual DwMessageComponent* Clone() const;
        int AsEnum() const;
        void FromEnum(int aCte);
        static DwMechanism*
            NewMechanism(const DwString& aStr, DwMessageComponent* aParent);
        static DwMechanism*
            (*sNewMechanism)(const DwString&, DwMessageComponent*);
    
    public:
    
        virtual void PrintDebugInfo(ostream& aStrm, int aDepth=0) const;
        virtual void CheckInvariants() const;
    
    protected:
    
        void _PrintDebugInfo(ostream& aStrm) const;
    };
    

    DESCRIPTION

    DwMechanism represents a field body for the Content-Transfer-Encoding header field as described in RFC-2045. DwMechanism provides convenience functions that allow you to set or get the content-transfer-encoding attribute as an enumerated value.

    Public Member Functions

    DwMechanism()
    DwMechanism(const DwMechanism& aCte)
    DwMechanism(const DwString& aStr, DwMessageComponent* aParent=0)

    The first constructor is the default constructor, which sets the DwMechanism object's string representation to the empty string and sets its parent to NULL.

    The second constructor is the copy constructor, which copies the string representation from aCte. The parent of the new DwMechanism object is set to NULL.

    The third constructor copies aStr to the DwMechanism object's string representation and sets aParent as its parent. The virtual member function Parse() should be called immediately after this constructor in order to parse the string representation. Unless it is NULL, aParent should point to an object of a class derived from DwField.

    const DwMechanism& operator = (const DwMechanism& aCte)

    This is the assignment operator, which performs a deep copy of aCte. The parent node of the DwMechanism object is not changed.

    virtual void Parse()

    This virtual function, inherited from DwMessageComponent, executes the parse method for DwMechanism objects. It should be called immediately after the string representation is modified and before any of the object's attributes are retrieved.

    This function clears the is-modified flag.

    virtual void Assemble()

    This virtual function, inherited from DwMessageComponent, executes the assemble method for DwMechanism objects. It should be called whenever one of the object's attributes is changed in order to assemble the string representation. It will be called automatically for this object by the parent object's Assemble() member function if the is-modified flag is set.

    This function clears the is-modified flag.

    virtual DwMessageComponent* Clone() const

    This virtual function, inherited from DwMessageComponent, creates a new DwMechanism object on the free store that has the same value as this DwMechanism object. The basic idea is that of a virtual copy constructor.

    int AsEnum() const

    Returns the content transfer encoding as an enumerated value. Enumerated values are defined for all standard content transfer encodings in the file enum.h. If the content transfer encoding is non-standard DwMime::kCteUnknown is returned. The inherited member function DwMessageComponent::AsString() may be used to get the content transfer encoding, standard or non-standard, as a string.

    void FromEnum(int aCte)

    Sets the content transfer encoding from an enumerated value. Enumerated values are defined for all standard content transfer encodings in the file enum.h. You may set the content transfer encoding to any string value, standard or non-standard, by using the inherited member function DwMessageComponent::FromString().

    static DwMechanism* NewMechanism(const DwString& aStr, DwMessageComponent* aParent)

    Creates a new DwMechanism object on the free store. If the static data member sNewMechanism is NULL, this member function will create a new DwMechanism and return it. Otherwise, NewMechanism() will call the user-supplied function pointed to by sNewMechanism, which is assumed to return an object from a class derived from DwMechanism, and return that object.

    virtual void PrintDebugInfo(ostream& aStrm, int aDepth=0) const

    This virtual function, inherited from DwMessageComponent, prints debugging information about this object to aStrm. It will also call PrintDebugInfo() for any of its child components down to a level of aDepth.

    This member function is available only in the debug version of the library.

    virtual void CheckInvariants() const

    Aborts if one of the invariants of the object fails. Use this member function to track down bugs.

    This member function is available only in the debug version of the library.

    Public Data Members

    static DwMechanism* (*sNewMechanism)(const DwString&, DwMessageComponent*)

    If sNewMechanism is not NULL, it is assumed to point to a user-supplied function that returns an object from a class derived from DwMechanism.

    mimelib1-1.1.4/mimelib/doc/msgcmp.html0000644000175000017500000003146011175345261017164 0ustar resivoresivo DwMessageComponent Man Page

    NAME

    DwMessageComponent -- Abstract base class for all message components

    SYNOPSIS

    class DW_EXPORT DwMessageComponent {
    
    public:
    
        enum componentType {
            kCidError=-1,
            kCidUnknown=0,
            kCidAddress,
            kCidAddressList,
            kCidBody,
            kCidBodyPart,
            kCidDispositionType,
            kCidMechanism,
            kCidMediaType,
            kCidParameter,
            kCidDateTime,
            kCidEntity,
            kCidField,
            kCidFieldBody,
            kCidGroup,
            kCidHeaders,
            kCidMailbox,
            kCidMailboxList,
            kCidMessage,
            kCidMessageComponent,
            kCidMsgId,
            kCidText
        };
        DwMessageComponent();
        DwMessageComponent(const DwMessageComponent& aCmp);
        DwMessageComponent(const DwString& aStr, DwMessageComponent* aParent=0);
        virtual ~DwMessageComponent();
        const DwMessageComponent& operator = (const DwMessageComponent& aCmp);
        virtual void Parse() = 0;
        virtual void Assemble() = 0;
        virtual DwMessageComponent* Clone() const = 0;
        void FromString(const DwString& aStr);
        void FromString(const char* aCstr);
        const DwString& AsString();
        DwMessageComponent* Parent();
        void SetParent(DwMessageComponent* aParent);
        DwBool IsModified() const;
        void SetModified();
        int ClassId() const;
        const char* ClassName() const;
        int ObjectId() const;
    
    protected:
    
        DwString mString;
        DwBool mIsModified;
        DwMessageComponent* mParent;
        componentType mClassId;
        const char* mClassName;
    
    public:
    
        virtual void PrintDebugInfo(ostream& aStrm, int aDepth=0) const;
        virtual void CheckInvariants() const;
    
    protected:
    
        void _PrintDebugInfo(ostream& aStrm) const;
    };
    

    DESCRIPTION

    DwMessageComponent is the root of an inheritance hierarchy from which all MIME message components are derived. Thus, DwMessageComponent defines important features that are inherited by nearly all other classes that represent components of a MIME message. These features are the following:

    • A string representation. The DwMessageComponent class provides a member function FromString(const DwString&) to set the string representation and a member function AsString() to get the string representation.

    • A broken-down, or parsed, representation. An RFC-822 date-time, for example, has a year, month, day, hour, minute, second, and time zone as elements of its broken-down representation. DwMessageComponent does not deal directly with the broken-down representation, since it is component-specific. Derived classes bear all the responsibility for their broken-down representations.

    • A parse method to extract the broken-down representation from the string representation. In the DwDateTime class, for example, the parse method extracts the year, month, day, hour, minute, second, and time zone from the RFC-822 date-time contained in the string representation. DwMessageComponent provides a pure virtual function Parse(), which executes the parse method for a derived class.

    • An assemble method to convert the broken-down representation to a string representation. This is the opposite of the parse method. In the DwDateTime class, for example, the assemble method creates an RFC-822 date-time string from values of the year, month, day, hour, minute, second, and time zone. DwMessageComponent provides a pure virtual function Assemble(), which executes the assemble method for a derived class.

    • An is-modified flag. When the string representation and the broken-down representation are consistent, the assemble method does not need to be executed. The is-modified flag is cleared when the two representations are consistent, and is set when they are inconsistent. The flag is set automatically whenever a DwMessageComponent object's broken-down representation is changed by calling one of the object's member functions, and it is cleared when the assemble or parse method is executed. DwMessageComponent also provides a member function SetModified() which forces the is-modified flag to be set.

    • A parent. Most message components are part of another component. A collection of headers is part of a message or body part, a header field is part of a collection of headers, a field-body is part of a header field, and so on. The parent of a component is the component that contains it. This tree structure is important, since a component's parent must be parsed before the component can be. Also, a component's string representation must be assembled before its parent's. To maintain consistency in the tree, whenever a component's is-modified flag is set, the component notifies its parent to also set its is-modified flag. In this way, an is-modified flag set anywhere in the tree always propagates up to the root component.

    • Children. The preceding discussion about a component's parent is relevant to an understanding of a component's children. A component's parse method calls the parse methods of its children after it has executed its own parse method (and, in some cases, created all of its children). Also, a component typically calls the assemble method of its children before it executes its own. A component's child may request that the component set its is-modified flag. DwMessageComponent does not deal directly with children. Derived classes bear all the responsibility for handling their children.

    Public Member Functions

    DwMessageComponent()
    DwMessageComponent(const DwMessageComponent& aCmp)
    DwMessageComponent(const DwString& aStr, DwMessageComponent* aParent=0)

    The first constructor is the default constructor, which sets the DwMessageComponent object's string representation to the empty string and sets its parent to NULL.

    The second constructor is the copy constructor, which performs a deep copy of aCmp. The parent of the new DwMessageComponent object is set to NULL.

    The third constructor copies aStr to the new DwMessageComponent object's string representation and sets aParent as its parent. In typical cases, the virtual member function Parse() should be called immediately after this constructor to parse the new DwMessageComponent object and all of its children into their broken-down representations.

    const DwMessageComponent& operator = (const DwMessageComponent& aCmp)

    This is the assignment operator, which performs a deep copy of aCmp.

    virtual void Parse() = 0

    A pure virtual function which provides an interface to the parse method. The parse method, implemented in derived classes, is responsible for extracting the broken-down representation from the string representation. In some derived classes, such as DwHeaders, the parse method is also responsible for creating the children of the object. (In the case of DwHeaders, the children created are the DwField objects that represent the fields contained in the headers.) The Parse() function always calls the Parse() function of all of its children.

    virtual void Assemble() = 0

    A pure virtual function which provides an interface to the assemble method. The assemble method, implemented in derived classes, is responsible for creating the string representation from the broken-down representation. In other words, the assemble method is the opposite of the parse method. Before assembling its string representation, the assemble method calls the assemble method of each of its children. In this way, the entire tree structure that represents a message may be traversed. If the is-modifed flag for a DwMessageComponent is cleared, the Assemble() function will return immediately without calling the Assemble() function of any of its children.

    virtual DwMessageComponent* Clone() const = 0

    Creates a new DwMessageComponent on the free store that is of the same type as, and has the same value as, this object. The basic idea is that of a ``virtual copy constructor.''

    void FromString(const DwString& aStr)
    void FromString(const char* aCstr)

    Sets the object's string representation. aCstr must be NUL-terminated. This member function does not invoke the parse method. Typically, the virtual member function Parse() should be called immediately after this member function to parse the DwMessageComponent object and all of its children into their broken-down representations. See also DwMessageComponent::Parse()

    const DwString& AsString()

    Returns the DwMessageComponent object's string representation. The assemble method is not called automatically. Typically, the Assemble() member function should be called immediately before this member function to insure that the broken-down representation and the string representation are consistent. See also DwMessageComponent::Assemble().

    DwMessageComponent* Parent()

    Returns the DwMessageComponent object that is the parent of this object.

    void SetParent(DwMessageComponent* aParent)

    Sets aParent as the DwMessageComponent object's parent.

    DwBool IsModified() const

    Returns 1 if the is-modified flag is set for this DwMessageComponent object.

    void SetModified()

    Sets the is-modified (dirty) flag for this DwMessageComponent object and notifies the object's parent to also set its is-modified flag.

    int ClassId() const

    Returns an integer id for the object's class.

    const char* ClassName() const

    Returns the name of the class as a NUL-terminated char string.

    int ObjectId() const

    Returns a object id that is unique among all DwMessageComponent objects.

    virtual void PrintDebugInfo(ostream& aStrm, int aDepth=0) const

    This virtual function prints debugging information about this object to aStrm. It will also call PrintDebugInfo() for any of its child components down to a level of aDepth.

    This member function is available only in the debug version of the library.

    virtual void CheckInvariants() const

    Aborts if one of the invariants of the object fails. Use this member function to track down bugs.

    This member function is available only in the debug version of the library. mimelib1-1.1.4/mimelib/doc/bodypart.html0000644000175000017500000001504011175345261017516 0ustar resivoresivo DwBodyPart Man Page

    NAME

    DwBodyPart -- Class representing a MIME body-part

    SYNOPSIS

    class DW_EXPORT DwBodyPart : public DwEntity {
    
    public:
    
        DwBodyPart();
        DwBodyPart(const DwBodyPart& aPart);
        DwBodyPart(const DwString& aStr, DwMessageComponent* aParent=0);
        virtual ~DwBodyPart();
        const DwBodyPart& operator = (const DwBodyPart& aPart);
        virtual DwMessageComponent* Clone() const;
        static DwBodyPart* NewBodyPart(const DwString& aStr,
            DwMessageComponent* aParent);
        DwBodyPart* Next() const;
        void SetNext(const DwBodyPart* aPart);
        static DwBodyPart* (*sNewBodyPart)(const DwString&, DwMessageComponent*);
    
    public:
    
        virtual void PrintDebugInfo(ostream& aStrm, int aDepth=0) const;
        virtual void CheckInvariants() const;
    
    protected:
    
        void _PrintDebugInfo(ostream& aStrm) const;
    };
    

    DESCRIPTION

    DwBodyPart represents a body part, as described in RFC-2045 and RFC-2046. A body part is an entity, so it has a collection of headers and a body. A body part is different from a message in that a body part is part of a multipart body.

    In MIME++, a DwBodyPart is a subclass of DwEntity; therefore, it contains both a DwHeaders object and a DwBody object, and it is contained in a multipart DwBody object.

    As with DwMessage, most of the functionality of DwBodyPart is implemented by the abstract class DwEntity.

    Public Member Functions

    DwBodyPart()
    DwBodyPart(const DwBodyPart& aPart)
    DwBodyPart(const DwString& aStr, DwMessageComponent* aParent=0)

    The first constructor is the default constructor, which sets the DwBodyPart object's string representation to the empty string and sets its parent to NULL.

    The second constructor is the copy constructor, which performs a deep copy of aPart. The parent of the new DwBodyPart object is set to NULL.

    The third constructor copies aStr to the DwBodyPart object's string representation and sets aParent as its parent. The virtual member function Parse() should be called immediately after this constructor in order to parse the string representation. Unless it is NULL, aParent should point to an object of a class derived from DwBody.

    const DwBodyPart& operator = (const DwBodyPart& aPart)

    This is the assignment operator, which performs a deep copy of aPart. The parent node of the DwBodyPart object is not changed.

    virtual DwMessageComponent* Clone() const

    This virtual function, inherited from DwMessageComponent, creates a new DwBodyPart on the free store that has the same value as this DwBodyPart object. The basic idea is that of a virtual copy constructor.

    static DwBodyPart* NewBodyPart(const DwString& aStr, DwMessageComponent* aParent)

    Creates a new DwBodyPart on the free store. If the static data member sNewBodyPart is NULL, this member function will create a new DwBodyPart and return it. Otherwise, NewBodyPart() will call the user-supplied function pointed to by sNewBodyPart, which is assumed to return an object from a class derived from DwBodyPart, and return that object.

    DwBodyPart* Next() const

    This member function returns the next DwBodyPart object following this DwBodyPart in the list of DwBodyPart objects contained in a multipart DwBody.

    void SetNext(const DwBodyPart* aPart)

    This advanced function sets aPart as the next DwBodyPart object following this DwBodyPart in the list of DwBodyPart objects contained in a multipart DwBody. Since DwBody contains a member function for adding a DwBodyPart object to its list, this function should be avoided for most applications.

    virtual void PrintDebugInfo(ostream& aStrm, int aDepth=0) const

    This virtual function, inherited from DwMessageComponent, prints debugging information about this object to aStrm. It will also call PrintDebugInfo() for any of its child components down to a level of aDepth.

    This member function is available only in the debug version of the library.

    virtual void CheckInvariants() const

    Aborts if one of the invariants of the object fails. Use this member function to track down bugs.

    This member function is available only in the debug version of the library.

    Public Data Members

    static DwBodyPart* (*sNewBodyPart)(const DwString&, DwMessageComponent*)

    If sNewBodyPart is not NULL, it is assumed to point to a user-supplied function that returns an object from a class derived from DwBodyPart.

    mimelib1-1.1.4/mimelib/doc/binhex.html0000644000175000017500000001653511175345261017161 0ustar resivoresivo DwBinhex Man Page

    NAME

    DwBinhex -- Class for converting files to or from Binhex 4.0 format

    SYNOPSIS

    class DW_EXPORT DwBinhex {
    
    public:
    
        DwBinhex();
        virtual ~DwBinhex();
        void Initialize();
        const char* FileName() const;
        void SetFileName(const char* aName);
        void FileType(char* aBuf) const;
        void SetFileType(const char* aType);
        void FileCreator(char* aBuf) const;
        void SetFileCreator(const char* aType);
        DwUint8 Flag1() const;
        void SetFlag1(DwUint8 aFlag);
        DwUint8 Flag2() const;
        void SetFlag2(DwUint8 aFlag);
        const DwString& DataFork() const;
        void SetDataFork(const DwString& aStr);
        const DwString& ResourceFork() const;
        void SetResourceFork(const DwString& aStr);
        const DwString& BinhexChars() const;
        void SetBinhexChars(const DwString& aStr);
        void Encode();
        int Decode();
    };
    

    DESCRIPTION

    DwBinhex converts data to or from Binhex 4.0 format. Binhex is a format used almost exclusively on Macintosh computers for encoding files into text characters for transmission through the mail transport system or for archiving on non-Macintosh systems. The format includes the file name, file type, file creator, Macintosh Finder flags, data fork, resource fork, and checksums. In MIME, the use of Binhex is deprecated; applesingle and appledouble are the preferred format for encoding Macintosh files. The Binhex 4.0 format is described in RFC-1741. Binhex is a widely used, de facto standard, but it is not an official Internet standard.

    To use DwBinhex for converting a Macintosh file to Binex format, call the member functions SetFileName(), SetFileType(), SetFileCreator(), SetFlag1(), SetFlag2(), SetDataFork(), and SetResourceFork() to set the elements to be encoded. Any elements that are not set by calling one of the member functions are assigned reasonable defaults. Then call the Encode() member function to actually perform the conversion to Binhex. Finally, call BinhexChars() to retrieve the Binhex characters.

    To use DwBinhex for converting a Macintosh file from Binhex format, call the member function SetBinhexChars() to assign the Binhex characters to be converted. Then call Decode() to actually perform the conversion. Finally, call FileName(), FileType(), FileCreator(), Flag1(), Flag2(), DataFork(), and ResourceFork() to extract the decoded elements.

    Note: DwBinhex does not change the file name in any way. When you you are dealing with file names, you should be aware of the fact that some filenames that are valid on a Macintosh may cause problems or unexpected results on a non-Macintosh system, and vice versa. Such problem characters include slash ('/'), colon (':'), space and possibly other characters.

    Public Member Functions

    DwBinhex()

    This is the default constructor.

    void Initialize()

    Resets the object's internal state to its initial state. Call this member function to reuse the object for more than one encode or decode operation.

    const char* FileName() const
    void SetFileName(const char* aName)

    Gets or sets the file name. The file name is restricted to a maximum length of 63 characters.

    void FileType(char* aBuf) const
    void SetFileType(const char* aType)

    Gets or sets the file type. All Macintosh files have a file type, which is represented by four bytes. Some examples include "TEXT" for a text file, or "APPL" for an application. aBuf should point to an array of at least four characters.

    void FileCreator(char* aBuf) const
    void SetFileCreator(const char* aType)

    Gets or sets the file creator. Most Macintosh files have a creator, which is represented by a signature of four bytes. The creator specifies which application to launch when a file's icon is double clicked. aBuf should point to an array of at least four characters.

    DwUint8 Flag1() const
    void SetFlag1(DwUint8 aFlag)

    Gets or sets the first byte of the Macintosh Finder flags. For files that originate on non-Macintosh systems, this byte should be set to zero (the default).

    DwUint8 Flag2() const
    void SetFlag2(DwUint8 aFlag)

    Gets or sets the second byte of the Macintosh Finder flags. For files that originate on non-Macintosh systems, this byte should be set to zero (the default).

    const DwString& DataFork() const
    void SetDataFork(const DwString& aStr)

    Gets or sets the data fork for the file. For files that originate on non-Macintosh systems, such as a GIF or JPEG file, the file data should be set as the data fork.

    const DwString& ResourceFork() const
    void SetResourceFork(const DwString& aStr)

    Gets or sets the resource fork for the file. For files that originate on non-Macintosh systems, such as a GIF or JPEG file, the resource should be normally be empty.

    const DwString& BinhexChars() const
    void SetBinhexChars(const DwString& aStr)

    Gets or sets the characters of the Binhex encoded file.

    void Encode()

    Converts the Macintosh file information to Binhex format.

    int Decode()

    Converts the Macintosh file information from Binhex format. Returns zero if the decode operation completes successufully; otherwise, the function returns -1.

    mimelib1-1.1.4/mimelib/doc/text.html0000644000175000017500000001371211175345261016662 0ustar resivoresivo DwText Man Page

    NAME

    DwText -- Class representing text in a RFC-822 header field-body

    SYNOPSIS

    class DW_EXPORT DwText : public DwFieldBody {
    
    public:
    
        DwText();
        DwText(const DwText& aText);
        DwText(const DwString& aStr, DwMessageComponent* aParent=0);
        virtual ~DwText();
        const DwText& operator = (const DwText& aText);
        virtual void Parse();
        virtual void Assemble();
        virtual DwMessageComponent* Clone() const;
        static DwText* NewText(const DwString& aStr, DwMessageComponent* aParent);
        static DwText* (*sNewText)(const DwString&, DwMessageComponent*);
    
    public:
    
        virtual void PrintDebugInfo(ostream& aStrm, int aDepth=0) const;
        virtual void CheckInvariants() const;
    
    protected:
    
        void _PrintDebugInfo(ostream& aStrm) const;
    };
    

    DESCRIPTION

    DwText represents an unstructured field body in a header field. It roughly corresponds to the text element of the BNF grammar defined in RFC-822.

    Public Member Functions

    DwText()
    DwText(const DwText& aText)
    DwText(const DwString& aStr, DwMessageComponent* aParent=0)

    The first constructor is the default constructor, which sets the DwText object's string representation to the empty string and sets its parent to NULL.

    The second constructor is the copy constructor, which copies the string representation from aText. The parent of the new DwText object is set to NULL.

    The third constructor copies aStr to the DwText object's string representation and sets aParent as its parent. The virtual member function Parse() should be called immediately after this constructor in order to parse the string representation. Unless it is NULL, aParent should point to an object of a class derived from DwField.

    const DwText& operator = (const DwText& aText)

    This is the assignment operator.

    virtual void Parse()

    This virtual member function is inherited from DwMessageComponent, where it is declared a pure virtual function. For a DwText object, this member function does nothing, since DwText represents an unstructured field body (like the Subject header field) that does not have a broken-down form.

    Note, however, that this function should still be called consistently, since a subclass of DwText may implement a parse method.

    This function clears the is-modified flag.

    virtual void Assemble()

    This virtual member function is inherited from DwMessageComponent, where it is declared a pure virtual function. For a DwText object, this member function does nothing, since DwText represents an unstructured field body (like the Subject header field) that does not have a broken-down form.

    Note, however, that this function should still be called consistently, since a subclass of DwText may implement an assemble method.

    This function clears the is-modified flag.

    virtual DwMessageComponent* Clone() const

    This virtual function, inherited from DwMessageComponent, creates a new DwText on the free store that has the same value as this DwText object. The basic idea is that of a ``virtual copy constructor.''

    static DwText* NewText(const DwString& aStr, DwMessageComponent* aParent)

    Creates a new DwText object on the free store. If the static data member sNewText is NULL, this member function will create a new DwText and return it. Otherwise, NewText() will call the user-supplied function pointed to by sNewText, which is assumed to return an object from a class derived from DwText, and return that object.

    virtual void PrintDebugInfo(ostream& aStrm, int aDepth=0) const

    This virtual function, inherited from DwMessageComponent, prints debugging information about this object to aStrm. It will also call PrintDebugInfo() for any of its child components down to a level of aDepth.

    This member function is available only in the debug version of the library.

    virtual void CheckInvariants() const

    Aborts if one of the invariants of the object fails. Use this member function to track down bugs.

    This member function is available only in the debug version of the library.

    Public Data Members

    static DwText* (*sNewText)(const DwString&, DwMessageComponent*)

    If sNewText is not NULL, it is assumed to point to a user-supplied function that returns an object from a class derived from DwText. mimelib1-1.1.4/mimelib/doc/nntp.html0000644000175000017500000004620111175345261016654 0ustar resivoresivo DwNntpClient Man Page

    NAME

    DwNntpClient -- Class for handling the client side of an NNTP session

    SYNOPSIS

    class DW_EXPORT DwNntpClient : public DwProtocolClient {
    
    public:
    
        enum {
            kCmdNoCommand=0,
            kCmdArticle,
            kCmdBody,
            kCmdHead,
            kCmdStat,
            kCmdGroup,
            kCmdHelp,
            kCmdIhave,
            kCmdLast,
            kCmdList,
            kCmdNewgroups,
            kCmdNewnews,
            kCmdNext,
            kCmdPost,
            kCmdQuit,
            kCmdSlave
        };
        DwNntpClient();
        virtual ~DwNntpClient();
        virtual int Open(const char* aServer, DwUint16 aPort=119);
        DwObserver* SetObserver(DwObserver* aObserver);
        int ReplyCode() const;
        const DwString& StatusResponse() const;
        const DwString& TextResponse() const;
        int Article(int aNumber=(-1));
        int Article(const char* aMsgid);
        int Body(int aNumber=(-1));
        int Body(const char* aMsgid);
        int Head(int aNumber=(-1));
        int Head(const char* aMsgid);
        int Stat(int aNumber=(-1));
        int Stat(const char* aMsgid);
        int Group(const char* aNewsgroupName);
        int Help();
        int Ihave(const char* aMsgId);
        int Last();
        int List();
        int Newgroups(const char* aDate, const char* aTime,
            DwBool aIsGmt=DwFalse, const char* aDistributions=0);
        int Newnews(const char* aNewsgroups, const char* aDate,
            const char* aTime, DwBool aIsGmt=DwFalse, const char* aDistribution=0);
        int Next();
        int Post();
        int Quit();
        int Slave();
        int SendData(const DwString& aStr);
        int SendData(const char* aBuf, int aBufLen);
    };
    

    DESCRIPTION

    DwNntpClient is a class that handles the client side of an NNTP session. Specifically, DwNntpClient provides facilities for opening a connection to an NNTP server, sending commands and data to the server, receiving responses and data from the server, and closing the connection. The protocol implemented is the Network News Transport Protocol, as specified in RFC-977.

    DwNntpClient is derived from DwProtocolClient. For information about inherited member functions, especially member functions for detecting failures or errors, see the man page for DwProtocolClient.

    In an NNTP session, the client sends commands to the server and receives responses from the server. A client command consists of a command word and zero or more argument words. A server response consists of a status line and possibly some additional lines of text. The status line consists of a three-digit numeric reply code followed by additional information. The reply code indicates a success or failure condition. In some cases, the server sends lines of text immediately after the status line. DwNntpClient provides facilities for you to send commands to the server and receive responses from the server.

    DwNntpClient has only a default constructor. On Win32 platforms, it is possible for the constructor to fail. (It calls WSAStartup().) You should verify that the constructor succeeded by calling the inherited member function DwProtocolClient::LastError() and checking for a zero return value.

    To open a connection to the server, call the member function Open() with the name of the server as an argument. Open() accepts an optional argument that specifies the TCP port that the server listens to. The default port is the standard NNTP port (119). Open() may fail, so you should check the return value to verify that it succeeded. To close the connection, call the inherited member function DwProtocolClient::Close(). To check if a connection is open, call the inherited member function DwProtocolClient::IsOpen(). IsOpen() returns a boolean value that indicates whether or not a call to Open() was successful; it will not detect failure in the network or a close operation by the remote host.

    For each NNTP command, DwNntpClient has a member function that sends that command and receives the server's response. If the command takes any arguments, then those arguments are passed as function arguments to the command function. The command functions return the numeric value of the three-digit reply code returned by the server. Your program must check the reply code to determine whether or not the command was accepted and performed by the server. In some cases, because of a communications error or some other error, it is not possible for the command function to send the command or receive the response. When this happens, the command function will return 0. You can determine the precise error or failure by calling the inherited member functions DwProtocolClient::LastError() or DwProtocolClient::LastFailure().

    After each command is sent, DwNntpClient receives the server's response and remembers it. The member function ReplyCode() returns the numeric value of the reply code received in response to the last command. StatusResponse() returns the entire status response from the server, including the reply code. If no status response is received, possibly because of a communications error or failure, ReplyCode() returns zero and StatusResponse() returns an empty string.

    The server sends a status response, including a reply code, for all all NNTP commands. For some commands, such as when the client requests an article body, the server sends a multi-line text response immediately following the status response. Multi-line text responses can be received in either of two ways. The simplest way is to call the member function TextResponse() after a command completes successfully. This simple method works fine for non-interactive applications. It can be a problem in interactive applications, however, because there is no data to display to a user until the entire text response is retrieved. An alternative method allows your program to retrieve the text response one line at a time as it is received. To use this method, you must define a subclass of DwObserver and assign an object of that class to the DwNntpClient object using the member function SetObserver(). DwObserver is an abstract class, declared in protocol.h, that has just one pure virtual member function Notify(). After each line of the text response is received, DwNntpClient will call the Notify() member function of its assigned DwObserver object. Each invocation of Notify() should call the DwNntpClient member function TextResponse() to retrieve the next line of the text response. Note that you cannot use both of these methods at the same time: if an observer is assigned, TextResponse() returns only the last line received, not the entire multi-line text response.

    Certain NNTP commands, such as the POST command, require the NNTP client to send multiple lines of text to the server. To perform this bulk data transfer, DwNntpClient provides the member function SendData(). In the current implementation, SendData() does not convert end of line characters, so it is your responsibility to convert the end of line characters to CR LF, if necessary. (You may use the utility function DwToCrLfEol() to do the conversion.) SendData() will perform the character stuffing to protect '.' at the beginning of a line, and it will append the final [CR LF] '.' CR LF. It is possible to divide data and make multiple calls to SendData(); however, if you do so, please note the following paragraph.

    Note: Because of a feature (some might say bug) in the current implementation, SendData() will not detect a '.' at the beginning of a line if the CR LF '.' sequence is split between two calls to SendData(). This problem will probably be resolved in a future version, but be aware that such a change will require a change in DwNntpClient's interface.

    Public Member Functions

    DwNntpClient()

    Initializes the DwNntpClient object. It is possible for the constructor to fail. To verify that the constructor succeeded, call the member function LastError() and check that it returns zero. (In the Win32 implementation, the constructor calls the Winsock function WSAStartup(), which may fail.)

    virtual int Open(const char* aServer, DwUint16 aPort=119)

    Opens a TCP connection to the server aServer at port aPort. aServer may be either a host name, such as "news.acme.com" or an IP number in dotted decimal format, such as "147.81.64.60". The default value for aPort is 119, the well-known port for NNTP assigned by the Internet Assigned Numbers Authority (IANA).

    If the connection attempt succeeds, the server sends a response. Open() returns the server's numeric reply code. The full response from the server can be retrieved by calling StatusResponse().

    If the connection attempt fails, Open() returns 0. To determine what error occurred when a connection attempt fails, call the inherited member function DwProtocolClient::LastError(). To determine if a failure also occurred, call the inherited member function DwProtocolClient::LastFailure().

    DwObserver* SetObserver(DwObserver* aObserver)

    Sets the observer object that interacts with the DwNntpClient object to retrieve a multi-line text response. If an observer is set, DwNntpClient will call the observer's Notify() method after each line of the text response is received. To remove an observer, call SetObserver() with a NULL argument. SetObserver() returns the previously set observer, or NULL if no observer was previously set.

    int ReplyCode() const

    Returns the numeric value of the three-digit reply code received from the server in response to the last client command. If no response was received, ReplyCode() returns zero.

    const DwString& StatusResponse() const

    Returns the entire status response last received from the server. If no response was received, perhaps because of a communications failure, StatusResponse() returns an empty string.

    const DwString& TextResponse() const

    If no observer is set for this object, TextResponse() returns a string that comprises the entire sequence of lines received from the server. Otherwise, if an observer is set for this object, TextResponse() returns only the most recent line received.

    int Article(int aNumber=(-1))
    int Article(const char* aMsgid)

    Sends the NNTP ARTICLE command and returns the reply code received from the server. If no response is received, the function returns zero. The optional argument aNumber specifies the number of an article to retrieve. If Article() is called with the default argument, the ARTICLE command is sent to the server with no argument. aMsgId specifies the message id of an article to retrieve.

    int Body(int aNumber=(-1))
    int Body(const char* aMsgid)

    Sends the NNTP BODY command and returns the reply code received from the server. If no response is received, the function returns zero. The optional argument aNumber specifies the number of an article whose body should be retrieved. If Body() is called with the default argument, the BODY command is sent to the server with no argument. aMsgId specifies the message id of the article to access.

    int Head(int aNumber=(-1))
    int Head(const char* aMsgid)

    Sends the NNTP HEAD command and returns the reply code received from the server. If no response is received, the function returns zero. The optional argument aNumber specifies the number of an article whose header lines should be retrieved. If Head() is called with the default argument, the HEAD command is sent to the server with no argument. aMsgId specifies the message id of the article to access.

    int Stat(int aNumber=(-1))
    int Stat(const char* aMsgid)

    Sends the NNTP STAT command and returns the reply code received from the server. If no response is received, the function returns zero. The optional argument aNumber specifies the number of an article to access. If Stat() is called with the default argument, the STAT command is sent to the server with no argument. aMsgId specifies the message id of the article to access.

    int Group(const char* aNewsgroupName)

    Sends the NNTP GROUP command and returns the reply code received from the server. The argument aNewsgroupName specifies the newgroup to be selected. If no response is received, the function returns zero.

    int Help()

    Sends the NNTP HELP command and returns the reply code received from the server. If no response is received, the function returns zero.

    int Ihave(const char* aMsgId)

    Sends the NNTP IHAVE command and returns the reply code received from the server. aMsgId specifies the message id of the article to be sent. If no response is received, the function returns zero.

    int Last()

    Sends the NNTP LAST command and returns the reply code received from the server. If no response is received, the function returns zero.

    int List()

    Sends the NNTP LIST command and returns the reply code received from the server. If no response is received, the function returns zero.

    int Newgroups(const char* aDate, const char* aTime, DwBool aIsGmt=DwFalse, const char* aDistributions=0)

    Sends the NNTP NEWGROUPS command and returns the reply code received from the server. If no response is received, the function returns zero. aDate is the date in the form YYMMDD, where YY is the two digit year, MM is the month, and DD is the day of the month. aTime is the time in the form HHMMSS, where HH is hours, MM is minutes, and SS is seconds. If aIsGmt is true, the optional GMT argument will be sent. aDistributions specifies the optional list of distribution groups.

    int Newnews(const char* aNewsgroups, const char* aDate, const char* aTime, DwBool aIsGmt=DwFalse, const char* aDistribution=0)

    Sends the NNTP NEWNEWS command and returns the reply code received from the server. If no response is received, the function returns zero. aNewsgroups is the newsgroups argument for the command. aDate is the date in the form YYMMDD, where YY is the two digit year, MM is the month, and DD is the day of the month. aTime is the time in the form HHMMSS, where HH is hours, MM is minutes, and SS is seconds. If aIsGmt is true, the optional GMT argument will be sent. aDistributions specifies the optional list of distribution groups.

    int Next()

    Sends the NNTP NEXT command and returns the reply code received from the server. If no response is received, perhaps because of an error, the function returns zero.

    int Post()

    Sends the NNTP POST command and returns the reply code received from the server. If no response is received, perhaps because of an error, the function returns zero.

    int Quit()

    Sends the NNTP QUIT command and returns the reply code received from the server. If no response is received, perhaps because of an error, the function returns zero.

    int Slave()

    Sends the NNTP SLAVE command and returns the reply code received from the server. If no response is received, perhaps because of an error, the function returns zero.

    int SendData(const DwString& aStr)
    int SendData(const char* aBuf, int aBufLen)

    Sends bulk data to the server and returns the reply code received. A bulk data transfer follows a POST or IHAVE command and is used to send a complete article to the server.

    In the current implementation, SendData() does not convert end of line characters, so it is your responsibility to convert the end of line characters to CR LF, if necessary. (You may use the utility function DwToCrLfEol() to do the conversion.) SendData() will perform the character stuffing to protect '.' at the beginning of a line, and it will append the final [CR LF] '.' CR LF. It is possible to divide the data and make multiple calls to SendData(); however, this may cause problems in the current implementation if a CR LF '.' sequence is split between calls. mimelib1-1.1.4/mimelib/doc/entity.html0000644000175000017500000001563111175345261017214 0ustar resivoresivo DwEntity Man Page

    NAME

    DwEntity -- Abstract class representing a MIME entity

    SYNOPSIS

    class DW_EXPORT DwEntity : public DwMessageComponent {
    
    public:
    
        DwEntity();
        DwEntity(const DwEntity& aEntity);
        DwEntity(const DwString& aStr, DwMessageComponent* aParent=0);
        virtual ~DwEntity();
        const DwEntity& operator = (const DwEntity& aEntity);
        virtual void Parse();
        virtual void Assemble();
        DwHeaders& Headers() const;
        DwBody& Body() const;
    
    protected:
    
        DwHeaders* mHeaders;
        DwBody*    mBody;
    
    public:
    
        virtual void PrintDebugInfo(ostream& aStrm, int aDepth=0) const;
        virtual void CheckInvariants() const;
    
    protected:
    
        void _PrintDebugInfo(ostream& aStrm) const;
    };
    

    DESCRIPTION

    RFC-2045 defines an entity as either a message or a body part, both of which have a collection of headers and a body. In MIME++, an entity is represented by the class DwEntity, which contains both a DwHeaders object and a DwBody object.

    In the tree (broken-down) representation of message, a DwEntity object may be either a root node, having child nodes but no parent node, or an intermediate node, having both a parent node and child nodes. A DwEntity object that is a root node must also be a DwMessage object. If a DwEntity object is an intermediate node, its parent must be a DwBody object. The child nodes of a DwEntity object are the DwHeaders and DwBody objects it contains.

    Since DwEntity is an abstract base class, you cannot create instances of it directly. DwEntity has two derived classes, DwMessage and DwBodyPart, which are concrete classes.

    To access the contained DwHeaders object, use the member function Headers(). To access the contained DwBody object, use the member function Body().

    Public Member Functions

    DwEntity()
    DwEntity(const DwEntity& aEntity)
    DwEntity(const DwString& aStr, DwMessageComponent* aParent=0)

    The first constructor is the default constructor, which sets the DwEntity object's string representation to the empty string and sets its parent to NULL.

    The second constructor is the copy constructor, which performs a deep copy of aEntity. The parent of the new DwEntity object is set to NULL.

    The third constructor copies aStr to the DwEntity object's string representation and sets aParent as its parent. The virtual member function Parse() should be called immediately after this constructor in order to parse the string representation. Unless it is NULL, aParent should point to an object of a class derived from DwBody.

    const DwEntity& operator = (const DwEntity& aEntity)

    This is the assignment operator, which performs a deep copy of aEntity. The parent node of the DwEntity object is not changed.

    virtual void Parse()

    This virtual function, inherited from DwMessageComponent, executes the parse method for DwEntity objects. The parse method creates or updates the broken-down representation from the string representation. For DwEntity objects, the parse method parses the string representation and sets the values of the DwHeaders and DwBody objects it contains. This member function also calls the Parse() member functions of the contained DwHeaders and DwBody objects.

    You should call this member function after you set or modify the string representation, and before you access either the contained headers or body.

    This function clears the is-modified flag.

    virtual void Assemble()

    This virtual function, inherited from DwMessageComponent, executes the assemble method for DwEntity objects. The assemble method creates or updates the string representation from the broken-down representation. In more concrete terms, the assemble method builds the string representation from the string representations of the contained DwHeaders and DwBody objects. This member function calls the Assemble() member functions of its DwHeaders and DwBody objects.

    You should call this member function after you modify either the contained headers or body, and before you retrieve the string representation.

    This function clears the is-modified flag.

    DwHeaders& Headers() const

    This function returns the DwHeaders object contained by this object.

    DwBody& Body() const

    This function returns the DwBody object contained by this object.

    virtual void PrintDebugInfo(ostream& aStrm, int aDepth=0) const

    This virtual function, inherited from DwMessageComponent, prints debugging information about this object to aStrm. It will also call PrintDebugInfo() for any of its child components down to a level of aDepth.

    This member function is available only in the debug version of the library.

    virtual void CheckInvariants() const

    Aborts if one of the invariants of the object fails. Use this member function to track down bugs.

    This member function is available only in the debug version of the library.

    mimelib1-1.1.4/mimelib/doc/protocol.html0000644000175000017500000002734211175345261017543 0ustar resivoresivo DwProtocolClient Man Page

    NAME

    DwProtocolClient -- Base class for all protocol clients

    SYNOPSIS

    class DW_EXPORT DwProtocolClient {
    
    public:
    
        enum Failure {
            kFailNoFailure      = 0, // No failure
            kFailNoWinsock      = 1, // A usable Winsock DLL could not be found
            kFailNetDown        = 2, // The network is down
            kFailHostNotFound   = 3, // The server was not found
            kFailConnReset      = 4, // The connection was reset
            kFailNetUnreachable = 5, // The network is unreachable
            kFailTimedOut       = 6, // Timed out while waiting for an operation
                                     // to complete
            kFailConnDropped    = 7,
            kFailConnRefused    = 8,
            kFailNoResources    = 9
        };
    
        enum Error {
            kErrNoError = 0,
            kErrUnknownError = 0x4000,
            kErrBadParameter = 0x4001,
            kErrBadUsage     = 0x4002,
            kErrNoWinsock    = 0x4003,  // Win32
            kErrHostNotFound = 0x5000,  // UNIX
            kErrTryAgain     = 0x5001,  // UNIX
            kErrNoRecovery   = 0x5002,  // UNIX
            kErrNoData       = 0x5003,  // UNIX
            kErrNoAddress    = 0x5004,  // UNIX
        };
    
    protected:
    
        DwProtocolClient();
    
    public:
    
        virtual ~DwProtocolClient();
        virtual int Open(const char* aServer, DwUint16 aPort);
        DwBool IsOpen() const;
        int Close();
        int SetReceiveTimeout(int aSecs);
        int LastCommand() const;
        int LastFailure() const;
        const char* LastFailureStr() const;
        int LastError() const;
        const char* LastErrorStr() const;
    
    protected:
    
        enum {
            kWSAStartup=1,  // Win32
            kgethostbyname,
            ksocket,
            ksetsockopt,
            kconnect,
            ksend,
            krecv,
            kclose,         // UNIX
            kclosesocket,   // Win32
            kselect
        };
        DwBool      mIsDllOpen;
        DwBool      mIsOpen;
        SOCKET      mSocket;
        DwUint16    mPort;
        char*       mServerName;
        int         mReceiveTimeout;
        int         mLastCommand;
        int         mFailureCode;
        const char* mFailureStr;
        int         mErrorCode;
        const char* mErrorStr;
        virtual void HandleError(int aErrorCode, int aSystemCall);
        int PSend(const char* aBuf, int aBufLen);
        int PReceive(char* aBuf, int aBufSize);
    };
    

    DESCRIPTION

    DwProtocolClient is the base class for other classes that implement specific protocols, such as SMTP, POP, and NNTP. DwProtocolClient serves two purposes. First, It combines operations common to all its derived classes, such as opening a TCP connection to the server. Second, it provides a platform-independent interface to the network services required by its subclasses.

    There are two separate implementations of DwProtocolClient: one for Berkeley sockets under UNIX, and one for Winsock under Win32. The interface is the same for both implementations, thus providing platform independence.

    There are two platform-specific details that you should be aware of. First, if you are writing a UNIX program, you should be sure to handle the SIGPIPE signal. This signal is raised when a program tries to write to a TCP connection that was shutdown by the remote host. The default action for this signal is to terminate the program. To prevent this from happening in your program, you should either catch the signal or tell the operating system to ignore it. Second, if you are writing a Win32 application for Windows NT or Windows95, you should be aware of the fact that the constructor calls the Winsock function WSAStartup() to initialize the Winsock DLL. (The destructor calls WSACleanup().) Because it is possible for WSAStartup() to fail, it is also possible that the constructor may fail. To verify that the constructor has succeeded, call the member function LastError() and check that it returns zero.

    To open a connection to a server, call Open() with the server name and TCP port number as arguments. Open() is declared virtual; derived classes may override this member function. Open() may fail, so you should check the return value to verify that it succeeded. To close the connection, call Close(). To check if a connection is open, call IsOpen(). IsOpen() returns a value that indicates whether or not a call to Open() was successful; it will not detect failure in the network or a close operation by the remote host.

    DwProtocolClient sets a timeout on receive operations on the TCP connection. The default value of the timeout period is 90 seconds. To change the default value, call SetReceiveTimeout() and pass the new value as an argument.

    Whenever DwProtocolClient cannot complete an operation, it is because an error has occurred. Most member functions indicate that an error has occurred via their return values. For most member functions, a return value of -1 indicates an error. To get the specific error that has occurred, call LastError(), which returns either the system error code or a MIME++ defined error code. To get a text string that describes the error, call LastErrorStr().

    Some errors are also considered "failures." A failure occurs when an operation cannot be completed because of conditions external to the program. For example, a failure occurs when the network is down or when an application's user enters bad input. Errors that occur because of programmer error are not considered failures. If an error occurs, you should call LastError() to determine the error, but you should also call LastFailure() to determine if a failure occurred. In interactive applications, failures should always be reported to the application's user. To get a text string that describes a failure, call LastFailureStr().

    It is possible to translate the error and failure message strings to a language other than English. To do this, you may override the virtual function HandleError().

    Public Member Functions

    virtual ~DwProtocolClient()

    Frees the resources used by this object. In a Win32 environment, the destructor calls WSACleanup().

    virtual int Open(const char* aServer, DwUint16 aPort)

    Opens a TCP connection to the server aServer at port aPort. aServer may be either a host name, such as "smtp.acme.com" or an IP number in dotted decimal format, such as "147.81.64.59". If the connection attempt succeeds, Open() returns 0; othewise, it returns -1. To determine what error occurred when the connection attempt fails, call the member function LastError(). To determine if a failure also occurred, call the member function LastFailure().

    DwBool IsOpen() const

    Returns true value if a connection to the server is open. IsOpen() will return a true value if a call to Open() was successful; it will not detect failure in the network or a close operation by the remote host.

    int Close()

    Closes the connection to the server. Returns 0 if successful, or returns -1 if unsuccessful.

    int SetReceiveTimeout(int aSecs)

    Changes the default timeout for receive operations on the socket to aSecs seconds. The default value is 90 seconds.

    int LastCommand() const

    Returns an enumerated value indicating the last command sent to the server. Enumerated values are defined in subclasses of DwProtocolClient.

    int LastFailure() const

    Returns an enumerated value indicating what failure last occurred.

    const char* LastFailureStr() const

    Returns a failure message string associated with the failure code returned by LastFailure().

    int LastError() const

    Returns an error code for the last error that occurred. Normally, the error code returned is an error code returned by a system call; DwProtocolClient does no translation of error codes returned by system calls. In some cases, an error code defined by MIME++ may returned to indicate improper use of the DwProtocolClient class.

    const char* LastErrorStr() const

    Returns an error message string associated with the error code returned by LastError().

    Protected Member Functions

    DwProtocolClient()

    Initializes the DwProtocolClient object. In a Win32 environment, this constructor calls WSAStartup() to initialize the Winsock DLL. To verify that the DLL was initialized successfully, call the member function LastError() and verify that it returns zero.

    virtual void HandleError(int aErrorCode, int aSystemCall)

    Interprets error codes. aErrorCode is an error code, which may be a system error code, or an error code defined by DwProtocolClient. aSystemCall is an enumerated value defined by DwProtocolClient that indicates the last system call made, which should be the system call that set the error code. HandleError() sets values for mErrorStr, mFailureCode, and mFailureStr.

    int PSend(const char* aBuf, int aBufLen)

    Sends aBufLen characters from the buffer aBuf. Returns the number of characters sent. If the number of characters sent is less than the number of characters specified in aBufLen, the caller should call LastError() to determine what, if any, error occurred. To determine if a failure also occurred, call the member function LastFailure().

    int PReceive(char* aBuf, int aBufSize)

    Receives up to aBufSize characters into the buffer aBuf. Returns the number of characters received. If zero is returned, the caller should call the member function LastError() to determine what, if any, error occurred. To determine if a failure also occurred, call the member function LastFailure(). mimelib1-1.1.4/mimelib/doc/message.html0000644000175000017500000001310611175345261017317 0ustar resivoresivo DwMessage Man Page

    NAME

    DwMessage -- Class representing an RFC-822/MIME message

    SYNOPSIS

    class DW_EXPORT DwMessage : public DwEntity {
    
    public:
    
        DwMessage();
        DwMessage(const DwMessage& aMessage);
        DwMessage(const DwString& aStr, DwMessageComponent* aParent=0);
        virtual ~DwMessage();
        const DwMessage& operator = (const DwMessage& aMessage);
        virtual DwMessageComponent* Clone() const;
        static DwMessage* NewMessage(const DwString& aStr,
            DwMessageComponent* aParent);
        static DwMessage* (*sNewMessage)(const DwString&, DwMessageComponent*);
    
    public:
    
        virtual void PrintDebugInfo(ostream& aStrm, int aDepth=0) const;
    
    protected:
    
        void _PrintDebugInfo(ostream& aStrm) const;
    };
    

    DESCRIPTION

    DwMessage represents an RFC-822/MIME message.

    A message contains both a collection of header fields and a body. In the terminology of RFC-2045, the general term for the headers-body combination is entity. In MIME++, DwMessage is a direct subclass of DwEntity, and therefore contains both a DwHeaders object and a DwBody object.

    In the tree (broken-down) representation of message, a DwMessage object is almost always a root node, having child nodes but no parent node. The child nodes are the DwHeaders object and the DwBody object it contains. A DwMessage may sometimes be an intermediate node. In this special case, the parent node is a DwBody object of type "message/*" and the DwMessage object represents an encapsulated message.

    To access the contained DwHeaders object, use the inherited member function DwEntity::Headers(). To access the contained DwBody object, use the inherited member function DwEntity::Body().

    Public Member Functions

    DwMessage()
    DwMessage(const DwMessage& aMessage)
    DwMessage(const DwString& aStr, DwMessageComponent* aParent=0)

    The first constructor is the default constructor, which sets the DwMessage object's string representation to the empty string and sets its parent to NULL.

    The second constructor is the copy constructor, which performs a deep copy of aMessage. The parent of the new DwMessage object is set to NULL.

    The third constructor copies aStr to the DwMessage object's string representation and sets aParent as its parent. The virtual member function Parse() should be called immediately after this constructor in order to parse the string representation.

    const DwMessage& operator = (const DwMessage& aMessage)

    This is the assignment operator, which performs a deep copy of aMessage. The parent node of the DwMessage object is not changed.

    virtual DwMessageComponent* Clone() const

    This virtual function, inherited from DwMessageComponent, creates a new DwMessage on the free store that has the same value as this DwMessage object. The basic idea is that of a ``virtual copy constructor.''

    static DwMessage* NewMessage(const DwString& aStr, DwMessageComponent* aParent)

    Creates a new DwMessage object on the free store. If the static data member sNewMessage is NULL, this member function will create a new DwMessage and return it. Otherwise, NewMessage() will call the user-supplied function pointed to by sNewMessage, which is assumed to return an object from a class derived from DwMessage, and return that object.

    virtual void PrintDebugInfo(ostream& aStrm, int aDepth=0) const

    This virtual function, inherited from DwMessageComponent, prints debugging information about this object to aStrm. It will also call PrintDebugInfo() for any of its child components down to a level of aDepth.

    This member function is available only in the debug version of the library.

    Public Data Members

    static DwMessage* (*sNewMessage)(const DwString&, DwMessageComponent*)

    If sNewMessage is not NULL, it is assumed to point to a user supplied function that returns an object from a class derived from DwMessage.

    mimelib1-1.1.4/mimelib/doc/mailbox.html0000644000175000017500000002350711175345261017334 0ustar resivoresivo DwMailbox Man Page

    NAME

    DwMailbox -- Class representing an RFC-822 mailbox

    SYNOPSIS

    class DW_EXPORT DwMailbox : public DwAddress {
    
        friend class DwMailboxList;
    
    public:
    
        DwMailbox();
        DwMailbox(const DwMailbox& aMailbox);
        DwMailbox(const DwString& aStr, DwMessageComponent* aParent=0);
        virtual ~DwMailbox();
        const DwMailbox& operator = (const DwMailbox& aMailbox);
        virtual void Parse();
        virtual void Assemble();
        virtual DwMessageComponent* Clone() const;
        const DwString& FullName() const;
        void SetFullName(const DwString& aFullName);
        const DwString& Route() const;
        void SetRoute(const DwString& aRoute);
        const DwString& LocalPart() const;
        void SetLocalPart(const DwString& aLocalPart);
        const DwString& Domain() const;
        void SetDomain(const DwString& aDomain);
        static DwMailbox* NewMailbox(const DwString& aStr, DwMessageComponent*
            aParent);
        static DwMailbox* (*sNewMailbox)(const DwString&, DwMessageComponent*);
    
    public:
    
        virtual void PrintDebugInfo(ostream& aStrm, int aDepth=0) const;
        virtual void CheckInvariants() const;
    
    protected:
    
        void _PrintDebugInfo(ostream& aStrm) const;
    };
    

    DESCRIPTION

    RFC-822 defines a mailbox as an entity that can be the recipient of a message. A mailbox is more specific than an address, which may be either a mailbox or a group. An RFC-822 mailbox contains a full name, a local-part, an optional route, and a domain. For example, in the mailbox

    Joe Schmoe <jschmoe@aol.co>

    "Joe Schmoe" is the full name, "jschmoe" is the local-part, and "aol.com" is the domain. The optional route is rarely seen in current usage, and is deprecated according to RFC-1123.

    In MIME++, an RFC-822 mailbox is represented by a DwMailbox object. DwMailbox is a subclass of DwAddress, which reflects the fact that a mailbox is also an address. A DwMailbox contains strings representing the full name, local-part, route, and domain of a mailbox.

    In the tree (broken-down) representation of message, a DwMailbox object may be only a leaf node, having a parent but no child nodes. Its parent node must be a DwField, a DwAddressList, or a DwMailboxList object.

    DwMailbox has member functions for getting or setting the strings it contains.

    DwMailbox object can be included in a list of DwMailbox objects. To get the next DwMailbox object in a list, use the inherited member function DwAddress::Next().

    Public Member Functions

    DwMailbox()
    DwMailbox(const DwMailbox& aMailbox)
    DwMailbox(const DwString& aStr, DwMessageComponent* aParent=0)

    The first constructor is the default constructor, which sets the DwMailbox object's string representation to the empty string and sets its parent to NULL.

    The second constructor is the copy constructor, which performs a deep copy of aMailbox. The parent of the new DwMailbox is set to NULL.

    The third constructor copies aStr to the DwMailbox object's string representation and sets aParent as its parent. The virtual member function Parse() should be called immediately after this constructor in order to parse the string representation. Unless it is NULL, aParent should point to an object of a class derived from DwField.

    const DwMailbox& operator = (const DwMailbox& aMailbox)

    This is the assignment operator, which performs a deep copy of aMailbox. The parent node of the DwMailbox object is not changed.

    virtual void Parse()

    This virtual function, inherited from DwMessageComponent, executes the parse method for DwMailbox objects. The parse method creates or updates the broken-down representation from the string representation. For DwMailbox objects, the parse method parses the string representation into the substrings for the full name, local-part, route, and domain.

    You should call this member function after you set or modify the string representation, and before you retrieve the full name, local-part, route, or domain.

    This function clears the is-modified flag.

    virtual void Assemble()

    This virtual function, inherited from DwMessageComponent, executes the assemble method for DwMailbox objects. The assemble method creates or updates the string representation from the broken-down representation. For DwMailbox objects, the assemble method builds the string representation from the full name, local-part, route, and domain strings.

    You should call this member function after you modify the full name, local-part, route, or domain, and before you retrieve the string representation.

    This function clears the is-modified flag.

    virtual DwMessageComponent* Clone() const

    This virtual function, inherited from DwMessageComponent, creates a new DwMailbox on the free store that has the same value as this DwMailbox object. The basic idea is that of a virtual copy constructor.

    const DwString& FullName() const

    Returns the full name for this DwMailbox object.

    void SetFullName(const DwString& aFullName)

    Sets the full name for this DwMailbox object.

    const DwString& Route() const

    Returns the route for this DwMailbox object.

    void SetRoute(const DwString& aRoute)

    Sets the route for this DwMailbox object.

    const DwString& LocalPart() const

    Returns the local-part for this DwMailbox object.

    void SetLocalPart(const DwString& aLocalPart)

    Sets the local-part for this DwMailbox object.

    const DwString& Domain() const

    Returns the domain for this DwMailbox object.

    void SetDomain(const DwString& aDomain)

    Sets the domain for this DwMailbox object.

    static DwMailbox* NewMailbox(const DwString& aStr, DwMessageComponent* aParent)

    Creates a new DwMailbox object on the free store. If the static data member sNewMailbox is NULL, this member function will create a new DwMailbox and return it. Otherwise, NewMailbox() will call the user-supplied function pointed to by sNewMailbox, which is assumed to return an object from a class derived from DwMailbox, and return that object.

    virtual void PrintDebugInfo(ostream& aStrm, int aDepth=0) const

    This virtual function, inherited from DwMessageComponent, prints debugging information about this object to aStrm. It will also call PrintDebugInfo() for any of its child components down to a level of aDepth.

    This member function is available only in the debug version of the library.

    virtual void CheckInvariants() const

    Aborts if one of the invariants of the object fails. Use this member function to track down bugs.

    This member function is available only in the debug version of the library.

    Public Data Members

    static DwMailbox* (*sNewMailbox)(const DwString&, DwMessageComponent*)

    If sNewMailbox is not NULL, it is assumed to point to a user-supplied function that returns an object from a class derived from DwMailbox.

    mimelib1-1.1.4/mimelib/doc/uuencode.html0000644000175000017500000001017611175345261017506 0ustar resivoresivo DwUuencode Man Page

    NAME

    DwUuencode -- Class for performing uuencode or uudecode operations

    SYNOPSIS

    class DW_EXPORT DwUuencode {
    
    public:
    
        DwUuencode();
        virtual ~DwUuencode();
        void SetFileName(const char* aName);
        const char* FileName() const;
        void SetFileMode(DwUint16 aMode);
        DwUint16 FileMode() const;
        void SetBinaryChars(const DwString& aStr);
        const DwString& BinaryChars() const;
        void SetAsciiChars(const DwString& aStr);
        const DwString& AsciiChars() const;
        DwBool Encode();
        DwBool Decode();
    };
    

    DESCRIPTION

    DwUuencode performs uuencode or uudecode operations. Uuencode is a format for encoding binary data into text characters for transmission through the mail system. The format also includes the file name and the file mode. (Note: The file mode is significant only in UNIX.) In MIME, the use of uuencode is deprecated; base64 is the preferred encoding for sending binary data.

    To use DwUuencode for encoding binary data into uuencode format, set the file name, file mode, and binary data string using the member functions SetFileName(), SetFileMode(), and SetBinaryChars(). Then call the member function Encode(). Finally, retrieve the uuencoded text characters by calling AsciiChars().

    To use DwUuencode to decode uuencoded data, set the ASCII characters using the member function SetAsciiChars(), then call Decode(). Finally, retrieve the file name, file mode, and binary characters by calling FileName(), FileMode(), and BinaryChars().

    Public Member Functions

    void SetFileName(const char* aName)

    Sets the file name to be included in the uuencoded output.

    const char* FileName() const

    Returns the file name extracted while uudecoding.

    void SetFileMode(DwUint16 aMode)

    Sets the file mode to be included in the uuencoded output. If the file mode is not explicitly set using this member function, a default value of 0644 (octal) is assumed.

    DwUint16 FileMode() const

    Returns the file mode extracted while uudecoding.

    void SetBinaryChars(const DwString& aStr)

    Sets the string of binary data to be used in the uuencode operation.

    const DwString& BinaryChars() const

    Returns the string of binary data extracted during a uudecode operation.

    void SetAsciiChars(const DwString& aStr)

    Sets the string of ASCII characters to used in the decode operation.

    const DwString& AsciiChars() const

    Returns the string of ASCII characters created during a uuencode operation.

    DwBool Encode()

    Creates an ASCII string of characters by uuencoding the file name, file mode, and binary data.

    DwBool Decode()

    Extracts the file name, file mode, and binary data from the ASCII characters via a uudecode operation. mimelib1-1.1.4/mimelib/doc/field.html0000644000175000017500000003261311175345261016762 0ustar resivoresivo DwField Man Page

    NAME

    DwField -- Class representing a MIME header field

    SYNOPSIS

    class DW_EXPORT DwField : public DwMessageComponent {
    
        friend class DwHeaders;
    
    public:
    
        DwField();
        DwField(const DwField& aField);
        DwField(const DwString& aStr, DwMessageComponent* aParent=0);
        virtual ~DwField();
        const DwField& operator = (const DwField& aField);
        virtual void Parse();
        virtual void Assemble();
        virtual DwMessageComponent* Clone() const;
        DwFieldBody* FieldBody() const;
        const DwString& FieldNameStr() const;
        const DwString& FieldBodyStr() const;
        DwField* Next() const;
        void SetFieldBody(DwFieldBody* aFieldBody);
        void SetFieldNameStr(const DwString& aStr);
        void SetFieldBodyStr(const DwString& aStr);
        void SetNext(const DwField* aField);
        static DwField* NewField(const DwString& aStr,
            DwMessageComponent* aParent);
        static DwFieldBody* CreateFieldBody(const DwString& aFieldName,
            const DwString& aFieldBody, DwMessageComponent* aParent);
        static DwFieldBody* _CreateFieldBody(const DwString& aFieldName,
            const DwString& aFieldBody, DwMessageComponent* aParent);
        static DwField* (*sNewField)(const DwString&, DwMessageComponent*);
        static DwFieldBody* (*sCreateFieldBody)(const DwString& aFieldName,
            const DwString& aFieldBody, DwMessageComponent* aParent);
    
    protected:
    
        DwString mFieldNameStr;
        DwString mFieldBodyStr;
        DwFieldBody* mFieldBody;
        void _SetFieldBody(DwFieldBody* aFieldBody);
    
    public:
    
        virtual void PrintDebugInfo(ostream& aStrm, int aDepth=0) const;
        virtual void CheckInvariants() const;
    
    protected:
    
        void _PrintDebugInfo(ostream& aStrm) const;
    };
    

    DESCRIPTION

    DwField represents a header field as described in RFC-822. According to RFC-822, a field contains a field name and a field body. In MIME++, a DwField contains three elements: a DwString that contains its field name, a DwString that contains its field body, and a DwFieldBody object that contains a broken-down (that is, parsed) version of its field body.

    In the tree (broken-down) representation of message, a DwField object is always an intermediate node, having a parent node and a single child node. The parent node is the DwHeaders object that contains it. The child node is the DwFieldBody object it contains.

    To get and set the field name, use the member functions FieldNameStr() and SetFieldNameStr(). To get and set the field body, use the member functions FieldBodyStr() and SetFieldBodyStr(). To get and set the DwFieldBody object, use FieldBody() and SetFieldBody().

    A DwField object can be included in a list of DwField objects; usually this is the list of DwField objects maintained by its parent DwHeaders object. To get the next DwField object in a list, use the member function Next().

    Public Member Functions

    DwField()
    DwField(const DwField& aField)
    DwField(const DwString& aStr, DwMessageComponent* aParent=0)

    The first constructor is the default constructor, which sets the DwField object's field name and field body to the empty string, set its parent to NULL, and sets its DwFieldBody object to NULL.

    The second constructor is the copy constructor, which performs a deep copy of aField. The parent of the new DwField object is set to NULL.

    The third constructor copies aStr to the DwField object's string representation and sets aParent as its parent. The virtual member function Parse() should be called immediately after this constructor in order to parse the string representation. Unless it is NULL, aParent should point to an object of a class derived from DwHeaders.

    const DwField& operator = (const DwField& aField)

    This is the assignment operator, which performs a deep copy of aField. The parent node of the DwField object is not changed.

    virtual void Parse()

    This virtual function, inherited from DwMessageComponent, executes the parse method for DwField objects. The parse method creates or updates the broken-down representation from the string representation. For DwField objects, the parse method parses the string representation, sets the values of the field name string and the field body string, and creates an instance of the appropriate subclass of DwFieldBody. This member function also calls the Parse() member function of its contained DwFieldBody object.

    You should call this member function after you set or modify the string representation, and before you access the field name, the field body, or the contained DwFieldBody object.

    This function clears the is-modified flag.

    virtual void Assemble()

    This virtual function, inherited from DwMessageComponent, executes the assemble method for DwField objects. The assemble method creates or updates the string representation from the broken-down representation. In more concrete terms, the assemble method builds the string representation from the field name and the string representation of the contained DwFieldBody object. This member function calls the Assemble() member function of its contained DwFieldBody object.

    You should call this member function after you modify either the field name or the contained DwFieldBody object, and before you retrieve the string representation.

    This function clears the is-modified flag.

    virtual DwMessageComponent* Clone() const

    This virtual function, inherited from DwMessageComponent, creates a new DwField on the free store that has the same value as this DwField object. The basic idea is that of a virtual copy constructor.

    DwFieldBody* FieldBody() const

    Returns the DwFieldBody object contained by this DwField object. If there is no field body, NULL will be returned.

    const DwString& FieldNameStr() const

    Returns the field name of this header field as a string.

    const DwString& FieldBodyStr() const

    Returns the field body of this header field as a string.

    DwField* Next() const

    Returns the next DwField object following this DwField object in the list contained in a DwHeaders. Returns NULL if this object is last in the list.

    void SetFieldBody(DwFieldBody* aFieldBody)

    Sets the DwFieldBody object contained by this object.

    void SetFieldNameStr(const DwString& aStr)

    Sets the field name of this header field.

    void SetFieldBodyStr(const DwString& aStr)

    Sets the field body of this header field.

    void SetNext(const DwField* aField)

    This advanced function sets aField as the next field following this field in the list of fields contained in the headers. Since DwHeaders contains member functions for adding DwField objects to its list, this function should be avoided for most applications.

    static DwField* NewField(const DwString& aStr, DwMessageComponent* aParent)

    Creates a new DwField object on the free store. If the static data member sNewField is NULL, this member function will create a new DwField and return it. Otherwise, NewField() will call the user-supplied function pointed to by sNewField, which is assumed to return an object from a class derived from DwField, and return that object.

    static DwFieldBody* CreateFieldBody(const DwString& aFieldName, const DwString& aFieldBody, DwMessageComponent* aParent)

    The static member function CreateFieldBody() is called from the Parse() member function and is responsible for creating a DwFieldBody object for this particular field. A typical scenario might go as follows: This member function examines the field name for this field, finds that it contains "To", creates a DwAddressList object to contain the field body, calls the Parse() member function for the DwAddressList, and sets the DwAddressList object as this DwField object's DwFieldBody.

    If you want to override the behavior of CreateFieldBody(), you can do so by setting the public data member sCreateFieldBody to point to your own function. CreateFieldBody() first checks to see if sCreateFieldBody is NULL. If it is not, CreateFieldBody() will assume that it points to a user-supplied function and will call that function. If it is NULL, CreateFieldBody() will call _CreateFieldBody(), which actually creates the DwFieldBody object. You may call _CreateFieldBody() from your own function for fields you do not wish to handle.

    virtual void PrintDebugInfo(ostream& aStrm, int aDepth=0) const

    This virtual function, inherited from DwMessageComponent, prints debugging information about this object to aStrm. It will also call PrintDebugInfo() for any of its child components down to a level of aDepth.

    This member function is available only in the debug version of the library.

    virtual void CheckInvariants() const

    Aborts if one of the invariants of the object fails. Use this member function to track down bugs.

    This member function is available only in the debug version of the library.

    Public Data Members

    static DwField* (*sNewField)(const DwString&, DwMessageComponent*)

    If sNewField is not NULL, it is assumed to point to a user-supplied function that returns an object from a class derived from DwField.

    static DwFieldBody* (*sCreateFieldBody)(const DwString& aFieldName, const DwString& aFieldBody, DwMessageComponent* aParent)

    See CreateFieldBody().

    Protected Member Functions

    void _SetFieldBody(DwFieldBody* aFieldBody)

    Sets the DwFieldBody object contained by this object. This function differs from SetFieldBody() in that it does not set the is-modified flag.

    mimelib1-1.1.4/mimelib/doc/msgid.html0000644000175000017500000001762411175345261017007 0ustar resivoresivo DwMsgId Man Page

    NAME

    DwMsgId -- Class representing an RFC-822 msg-id

    SYNOPSIS

    class DW_EXPORT DwMsgId : public DwFieldBody {
    
    public:
    
        DwMsgId();
        DwMsgId(const DwMsgId& aMsgId);
        DwMsgId(const DwString& aStr, DwMessageComponent* aParent=0);
        virtual ~DwMsgId();
        const DwMsgId& operator = (const DwMsgId& aMsgId);
        virtual void Parse();
        virtual void Assemble();
        virtual DwMessageComponent* Clone() const;
        virtual void CreateDefault();
        const DwString& LocalPart() const;
        void SetLocalPart(const DwString& aLocalPart);
        const DwString& Domain() const;
        void SetDomain(const DwString& aDomain);
        static DwMsgId* NewMsgId(const DwString& aStr,
            DwMessageComponent* aParent);
        static DwMsgId* (*sNewMsgId)(const DwString&, DwMessageComponent*);
        static const char* sHostName;
    
    public:
    
        virtual void PrintDebugInfo(ostream& aStrm, int aDepth=0) const;
        virtual void CheckInvariants() const;
    
    protected:
    
        void _PrintDebugInfo(ostream& aStrm) const;
    };
    

    DESCRIPTION

    DwMsgId represents a msg-id as described in RFC-822. In the BNF grammar in RFC-822, a msg-id has a local-part and a domain. In MIME++, a DwMsgId contains strings that contain the local-part and the domain.

    In the tree (broken-down) representation of message, a DwMsgId object may only be a leaf node, having a parent but no child nodes. Its parent node must be a DwField object.

    DwMsgId has member functions for getting or setting its local-part and its domain. You can have the library to create the contents of a DwMsgId object for you by calling the member function CreateDefault().

    Public Member Functions

    DwMsgId()
    DwMsgId(const DwMsgId& aMsgId)
    DwMsgId(const DwString& aStr, DwMessageComponent* aParent=0)

    The first constructor is the default constructor, which sets the DwMsgId object's string representation to the empty string and sets its parent to NULL.

    The second constructor is the copy constructor, which performs a deep copy of aMsgId. The parent of the new DwMsgId object is set to NULL.

    The third constructor copies aStr to the DwMsgId object's string representation and sets aParent as its parent. The virtual member function Parse() should be called immediately after this constructor in order to parse the string representation. Unless it is NULL, aParent should point to an object of a class derived from DwField.

    const DwMsgId& operator = (const DwMsgId& aMsgId)

    This is the assignment operator, which performs a deep copy of aMsgId. The parent node of the DwMsgId object is not changed.

    virtual void Parse()

    This virtual function, inherited from DwMessageComponent, executes the parse method for DwMsgId objects. The parse method parses the local-part and the domain from the string representation.

    You should call this member function after you set or modify the string representation, and before you retrieve local-part or domain.

    This function clears the is-modified flag.

    virtual void Assemble()

    This virtual function, inherited from DwMessageComponent, executes the assemble method for DwMsgId objects. The assemble method creates or updates the string representation from the local-part and the domain.

    You should call this member function after you modify the local-part or the domain, and before you retrieve the string representation.

    This function clears the is-modified flag.

    virtual DwMessageComponent* Clone() const

    This virtual function, inherited from DwMessageComponent, creates a new DwMsgId on the free store that has the same value as this DwMsgId object. The basic idea is that of a ``virtual copy constructor.''

    virtual void CreateDefault()

    Creates a value for the msg-id. Uses the current time, process id, and fully qualified domain name for the host.

    const DwString& LocalPart() const

    Returns the local-part of the msg-id.

    void SetLocalPart(const DwString& aLocalPart)

    Sets the local-part of the msg-id.

    const DwString& Domain() const

    Returns the domain of the msg-id.

    void SetDomain(const DwString& aDomain)

    Sets the domain of the msg-id.

    static DwMsgId* NewMsgId(const DwString& aStr, DwMessageComponent* aParent)

    Creates a new DwMsgId object on the free store. If the static data member sNewMsgId is NULL, this member function will create a new DwMsgId and return it. Otherwise, NewMsgId() will call the user-supplied function pointed to by sNewMsgId, which is assumed to return an object from a class derived from DwMsgId, and return that object.

    virtual void PrintDebugInfo(ostream& aStrm, int aDepth=0) const

    This virtual function, inherited from DwMessageComponent, prints debugging information about this object to aStrm. It will also call PrintDebugInfo() for any of its child components down to a level of aDepth.

    This member function is available only in the debug version of the library.

    virtual void CheckInvariants() const

    Aborts if one of the invariants of the object fails. Use this member function to track down bugs.

    This member function is available only in the debug version of the library.

    Public Data Members

    static DwMsgId* (*sNewMsgId)(const DwString&, DwMessageComponent*)

    If sNewMsgId is not NULL, it is assumed to point to a user-supplied function that returns an object from a class derived from DwMsgId.

    static const char* sHostName

    Host name of machine, used to create msg-id string. This data member is ignored if the platform supports a gethostname() function call. mimelib1-1.1.4/mimelib/protocol.cpp0000644000175000017500000003216311175345261016611 0ustar resivoresivo//============================================================================= // File: proto_un.cpp // Contents: Definitions for DwClientProtocol // Maintainer: Doug Sauder // WWW: http://www.fwb.gulf.net/~dwsauder/mimepp.html // // Copyright (c) 1996, 1997 Douglas W. Sauder // All rights reserved. // // IN NO EVENT SHALL DOUGLAS W. SAUDER BE LIABLE TO ANY PARTY FOR DIRECT, // INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF // THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF DOUGLAS W. SAUDER // HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // DOUGLAS W. SAUDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT // NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A // PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" // BASIS, AND DOUGLAS W. SAUDER HAS NO OBLIGATION TO PROVIDE MAINTENANCE, // SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. // //============================================================================= // Comments: // // 1. The program should handle the SIGPIPE signal. Ignoring it should be okay. // // 2. The recv() and send() system calls are *not* restarted if they are // interrupted by a signal. This behavior is necessary if we want to // be able to timeout a blocked call. #define DW_IMPLEMENTATION #include #include #include #include #include #include #include #include #include #include #if defined(_AIX) #include #include #include #endif #ifdef DW_WIN32 #define ETIMEDOUT WSAETIMEDOUT #define ENOBUFS WSAENOBUFS #define EPROTONOSUPPORT WSAEPROTONOSUPPORT #define ENOTSOCK WSAENOTSOCK #define EMSGSIZE WSAEMSGSIZE #define EADDRNOTAVAIL WSAEADDRNOTAVAIL #endif #ifndef INADDR_NONE #define INADDR_NONE (-1) #endif #if defined(DW_DEBUG_PROTO) # define DBG_PROTO_STMT(x) x #else # define DBG_PROTO_STMT(x) #endif // WABA: This should be defined by netdb.h // deller: Needed for HP/UX #if defined(__hpux) extern int h_errno; #endif static int translate_h_errno(int herrno); static const char* get_error_text(int aErrorCode); DwProtocolClient::DwProtocolClient() { mIsDllOpen = DwTrue; mIsOpen = DwFalse; mSocket = -1; mPort = 0; mServerName = 0; mReceiveTimeout = 90; mLastCommand = 0; mFailureCode = kFailNoFailure; mFailureStr = ""; mErrorCode = kErrNoError; mErrorStr = get_error_text(kErrNoError); } DwProtocolClient::~DwProtocolClient() { if (mIsOpen) { Close(); } if (mServerName) { delete [] mServerName; mServerName = 0; } } int DwProtocolClient::Open(const char* aServer, DwUint16 aPort) { mFailureCode = kFailNoFailure; mFailureStr = ""; mErrorCode = kErrNoError; mErrorStr = get_error_text(mErrorCode); if (mIsOpen) { // error! mErrorCode = kErrBadUsage; mErrorStr = get_error_text(mErrorCode); return -1; } if (aServer == 0 || aServer[0] == 0) { // error! mErrorCode = kErrBadParameter; mErrorStr = get_error_text(mErrorCode); return -1; } if (mServerName) { delete [] mServerName; mServerName = 0; } mServerName = new char[strlen(aServer)+1]; strcpy(mServerName, aServer); mPort = aPort; // Open the socket mSocket = socket(PF_INET, SOCK_STREAM, 0); if (mSocket == -1) { // error! int err = errno; HandleError(err, ksocket); return -1; } // If the server is specified by an IP number in dotted decimal form, // then try to connect to that IP number. int err = -1; struct sockaddr_in serverAddr; memset(&serverAddr, 0, sizeof(struct sockaddr_in)); serverAddr.sin_family = AF_INET; serverAddr.sin_port = htons(mPort); serverAddr.sin_addr.s_addr = inet_addr(mServerName); if (serverAddr.sin_addr.s_addr != INADDR_NONE) { DBG_PROTO_STMT(cout << "Trying connection to " << mServerName << endl;) err = connect(mSocket, (struct sockaddr*)&serverAddr, sizeof(struct sockaddr_in)); } // Otherwise, do a host name lookup. else { struct hostent* hostentp = gethostbyname(mServerName); if (hostentp == NULL) { // error! int err = h_errno; close(mSocket); mSocket = -1; err = translate_h_errno(err); HandleError(err, kgethostbyname); return -1; } // Connect to the server. Try each IP number until one succeeds. char** addr_list = hostentp->h_addr_list; while (*addr_list) { struct in_addr* in_addrp = (struct in_addr*)*addr_list; memcpy(&serverAddr.sin_addr.s_addr, in_addrp, sizeof(struct in_addr)); DBG_PROTO_STMT(cout << "Trying connection to " << mServerName;) DBG_PROTO_STMT(cout << " (" << inet_ntoa(*in_addrp) << ')' << endl;) err = connect(mSocket, (struct sockaddr*)&serverAddr, sizeof(struct sockaddr_in)); if (err != -1) { break; } ++addr_list; } } if (err == -1) { // error! mErrorCode = errno; close(mSocket); mSocket = -1; HandleError(err, kconnect); return -1; } DBG_PROTO_STMT(cout << "Connection okay" << endl;) mIsOpen = DwTrue; return 0; } DwBool DwProtocolClient::IsOpen() const { return mIsOpen; } int DwProtocolClient::Close() { mFailureCode = kFailNoFailure; mFailureStr = ""; mErrorCode = kErrNoError; mErrorStr = get_error_text(mErrorCode); if (! mIsOpen) { // error! mErrorCode = kErrBadUsage; mErrorStr = get_error_text(mErrorCode); return -1; } int err = close(mSocket); if (err < 0) { // error! int err = errno; HandleError(err, kclose); return -1; } mIsOpen = DwFalse; return 0; } int DwProtocolClient::SetReceiveTimeout(int aSecs) { mReceiveTimeout = aSecs; return 0; } int DwProtocolClient::LastCommand() const { return mLastCommand; } int DwProtocolClient::LastFailure() const { return mFailureCode; } const char* DwProtocolClient::LastFailureStr() const { return mFailureStr; } int DwProtocolClient::LastError() const { return mErrorCode; } const char* DwProtocolClient::LastErrorStr() const { return mErrorStr; } int DwProtocolClient::PSend(const char* aBuf, int aBufLen) { mFailureCode = kFailNoFailure; mFailureStr = ""; mErrorCode = kErrNoError; mErrorStr = get_error_text(mErrorCode); if (! mIsOpen) { // error! mErrorCode = kErrBadUsage; mErrorStr = get_error_text(mErrorCode); return 0; } int ret; int numToSend = aBufLen; int numSent = 0; while (numToSend > 0) { ret = send(mSocket, &aBuf[numSent], numToSend, 0); if (ret == -1) { // error! int err = errno; HandleError(err, ksend); break; } else { numSent += ret; numToSend -= ret; } } return numSent; } int DwProtocolClient::PReceive(char* aBuf, int aBufSize) { mFailureCode = kFailNoFailure; mFailureStr = ""; mErrorCode = kErrNoError; mErrorStr = get_error_text(mErrorCode); if (! mIsOpen) { // error! mErrorCode = kErrBadUsage; mErrorStr = get_error_text(mErrorCode); return 0; } // Suspend until there's input to read fd_set readfds; FD_ZERO(&readfds); FD_SET(mSocket, &readfds); struct timeval timeout; timeout.tv_sec = mReceiveTimeout; timeout.tv_usec = 0; int numFds = select(mSocket+1, &readfds, 0, 0, &timeout); int numReceived = 0; // If an error occurred, deal with it if (numFds == -1) { int err = errno; HandleError(err, kselect); numReceived = 0; } // Read the input, if available else if (numFds == 1) { int ret = recv(mSocket, aBuf, aBufSize, 0); if (ret == -1) { // error! int err = errno; HandleError(err, krecv); numReceived = 0; } else /* if (ret != -1) */ { numReceived = ret; } } // Otherwise, there was a timeout else if (numFds == 0) { DBG_PROTO_STMT(cout << "Receive timed out" << endl;) int err = ETIMEDOUT; HandleError(err, kselect); numReceived = 0; } return numReceived; } void DwProtocolClient::HandleError(int aErrorCode, int aSystemCall) { mErrorCode = aErrorCode; mErrorStr = get_error_text(mErrorCode); switch (aSystemCall) { case ksocket: switch (mErrorCode) { case EMFILE: case ENFILE: case ENOBUFS: mFailureCode = kFailNoResources; mFailureStr = "Cannot get required system resources"; break; case EPROTONOSUPPORT: case EACCES: break; } break; case kgethostbyname: switch (mErrorCode) { case kErrHostNotFound: case kErrTryAgain: case kErrNoRecovery: case kErrNoData: mFailureCode = kFailHostNotFound; mFailureStr = "The server was not found"; break; default: break; } break; case ksetsockopt: break; case kconnect: switch (aErrorCode) { case ETIMEDOUT: mFailureCode = kFailTimedOut; mFailureStr = "The connection attempt to the server timed out"; break; case ECONNREFUSED: mFailureCode = kFailConnRefused; mFailureStr = "The connection was refused by the server"; break; case ENETUNREACH: mFailureCode = kFailNetUnreachable; mFailureStr = "The network is unreachable"; break; case EBADF: case ENOTSOCK: case EADDRNOTAVAIL: case EAFNOSUPPORT: case EISCONN: case EADDRINUSE: case EFAULT: case EINPROGRESS: case EALREADY: break; } break; case ksend: switch(aErrorCode) { case ENOBUFS: mFailureCode = kFailNoResources; mFailureStr = "Cannot get required system resources"; break; case EBADF: case ENOTSOCK: case EFAULT: case EMSGSIZE: case EWOULDBLOCK: case ECONNREFUSED: case EISCONN: case EACCES: break; } break; case krecv: switch(aErrorCode) { case EBADF: case ENOTSOCK: case EWOULDBLOCK: case EINTR: case EFAULT: break; } break; case kclose: switch (aErrorCode) { case EBADF: case EINTR: case ETIMEDOUT: break; } break; case kselect: switch (aErrorCode) { case ETIMEDOUT: mFailureCode = kFailTimedOut; mFailureStr = "Timed out while waiting for the server"; break; case EBADF: case EINTR: case EINVAL: break; } break; default: break; } } static int translate_h_errno(int herrno) { int err = 0; switch (herrno) { case HOST_NOT_FOUND: err = DwProtocolClient::kErrHostNotFound; break; case TRY_AGAIN: err = DwProtocolClient::kErrTryAgain; break; case NO_RECOVERY: err = DwProtocolClient::kErrNoRecovery; break; case NO_DATA: err = DwProtocolClient::kErrNoData; break; default: err = DwProtocolClient::kErrUnknownError; break; } return err; } static const char* get_error_text(int aErrorCode) { const char* msg = ""; switch (aErrorCode) { case DwProtocolClient::kErrNoError: msg = "No error"; break; case DwProtocolClient::kErrUnknownError: msg = "Unknown error"; break; case DwProtocolClient::kErrBadParameter: msg = "(MIME++) bad parameter passed to function"; break; case DwProtocolClient::kErrBadUsage: msg = "(MIME++) bad library usage"; break; case DwProtocolClient::kErrNoWinsock: msg = "(MIME++) incompatible Winsock version"; break; case DwProtocolClient::kErrHostNotFound: msg = "Host not found"; break; case DwProtocolClient::kErrTryAgain: msg = "Nonauthoritative host not found"; break; case DwProtocolClient::kErrNoRecovery: msg = "Nonrecoverable errors: FORMERR, REFUSED, NOTIMP"; break; case DwProtocolClient::kErrNoData: msg = "Valid name, no data record of requested type"; break; case DwProtocolClient::kErrNoAddress: msg = "No address, look for MX record"; break; default: msg = strerror(aErrorCode); break; } return msg; } mimelib1-1.1.4/mimelib/Makefile.am0000644000175000017500000000312411206750346016272 0ustar resivoresivo# UNIX makefile for MIME++ library and example programs # Choose a version to compile. I recommend compiling development version, # which includes numerous assert macros to catch bad function arguments # and other safeguards. The production version is designed to avoid # program aborts, such as will occur if an assertion fails. The production # version tries to recover as best it can in the case of exceptional # conditions. The debug version is designed to help you find bugs once # you know they exist. The development version helps you out here just # a little, because it will dump core so you can examine the program # state with a debugger. # # Make sure you type 'make clean' after compiling one version before # compiling a different version. SUBDIRS = mimelib tests LIBVERSION = DW_DEVELOPMENT_VERSION # LIBVERSION = DW_PRODUCTION_VERSION # LIBVERSION = DW_DEBUG_VERSION INCLUDES = $(all_includes) AM_CPPFLAGS = -D$(LIBVERSION) -D_REENTRANT lib_LTLIBRARIES = libmimelib.la libmimelib_la_SOURCES = \ protocol.cpp \ address.cpp \ addrlist.cpp \ body.cpp \ bodypart.cpp \ boyermor.cpp \ datetime.cpp \ disptype.cpp \ dw_cte.cpp \ dw_date.cpp \ dw_mime.cpp \ entity.cpp \ field.cpp \ fieldbdy.cpp \ group.cpp \ headers.cpp \ mailbox.cpp \ mboxlist.cpp \ mechansm.cpp \ mediatyp.cpp \ message.cpp \ msgcmp.cpp \ msgid.cpp \ nntp.cpp \ param.cpp \ pop.cpp \ dwstring.cpp \ text.cpp \ token.cpp \ uuencode.cpp \ binhex.cpp libmimelib_la_LDFLAGS = -version-info 1:1 -no-undefined mimelib1-1.1.4/mimelib/pop.cpp0000644000175000017500000003177111175345261015552 0ustar resivoresivo//============================================================================= // File: pop.cpp // Contents: Definitions for DwPopClient // Maintainer: Doug Sauder // WWW: http://www.fwb.gulf.net/~dwsauder/mimepp.html // // Copyright (c) 1996, 1997 Douglas W. Sauder // All rights reserved. // // IN NO EVENT SHALL DOUGLAS W. SAUDER BE LIABLE TO ANY PARTY FOR DIRECT, // INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF // THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF DOUGLAS W. SAUDER // HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // DOUGLAS W. SAUDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT // NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A // PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" // BASIS, AND DOUGLAS W. SAUDER HAS NO OBLIGATION TO PROVIDE MAINTENANCE, // SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. // //============================================================================= #define DW_IMPLEMENTATION #include #include #include #include #include #define POP_PORT 110 #define RECV_BUFFER_SIZE 8192 #define SEND_BUFFER_SIZE 1024 #if defined(DW_DEBUG_POP) # define DBG_POP_STMT(x) x #else # define DBG_POP_STMT(x) #endif DwPopClient::DwPopClient() { mSendBuffer = new char[SEND_BUFFER_SIZE]; mRecvBuffer = new char[RECV_BUFFER_SIZE]; mNumRecvBufferChars = 0; mRecvBufferPos = 0; mStatusCode = 0; mObserver = 0; } DwPopClient::~DwPopClient() { if (mRecvBuffer) { delete [] mRecvBuffer; mRecvBuffer = 0; } if (mSendBuffer) { delete [] mSendBuffer; mSendBuffer = 0; } } int DwPopClient::Open(const char* aServer, DwUint16 aPort) { mStatusCode = 0; mSingleLineResponse = mMultiLineResponse = ""; int err = DwProtocolClient::Open(aServer, aPort); if (! err) { PGetSingleLineResponse(); } return mStatusCode; } DwObserver* DwPopClient::SetObserver(DwObserver* aObserver) { DwObserver* obs = mObserver; mObserver = aObserver; return obs; } int DwPopClient::StatusCode() const { return mStatusCode; } const DwString& DwPopClient::SingleLineResponse() const { return mSingleLineResponse; } const DwString& DwPopClient::MultiLineResponse() const { return mMultiLineResponse; } int DwPopClient::User(const char* aName) { mStatusCode = 0; mSingleLineResponse = mMultiLineResponse = ""; mLastCommand = kCmdUser; strcpy(mSendBuffer, "USER "); strncat(mSendBuffer, aName, SEND_BUFFER_SIZE-32); strcat(mSendBuffer, "\r\n"); DBG_POP_STMT(cout << "C: " << mSendBuffer << flush;) int bufferLen = strlen(mSendBuffer); int numSent = PSend(mSendBuffer, bufferLen); if (numSent == bufferLen) { PGetSingleLineResponse(); } return mStatusCode; } int DwPopClient::Pass(const char* aPasswd) { mStatusCode = 0; mSingleLineResponse = mMultiLineResponse = ""; mLastCommand = kCmdPass; strcpy(mSendBuffer, "PASS "); strncat(mSendBuffer, aPasswd, SEND_BUFFER_SIZE-32); strcat(mSendBuffer, "\r\n"); DBG_POP_STMT(cout << "C: " << mSendBuffer << flush;) int bufferLen = strlen(mSendBuffer); int numSent = PSend(mSendBuffer, bufferLen); if (numSent == bufferLen) { PGetSingleLineResponse(); } return mStatusCode; } int DwPopClient::Quit() { mStatusCode = 0; mSingleLineResponse = mMultiLineResponse = ""; mLastCommand = kCmdQuit; strcpy(mSendBuffer, "QUIT\r\n"); DBG_POP_STMT(cout << "C: " << mSendBuffer << flush;) int bufferLen = strlen(mSendBuffer); int numSent = PSend(mSendBuffer, bufferLen); if (numSent == bufferLen) { PGetSingleLineResponse(); } return mStatusCode; } int DwPopClient::Stat() { mStatusCode = 0; mSingleLineResponse = mMultiLineResponse = ""; mLastCommand = kCmdStat; strcpy(mSendBuffer, "STAT\r\n"); DBG_POP_STMT(cout << "C: " << mSendBuffer << flush;) int bufferLen = strlen(mSendBuffer); int numSent = PSend(mSendBuffer, bufferLen); if (numSent == bufferLen) { PGetSingleLineResponse(); } return mStatusCode; } int DwPopClient::List() { mStatusCode = 0; mSingleLineResponse = mMultiLineResponse = ""; mLastCommand = kCmdList; strcpy(mSendBuffer, "LIST\r\n"); DBG_POP_STMT(cout << "C: " << mSendBuffer << flush;) int bufferLen = strlen(mSendBuffer); int numSent = PSend(mSendBuffer, bufferLen); if (numSent == bufferLen) { PGetSingleLineResponse(); if (mStatusCode == '+') { PGetMultiLineResponse(); } } return mStatusCode; } int DwPopClient::List(int aMsg) { mStatusCode = 0; mSingleLineResponse = mMultiLineResponse = ""; mLastCommand = kCmdList; snprintf(mSendBuffer, SEND_BUFFER_SIZE, "LIST %d\r\n", aMsg); DBG_POP_STMT(cout << "C: " << mSendBuffer << flush;) int bufferLen = strlen(mSendBuffer); int numSent = PSend(mSendBuffer, bufferLen); if (numSent == bufferLen) { PGetSingleLineResponse(); } return mStatusCode; } int DwPopClient::Retr(int aMsg) { mStatusCode = 0; mSingleLineResponse = mMultiLineResponse = ""; mLastCommand = kCmdRetr; snprintf(mSendBuffer, SEND_BUFFER_SIZE, "RETR %d\r\n", aMsg); DBG_POP_STMT(cout << "C: " << mSendBuffer << flush;) int bufferLen = strlen(mSendBuffer); int numSent = PSend(mSendBuffer, bufferLen); if (numSent == bufferLen) { PGetSingleLineResponse(); if (mStatusCode == '+') { PGetMultiLineResponse(); } } return mStatusCode; } int DwPopClient::Dele(int aMsg) { mStatusCode = 0; mSingleLineResponse = mMultiLineResponse = ""; mLastCommand = kCmdDele; snprintf(mSendBuffer, SEND_BUFFER_SIZE, "DELE %d\r\n", aMsg); DBG_POP_STMT(cout << "C: " << mSendBuffer << flush;) int bufferLen = strlen(mSendBuffer); int numSent = PSend(mSendBuffer, bufferLen); if (numSent == bufferLen) { PGetSingleLineResponse(); } return mStatusCode; } int DwPopClient::Noop() { mStatusCode = 0; mSingleLineResponse = mMultiLineResponse = ""; mLastCommand = kCmdNoop; strcpy(mSendBuffer, "NOOP\r\n"); DBG_POP_STMT(cout << "C: " << mSendBuffer << flush;) int bufferLen = strlen(mSendBuffer); int numSent = PSend(mSendBuffer, bufferLen); if (numSent == bufferLen) { PGetSingleLineResponse(); } return mStatusCode; } int DwPopClient::Rset() { mStatusCode = 0; mSingleLineResponse = mMultiLineResponse = ""; mLastCommand = kCmdRset; strcpy(mSendBuffer, "RSET\r\n"); DBG_POP_STMT(cout << "C: " << mSendBuffer << flush;) int bufferLen = strlen(mSendBuffer); int numSent = PSend(mSendBuffer, bufferLen); if (numSent == bufferLen) { PGetSingleLineResponse(); } return mStatusCode; } int DwPopClient::Last() { mStatusCode = 0; mSingleLineResponse = mMultiLineResponse = ""; mLastCommand = kCmdRset; strcpy(mSendBuffer, "LAST\r\n"); DBG_POP_STMT(cout << "C: " << mSendBuffer << flush;) int bufferLen = strlen(mSendBuffer); int numSent = PSend(mSendBuffer, bufferLen); if (numSent == bufferLen) { PGetSingleLineResponse(); } return mStatusCode; } int DwPopClient::Apop(const char* aName, const char* aDigest) { mStatusCode = 0; mSingleLineResponse = mMultiLineResponse = ""; mLastCommand = kCmdApop; strcpy(mSendBuffer, "APOP "); strncat(mSendBuffer, aName, 256); strcat(mSendBuffer, " "); strncat(mSendBuffer, aDigest, 256); strcat(mSendBuffer, "\r\n"); DBG_POP_STMT(cout << "C: " << mSendBuffer << flush;) int bufferLen = strlen(mSendBuffer); int numSent = PSend(mSendBuffer, bufferLen); if (numSent == bufferLen) { PGetSingleLineResponse(); } return mStatusCode; } int DwPopClient::Top(int aMsg, int aNumLines) { mStatusCode = 0; mSingleLineResponse = mMultiLineResponse = ""; mLastCommand = kCmdTop; snprintf(mSendBuffer, SEND_BUFFER_SIZE, "TOP %d %d\r\n", aMsg, aNumLines); DBG_POP_STMT(cout << "C: " << mSendBuffer << flush;) int bufferLen = strlen(mSendBuffer); int numSent = PSend(mSendBuffer, bufferLen); if (numSent == bufferLen) { PGetSingleLineResponse(); if (mStatusCode == '+') { PGetMultiLineResponse(); } } return mStatusCode; } int DwPopClient::Uidl() { mStatusCode = 0; mSingleLineResponse = mMultiLineResponse = ""; mLastCommand = kCmdUidl; strcpy(mSendBuffer, "UIDL\r\n"); DBG_POP_STMT(cout << "C: " << mSendBuffer << flush;) int bufferLen = strlen(mSendBuffer); int numSent = PSend(mSendBuffer, bufferLen); if (numSent == bufferLen) { PGetSingleLineResponse(); if (mStatusCode == '+') { PGetMultiLineResponse(); } } return mStatusCode; } int DwPopClient::Uidl(int aMsg) { mStatusCode = 0; mSingleLineResponse = mMultiLineResponse = ""; mLastCommand = kCmdUidl; snprintf(mSendBuffer, SEND_BUFFER_SIZE, "UIDL %d\r\n", aMsg); DBG_POP_STMT(cout << "C: " << mSendBuffer << flush); int bufferLen = strlen(mSendBuffer); int numSent = PSend(mSendBuffer, bufferLen); if (numSent == bufferLen) { PGetSingleLineResponse(); if (mStatusCode == '+') { PGetMultiLineResponse(); } } return mStatusCode; } void DwPopClient::PGetSingleLineResponse() { mStatusCode = 0; mSingleLineResponse = ""; char* ptr; int len; int err = PGetLine(&ptr, &len); if (! err) { mStatusCode = ptr[0]; mSingleLineResponse.assign(ptr, len); DBG_POP_STMT(char buffer[256];) DBG_POP_STMT(strncpy(buffer, ptr, len);) DBG_POP_STMT(buffer[len] = 0;) DBG_POP_STMT(cout << "S: " << buffer;) } } void DwPopClient::PGetMultiLineResponse() { mMultiLineResponse = ""; // Get a line at a time until we get CR LF . CR LF while (1) { char* ptr; int len; int err = PGetLine(&ptr, &len); // Check for an error if (err) { mStatusCode = 0; return; } // Check for '.' on a line by itself, which indicates end of multiline // response if (len >= 3 && ptr[0] == '.' && ptr[1] == '\r' && ptr[2] == '\n') { break; } // Remove '.' at beginning of line if (*ptr == '.') ++ptr; // If an observer is assigned, notify it. // Implementation note: An observer is assumed to fetch the multiline // response one line at a time, therefore we assign to the string, // rather than append to it. if (mObserver) { mMultiLineResponse.assign(ptr, len); mObserver->Notify(); } else { mMultiLineResponse.append(ptr, len); } } } int DwPopClient::PGetLine(char** aPtr, int* aLen) { // Restore the saved state int startPos = mRecvBufferPos; int pos = mRecvBufferPos; int lastChar = -1; // Keep trying until we get a complete line, detect an error, or // determine that the connection has been closed int isEndOfLineFound = 0; while (1) { // Search buffer for end of line chars. Stop when we find them or when // we exhaust the buffer. while (pos < mNumRecvBufferChars) { if (lastChar == '\r' && mRecvBuffer[pos] == '\n') { isEndOfLineFound = 1; ++pos; break; } lastChar = mRecvBuffer[pos]; ++pos; } if (isEndOfLineFound) { *aPtr = &mRecvBuffer[startPos]; *aLen = pos - startPos; mRecvBufferPos = pos; return 0; } // If the buffer has no room, return without an error; otherwise, // replenish the buffer. // Implementation note: The standard does not allow long lines, // however, that does not mean that they won't occur. The way // this function deals with long lines is to return a full buffer's // worth of characters as a line. The next call to this function // will start where this call left off. In essence, we have // *forced* a line break, but without putting in CR LF characters. if (startPos == 0 && pos == RECV_BUFFER_SIZE) { *aPtr = mRecvBuffer; *aLen = RECV_BUFFER_SIZE; mRecvBufferPos = pos; return 0; } memmove(mRecvBuffer, &mRecvBuffer[startPos], mNumRecvBufferChars-startPos); mNumRecvBufferChars -= startPos; mRecvBufferPos = mNumRecvBufferChars; int bufFreeSpace = RECV_BUFFER_SIZE - mRecvBufferPos; int n = PReceive(&mRecvBuffer[mRecvBufferPos], bufFreeSpace); if (n == 0) { // The connection has been closed or an error occurred return -1; } mNumRecvBufferChars += n; startPos = 0; pos = mRecvBufferPos; } } mimelib1-1.1.4/mimelib/mailbox.cpp0000644000175000017500000002647511175345261016414 0ustar resivoresivo//============================================================================= // File: mailbox.cpp // Contents: Definitions for DwMailbox // Maintainer: Doug Sauder // WWW: http://www.fwb.gulf.net/~dwsauder/mimepp.html // // Copyright (c) 1996, 1997 Douglas W. Sauder // All rights reserved. // // IN NO EVENT SHALL DOUGLAS W. SAUDER BE LIABLE TO ANY PARTY FOR DIRECT, // INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF // THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF DOUGLAS W. SAUDER // HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // DOUGLAS W. SAUDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT // NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A // PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" // BASIS, AND DOUGLAS W. SAUDER HAS NO OBLIGATION TO PROVIDE MAINTENANCE, // SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. // //============================================================================= #define DW_IMPLEMENTATION #include #include #include #include #include #include #include #include #include void RemoveCrAndLf(DwString& aStr); const char* const DwMailbox::sClassName = "DwMailbox"; DwMailbox* (*DwMailbox::sNewMailbox)(const DwString&, DwMessageComponent*) = 0; DwMailbox* DwMailbox::NewMailbox(const DwString& aStr, DwMessageComponent* aParent) { if (sNewMailbox) { return sNewMailbox(aStr, aParent); } else { return new DwMailbox(aStr, aParent); } } DwMailbox::DwMailbox() { mClassId = kCidMailbox; mClassName = sClassName; } DwMailbox::DwMailbox(const DwMailbox& aMailbox) : DwAddress(aMailbox), mFullName(aMailbox.mFullName), mRoute(aMailbox.mRoute), mLocalPart(aMailbox.mLocalPart), mDomain(aMailbox.mDomain) { mClassId = kCidMailbox; mClassName = sClassName; } DwMailbox::DwMailbox(const DwString& aStr, DwMessageComponent* aParent) : DwAddress(aStr, aParent) { mClassId = kCidMailbox; mClassName = sClassName; } DwMailbox::~DwMailbox() { } const DwMailbox& DwMailbox::operator = (const DwMailbox& aMailbox) { if (this == &aMailbox) return *this; DwAddress::operator = (aMailbox); mFullName = aMailbox.mFullName; mRoute = aMailbox.mRoute; mLocalPart = aMailbox.mLocalPart; mDomain = aMailbox.mDomain; return *this; } const DwString& DwMailbox::FullName() const { return mFullName; } void DwMailbox::SetFullName(const DwString& aFullName) { mFullName = aFullName; SetModified(); } const DwString& DwMailbox::Route() const { return mRoute; } void DwMailbox::SetRoute(const DwString& aRoute) { mRoute = aRoute; SetModified(); } const DwString& DwMailbox::LocalPart() const { return mLocalPart; } void DwMailbox::SetLocalPart(const DwString& aLocalPart) { mLocalPart = aLocalPart; SetModified(); } const DwString& DwMailbox::Domain() const { return mDomain; } void DwMailbox::SetDomain(const DwString& aDomain) { mDomain = aDomain; SetModified(); } // Some mailboxes to test // // John Doe // John@acme.com (John Doe) // John.Doe@acme.com (John Doe) // John.Doe (Jr) @acme.com (John Doe) // John <@domain1.com,@domain2.com:jdoe@acme.com> // // <@node1.[128.129.130.131],@node2.uu.edu: // jdoe(John Doe)@node3.[131.130.129.128]> (John Doe) // void DwMailbox::Parse() { mIsModified = 0; DwString emptyString(""); DwString space(" "); int isFirstPhraseNull = 1; int isSimpleAddress = 1; DwString firstPhrase(emptyString); DwString lastComment(emptyString); mRoute = emptyString; mLocalPart = emptyString; mDomain = emptyString; mFullName = emptyString; DwRfc822Tokenizer tokenizer(mString); int ch; enum { eStart, // start eLtSeen, // less-than-seen eInRoute, // in-route eInAddrSpec, // in-addr-spec eAtSeen, // at-seen eGtSeen // greater-than-seen }; // Start state -- terminated by '<' or '@' int type = tokenizer.Type(); int state = eStart; while (state == eStart && type != eTkNull) { switch (type) { case eTkSpecial: ch = tokenizer.Token()[0]; switch (ch) { case '@': state = eAtSeen; break; case '<': isSimpleAddress = 0; mLocalPart = emptyString; state = eLtSeen; break; case '.': mLocalPart += tokenizer.Token(); break; } break; case eTkAtom: case eTkQuotedString: if (isFirstPhraseNull) { firstPhrase = tokenizer.Token(); isFirstPhraseNull = 0; } else { firstPhrase += space; firstPhrase += tokenizer.Token(); } mLocalPart += tokenizer.Token(); break; case eTkComment: tokenizer.StripDelimiters(); lastComment = tokenizer.Token(); break; } ++tokenizer; type = tokenizer.Type(); } // Less-than-seen state -- process only one valid token and transit to // in-route state or in-addr-spec state while (state == eLtSeen && type != eTkNull) { switch (type) { case eTkSpecial: ch = tokenizer.Token()[0]; switch (ch) { case '@': // '@' immediately following '<' indicates a route mRoute = tokenizer.Token(); state = eInRoute; break; } break; case eTkAtom: case eTkQuotedString: mLocalPart = tokenizer.Token(); state = eInAddrSpec; break; } ++tokenizer; type = tokenizer.Type(); } // In-route state -- terminated by ':' while (state == eInRoute && type != eTkNull) { switch (type) { case eTkSpecial: ch = tokenizer.Token()[0]; switch (ch) { case ':': state = eInAddrSpec; break; case '@': case ',': case '.': mRoute += tokenizer.Token(); break; } break; case eTkAtom: mRoute += tokenizer.Token(); break; case eTkDomainLiteral: mRoute += tokenizer.Token(); break; } ++tokenizer; type = tokenizer.Type(); } // in-addr-spec state -- terminated by '@' while (state == eInAddrSpec && type != eTkNull) { switch (type) { case eTkSpecial: ch = tokenizer.Token()[0]; switch (ch) { case '@': state = eAtSeen; break; case '.': mLocalPart += tokenizer.Token(); break; } break; case eTkAtom: case eTkQuotedString: mLocalPart += tokenizer.Token(); break; } ++tokenizer; type = tokenizer.Type(); } // at-seen state -- terminated by '>' or end of string while (state == eAtSeen && type != eTkNull) { switch (type) { case eTkSpecial: ch = tokenizer.Token()[0]; switch (ch) { case '>': state = eGtSeen; break; case '.': mDomain += tokenizer.Token(); break; } break; case eTkAtom: mDomain += tokenizer.Token(); break; case eTkDomainLiteral: mDomain += tokenizer.Token(); break; case eTkComment: tokenizer.StripDelimiters(); lastComment = tokenizer.Token(); break; } ++tokenizer; type = tokenizer.Type(); } // greater-than-seen state -- terminated by end of string while (state == eGtSeen && type != eTkNull) { switch (type) { case eTkComment: tokenizer.StripDelimiters(); lastComment = tokenizer.Token(); break; } ++tokenizer; type = tokenizer.Type(); } // Get full name, if possible if (isSimpleAddress) { mFullName = lastComment; } else if (firstPhrase != emptyString) { mFullName = firstPhrase; } else if (lastComment != emptyString) { mFullName = lastComment; } // Check validity if (mLocalPart.length() > 0) { mIsValid = 1; } else { mIsValid = 0; } // Remove CR or LF from local-part or full name RemoveCrAndLf(mFullName); RemoveCrAndLf(mLocalPart); } void DwMailbox::Assemble() { if (!mIsModified) return; mIsValid = 1; if (mLocalPart.length() == 0 || mDomain.length() == 0) { mIsValid = 0; mString = ""; return; } mString = ""; if (mFullName.length() > 0) { mString += mFullName; mString += " "; } mString += "<"; if (mRoute.length() > 0) { mString += mRoute; mString += ":"; } mString += mLocalPart; mString += "@"; mString += mDomain; mString += ">"; mIsModified = 0; } DwMessageComponent* DwMailbox::Clone() const { return new DwMailbox(*this); } #if defined(DW_DEBUG_VERSION) void DwMailbox::PrintDebugInfo(std::ostream& aStrm, int /*aDepth*/) const { aStrm << "---------------- Debug info for DwMailbox class ----------------\n"; _PrintDebugInfo(aStrm); } #else void DwMailbox::PrintDebugInfo(std::ostream& , int) const {} #endif // defined(DW_DEBUG_VERSION) #if defined(DW_DEBUG_VERSION) void DwMailbox::_PrintDebugInfo(std::ostream& aStrm) const { DwAddress::_PrintDebugInfo(aStrm); aStrm << "Full Name: " << mFullName << '\n'; aStrm << "Route: " << mRoute << '\n'; aStrm << "Local Part: " << mLocalPart << '\n'; aStrm << "Domain: " << mDomain << '\n'; } #else void DwMailbox::_PrintDebugInfo(std::ostream& ) const {} #endif // defined(DW_DEBUG_VERSION) void DwMailbox::CheckInvariants() const { #if defined(DW_DEBUG_VERSION) DwAddress::CheckInvariants(); mFullName.CheckInvariants(); mRoute.CheckInvariants(); mLocalPart.CheckInvariants(); mDomain.CheckInvariants(); #endif // defined(DW_DEBUG_VERSION) } void RemoveCrAndLf(DwString& aStr) { // Do a quick check to see if at least one CR or LF is present size_t n = aStr.find_first_of("\r\n"); if (n == DwString::npos) return; // At least one CR or LF is present, so copy the string const DwString& in = aStr; size_t inLen = in.length(); DwString out; out.reserve(inLen); int lastChar = 0; size_t i = 0; while (i < inLen) { int ch = in[i]; if (ch == (int) '\r') { out += ' '; } else if (ch == (int) '\n') { if (lastChar != (int) '\r') { out += ' '; } } else { out += (char) ch; } lastChar = ch; ++i; } aStr = out; } mimelib1-1.1.4/mimelib/text.cpp0000644000175000017500000000562411175345261015736 0ustar resivoresivo//============================================================================= // File: text.cpp // Contents: Definitions for DwText // Maintainer: Doug Sauder // WWW: http://www.fwb.gulf.net/~dwsauder/mimepp.html // // Copyright (c) 1996, 1997 Douglas W. Sauder // All rights reserved. // // IN NO EVENT SHALL DOUGLAS W. SAUDER BE LIABLE TO ANY PARTY FOR DIRECT, // INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF // THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF DOUGLAS W. SAUDER // HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // DOUGLAS W. SAUDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT // NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A // PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" // BASIS, AND DOUGLAS W. SAUDER HAS NO OBLIGATION TO PROVIDE MAINTENANCE, // SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. // //============================================================================= #define DW_IMPLEMENTATION #include #include #include #include const char* const DwText::sClassName = "DwText"; DwText* (*DwText::sNewText)(const DwString&, DwMessageComponent*) = 0; DwText* DwText::NewText(const DwString& aStr, DwMessageComponent* aParent) { DwText* text; if (sNewText) { text = sNewText(aStr, aParent); } else { text = new DwText(aStr, aParent); } return text; } DwText::DwText() { mClassId = kCidText; mClassName = sClassName; } DwText::DwText(const DwText& aText) : DwFieldBody(aText) { mClassId = kCidText; mClassName = sClassName; } DwText::DwText(const DwString& aStr, DwMessageComponent* aParent) : DwFieldBody(aStr, aParent) { mClassId = kCidText; mClassName = sClassName; } DwText::~DwText() { } const DwText& DwText::operator = (const DwText& aText) { if (this == &aText) return *this; DwFieldBody::operator = (aText); return *this; } void DwText::Parse() { mIsModified = 0; } void DwText::Assemble() { mIsModified = 0; } DwMessageComponent* DwText::Clone() const { return new DwText(*this); } #if defined (DW_DEBUG_VERSION) void DwText::PrintDebugInfo(std::ostream& aStrm, int /*aDepth*/) const { aStrm << "------------------ Debug info for DwText class -----------------\n"; _PrintDebugInfo(aStrm); } #else void DwText::PrintDebugInfo(std::ostream& , int ) const {} #endif // defined (DW_DEBUG_VERSION) #if defined (DW_DEBUG_VERSION) void DwText::_PrintDebugInfo(std::ostream& aStrm) const { DwFieldBody::_PrintDebugInfo(aStrm); } #else void DwText::_PrintDebugInfo(std::ostream& ) const {} #endif // defined (DW_DEBUG_VERSION) void DwText::CheckInvariants() const { #if defined (DW_DEBUG_VERSION) DwFieldBody::CheckInvariants(); #endif // defined (DW_DEBUG_VERSION) } mimelib1-1.1.4/mimelib/token.cpp0000644000175000017500000003435411175345261016074 0ustar resivoresivo//============================================================================= // File: token.cpp // Contents: Definitions for DwTokenizer, DwRfc822Tokenizer // Maintainer: Doug Sauder // WWW: http://www.fwb.gulf.net/~dwsauder/mimepp.html // // Copyright (c) 1996, 1997 Douglas W. Sauder // All rights reserved. // // IN NO EVENT SHALL DOUGLAS W. SAUDER BE LIABLE TO ANY PARTY FOR DIRECT, // INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF // THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF DOUGLAS W. SAUDER // HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // DOUGLAS W. SAUDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT // NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A // PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" // BASIS, AND DOUGLAS W. SAUDER HAS NO OBLIGATION TO PROVIDE MAINTENANCE, // SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. // //============================================================================= #define DW_IMPLEMENTATION #include #include #include #include #include #include std::ostream* DwTokenizer::mDebugOut = 0; DwTokenizer::DwTokenizer(const DwString& aStr) : mString(aStr) { mTokenStart = 0; mTokenLength = 0; mNextStart = 0; mTkType = eTkError; } DwTokenizer::DwTokenizer(const char* aCStr) : mString(aCStr) { mTokenStart = 0; mTokenLength = 0; mNextStart = 0; mTkType = eTkError; } DwTokenizer::~DwTokenizer() { } void DwTokenizer::StripDelimiters() { if (mTokenLength < 2) return; // const ref -- avoids copy on write when using operator[] const DwString& token = mToken; switch (mTkType) { case eTkQuotedString: if (token[0] == '"') { mToken = mToken.substr(1); ++mTokenStart; --mTokenLength; } if (mTokenLength > 0 && token[mTokenLength-1] == '"') { mToken = mToken.substr(0, mTokenLength-1); --mTokenLength; } break; case eTkDomainLiteral: if (token[0] == '[') { mToken = mToken.substr(1); ++mTokenStart; --mTokenLength; } if (mTokenLength > 0 && token[mTokenLength-1] == ']') { mToken = mToken.substr(0, mTokenLength-1); --mTokenLength; } break; case eTkComment: if (token[0] == '(') { mToken = mToken.substr(1); ++mTokenStart; --mTokenLength; } if (mTokenLength > 0 && token[mTokenLength-1] == ')') { mToken = mToken.substr(0, mTokenLength-1); --mTokenLength; } break; } } void DwTokenizer::ParseQuotedString() { size_t pos = mTokenStart; while (1) { ++pos; if (pos >= mString.length()) { // Ran out of string mTokenLength = 0; mToken = ""; mNextStart = pos; mTkType = eTkError; break; } else if (mString[pos] == '\\') { // Quoted character ++pos; if (pos >= mString.length()) { // Ran out of string mTokenLength = 0; mToken = ""; mNextStart = pos; mTkType = eTkError; break; } } else if (mString[pos] == '"') { // End of quoted string ++pos; mTokenLength = pos - mTokenStart; mToken = mString.substr(mTokenStart, mTokenLength); mNextStart = pos; break; } } } void DwTokenizer::ParseComment() { size_t pos = mTokenStart; int level = 1; while (1) { ++pos; if (pos >= mString.length()) { // Ran out of string mTokenLength = 0; mToken = ""; mNextStart = pos; mTkType = eTkError; break; } else if (mString[pos] == '\\') { // Quoted character ++pos; if (pos >= mString.length()) { // Ran out of string mTokenLength = 0; mToken = ""; mNextStart = pos; mTkType = eTkError; break; } } else if (mString[pos] == ')') { --level; if (level == 0) { // End of comment ++pos; mTokenLength = pos - mTokenStart; mToken = mString.substr(mTokenStart, mTokenLength); mNextStart = pos; break; } } else if (mString[pos] == '(') { ++level; } } } void DwTokenizer::ParseDomainLiteral() { size_t pos = mTokenStart; while (1) { ++pos; if (pos >= mString.length()) { // Ran out of string mTokenLength = 0; mToken = ""; mNextStart = pos; mTkType = eTkError; break; } else if (mString[pos] == '\\') { // Quoted character ++pos; if (pos >= mString.length()) { // Ran out of string mTokenLength = 0; mToken = ""; mNextStart = pos; mTkType = eTkError; break; } } else if (mString[pos] == ']') { // End of domain literal ++pos; mTokenLength = pos - mTokenStart; mToken = mString.substr(mTokenStart, mTokenLength); mNextStart = pos; break; } } } void DwTokenizer::PrintToken(std::ostream* aOut) { if (!aOut) return; const char* type = 0; switch (mTkType) { case eTkError: type = "error "; break; case eTkNull: type = "null "; break; case eTkSpecial: type = "special "; break; case eTkAtom: type = "atom "; break; case eTkComment: type = "comment "; break; case eTkQuotedString: type = "quoted string "; break; case eTkDomainLiteral: type = "domain literal "; break; case eTkTspecial: type = "tspecial "; break; case eTkToken: type = "token "; break; default: type = "unknown "; break; } *aOut << type << mToken << '\n'; } static inline bool isspecialorspaceorcntrl( int c ) { switch ( c ) { case '(': case ')': case '<': case '>': case '@': case ',': case ';': case ':': case '\\': case '"': case '.': case '[': case ']': // isspace() case ' ': return true; //case '\r': included in iscntrl() //case '\f': included in iscntrl() //case '\t': included in iscntrl() //case '\n': included in iscntrl() //case '\v': included in iscntrl() // iscntrl() default: return ( (c >= 0 && c <= 15) || (c >= 17 && c <= 31) ); } } static inline bool isnotspaceorcntrl( int c ) { switch ( c ) { // isspace() case ' ': //case '\r': included in iscntrl() //case '\f': included in iscntrl() //case '\t': included in iscntrl() //case '\n': included in iscntrl() //case '\v': included in iscntrl() // iscntrl() return false; default: return !( (c >= 0 && c <= 15) || (c >= 17 && c <= 31) ); } } DwRfc822Tokenizer::DwRfc822Tokenizer(const DwString& aStr) : DwTokenizer(aStr) { ParseToken(); } DwRfc822Tokenizer::DwRfc822Tokenizer(const char* aCStr) : DwTokenizer(aCStr) { ParseToken(); } DwRfc822Tokenizer::~DwRfc822Tokenizer() { } int DwRfc822Tokenizer::Restart() { mNextStart = 0; ParseToken(); return mTkType; } int DwRfc822Tokenizer::operator ++ () { ParseToken(); return mTkType; } void DwRfc822Tokenizer::ParseToken() { // Assume the field body has already been extracted. That is, we don't // have to watch for the end of the field body or folding. We just // treat any CRs or LFs as white space. mTokenStart = mNextStart; mTokenLength = 0; mTkType = eTkNull; // Skip leading space. Also, since control chars are not permitted // in atoms, skip these, too. while (1) { if (mTokenStart >= mString.length()) { return; } if (isnotspaceorcntrl(mString[mTokenStart])) break; ++mTokenStart; } char ch = mString[mTokenStart]; switch (ch) { // Quoted string case '"': mTkType = eTkQuotedString; ParseQuotedString(); break; // Comment case '(': mTkType = eTkComment; ParseComment(); break; // Domain literal case '[': mTkType = eTkDomainLiteral; ParseDomainLiteral(); break; // Special case ')': case '<': case '>': case '@': case ',': case ';': case ':': case '\\': case '.': case ']': mTkType = eTkSpecial; mTokenLength = 1; mToken = mString.substr(mTokenStart, 1); mNextStart = mTokenStart + 1; break; default: mTkType = eTkAtom; ParseAtom(); break; } if (mDebugOut) PrintToken(mDebugOut); } void DwRfc822Tokenizer::ParseAtom() { size_t pos = mTokenStart; while (1) { ++pos; char ch = (pos < mString.length()) ? mString[pos] : (char) 0; if (pos >= mString.length() || isspecialorspaceorcntrl(ch)) { mTokenLength = pos - mTokenStart; mToken = mString.substr(mTokenStart, mTokenLength); mNextStart = pos; break; } } } static inline bool istspecialorspaceorcntrl( int c ) { switch ( c ) { case '(': case ')': case '<': case '>': case '@': case ',': case ';': case ':': case '\\': case '"': case '/': case '[': case ']': case '?': case '=': // isspace() case ' ': return true; //case '\r': included in iscntrl() //case '\f': included in iscntrl() //case '\t': included in iscntrl() //case '\n': included in iscntrl() //case '\v': included in iscntrl() // iscntrl() default: return ( ( c >= 0 && c <= 15) || (c >= 17 && c <= 31) ); } } DwRfc1521Tokenizer::DwRfc1521Tokenizer(const DwString& aStr) : DwTokenizer(aStr) { ParseToken(); } DwRfc1521Tokenizer::DwRfc1521Tokenizer(const char* aCStr) : DwTokenizer(aCStr) { ParseToken(); } DwRfc1521Tokenizer::~DwRfc1521Tokenizer() { } int DwRfc1521Tokenizer::Restart() { mNextStart = 0; ParseToken(); return mTkType; } int DwRfc1521Tokenizer::operator ++ () { ParseToken(); return mTkType; } void DwRfc1521Tokenizer::ParseToken() { // Assume the field body has already been extracted. That is, we don't // have to watch for the end of the field body or folding. We just // treat any CRs or LFs as white space. mTokenStart = mNextStart; mTokenLength = 0; mTkType = eTkNull; // Skip leading space. Also, since control chars are not permitted // in atoms, skip these, too. while (1) { if (mTokenStart >= mString.length()) { return; } if (isnotspaceorcntrl(mString[mTokenStart])) break; ++mTokenStart; } char ch = mString[mTokenStart]; switch (ch) { // Quoted string case '"': mTkType = eTkQuotedString; ParseQuotedString(); break; // Comment case '(': mTkType = eTkComment; ParseComment(); break; // Domain literal case '[': mTkType = eTkDomainLiteral; ParseDomainLiteral(); break; // Special case ')': case '<': case '>': case '@': case ',': case ';': case ':': case '\\': case '/': case ']': case '?': case '=': mTkType = eTkTspecial; mTokenLength = 1; mToken = mString.substr(mTokenStart, 1); mNextStart = mTokenStart + 1; break; default: mTkType = eTkToken; ParseAtom(); break; } if (mDebugOut) PrintToken(mDebugOut); } void DwRfc1521Tokenizer::ParseAtom() { size_t pos = mTokenStart; while (1) { ++pos; char ch = (pos < mString.length()) ? mString[pos] : (char) 0; if (pos >= mString.length() || istspecialorspaceorcntrl(ch)) { mTokenLength = pos - mTokenStart; mToken = mString.substr(mTokenStart, mTokenLength); mNextStart = pos; break; } } } DwTokenString::DwTokenString(const DwString& aStr) : mString(aStr) { mTokensStart = 0; mTokensLength = 0; } DwTokenString::~DwTokenString() { } void DwTokenString::SetFirst(const DwTokenizer& aTkzr) { switch (aTkzr.Type()) { case eTkError: case eTkNull: mTokensStart = aTkzr.mTokenStart; mTokensLength = 0; break; case eTkComment: case eTkDomainLiteral: case eTkQuotedString: case eTkSpecial: case eTkAtom: case eTkTspecial: case eTkToken: mTokensStart = aTkzr.mTokenStart; mTokensLength = aTkzr.mTokenLength; break; } mTokens = mString.substr(mTokensStart, mTokensLength); } void DwTokenString::SetLast(const DwTokenizer& aTkzr) { assert(aTkzr.mTokenStart >= mTokensStart); if (aTkzr.mTokenStart < mTokensStart) return; mTokensLength = aTkzr.mTokenStart + aTkzr.mTokenLength - mTokensStart; mTokens = mString.substr(mTokensStart, mTokensLength); } void DwTokenString::ExtendTo(const DwTokenizer& aTkzr) { assert(aTkzr.mTokenStart >= mTokensStart); if (aTkzr.mTokenStart < mTokensStart) return; mTokensLength = aTkzr.mTokenStart - mTokensStart; mTokens = mString.substr(mTokensStart, mTokensLength); } mimelib1-1.1.4/mimelib/mimelib/0000755000175000017500000000000011207320630015642 5ustar resivoresivomimelib1-1.1.4/mimelib/mimelib/disptype.h0000644000175000017500000002203011175345261017664 0ustar resivoresivo//============================================================================= // File: disptype.h // Contents: Declarations for DwDispositionType // Maintainer: Doug Sauder // WWW: http://www.fwb.gulf.net/~dwsauder/mimepp.html // // Copyright (c) 1996, 1997 Douglas W. Sauder // All rights reserved. // // IN NO EVENT SHALL DOUGLAS W. SAUDER BE LIABLE TO ANY PARTY FOR DIRECT, // INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF // THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF DOUGLAS W. SAUDER // HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // DOUGLAS W. SAUDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT // NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A // PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" // BASIS, AND DOUGLAS W. SAUDER HAS NO OBLIGATION TO PROVIDE MAINTENANCE, // SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. // //============================================================================= #ifndef DW_DISPTYPE_H #define DW_DISPTYPE_H #ifndef DW_CONFIG_H #include #endif #ifndef DW_STRING_H #include #endif #ifndef DW_FIELDBDY_H #include #endif class DwParameter; //============================================================================= //+ Name DwDispositionType -- Class representing a MIME content-disposition field body //+ Description //. {\tt DwDispositionType} represents a field body for the //. Content-Disposition header field as described in RFC-1806. This header //. field specifies whether the content of a message or body part should //. be displayed automatically to a user. A disposition-type of inline //. indicates that the content should be displayed; a disposition-type //. of attachment indicates that it should not be. RFC-1806 specifies //. that a filename parameter may be optionally included in the field //. body; the filename parameter suggests a file name for saving the //. message or body part's content. //. //. {\tt DwDispositionType} provides convenience functions that allow you //. to set or get the disposition-type as an enumerated value, to set or //. get the filename parameter, or to manage a list of parameters. //. //. RFC-1806 specifically states that the Content-Disposition header field //. is experimental and not a proposed standard. //============================================================================= // Last modified 1997-08-23 //+ Noentry ~DwDispositionType _AddParameter EnumToStr StrToEnum //+ Noentry DeleteParameterList CopyParameterList mDispositionType //+ Noentry mDispositionTypeStr mFilenameStr mFirstParameter //+ Noentry PrintDebugInfo _PrintDebugInfo CheckInvariants class DW_EXPORT DwDispositionType : public DwFieldBody { public: DwDispositionType(); DwDispositionType(const DwDispositionType& aDispType); DwDispositionType(const DwString& aStr, DwMessageComponent* aParent=0); //. The first constructor is the default constructor, which sets the //. {\tt DwDispositionType} object's string representation to the empty //. string and sets its parent to {\tt NULL}. //. //. The second constructor is the copy constructor, which performs //. deep copy of {\tt aDispType}. //. The parent of the new {\tt DwDispositionType} object is set to //. {\tt NULL}. //. //. The third constructor copies {\tt aStr} to the {\tt DwDispositionType} //. object's string representation and sets {\tt aParent} as its parent. //. The virtual member function {\tt Parse()} should be called immediately //. after this constructor in order to parse the string representation. //. Unless it is {\tt NULL}, {\tt aParent} should point to an object of //. a class derived from {\tt DwField}. virtual ~DwDispositionType(); const DwDispositionType& operator = (const DwDispositionType& aDispType); //. This is the assignment operator, which performs a deep copy of //. {\tt aDispType}. The parent node of the {\tt DwDipositionType} //. object is not changed. virtual void Parse(); //. This virtual function, inherited from {\tt DwMessageComponent}, //. executes the parse method for {\tt DwDispositionType} objects. //. It should be called immediately after the string representation //. is modified and before the parts of the broken-down //. representation are accessed. //. //. This function clears the is-modified flag. virtual void Assemble(); //. This virtual function, inherited from {\tt DwMessageComponent}, //. executes the assemble method for {\tt DwDispositionType} objects. //. It should be called whenever one of the object's attributes //. is changed in order to assemble the string representation from //. its broken-down representation. It will be called //. automatically for this object by the parent object's //. {\tt Assemble()} member function if the is-modified flag is set. //. //. This function clears the is-modified flag. virtual DwMessageComponent* Clone() const; //. This virtual function, inherited from {\tt DwMessageComponent}, //. creates a new {\tt DwDispositionType} object on the free store that //. has the same value as this {\tt DwDispositionType} object. The basic //. idea is that of a virtual copy constructor. int DispositionType() const; //. Returns the disposition-type as an enumerated value. Valid //. enumerated types, which are defined in enum.h, include //. {\tt DwMime::kDispTypeNull}, {\tt DwMime::kDispTypeUnknown}, //. {\tt DwMime::kDispTypeInline}, and {\tt DwMime::kDispTypeAttachment}. void SetDispositionType(int aType); //. Sets the disposition-type from the enumerated value {\tt aType}. //. Valid enumerated types, which are defined in enum.h, include //. {\tt DwMime::kDispTypeNull}, {\tt DwMime::kDispTypeUnknown}, //. {\tt DwMime::kDispTypeInline}, and {\tt DwMime::kDispTypeAttachment}. const DwString& DispositionTypeStr() const; //. Returns the disposition-type as a string. void SetDispositionTypeStr(const DwString& aStr); //. Sets the disposition-type from a string. const DwString& Filename() const; //. This convenience function returns the value from the filename //. parameter, if present. If no filename parameter is present, //. an empty string is returned. void SetFilename(const DwString& aStr); //. This convenience function sets the value of the filename parameter //. to {\tt aStr}. DwParameter* FirstParameter() const; //. Returns the first {\tt DwParameter} object in the list managed by //. this {\tt DwDispositionType} object, or {\tt NULL} if no parameters are //. present. Use {\tt DwParameter::Next()} to iterate through the list. void AddParameter(DwParameter* aParam); //. Adds a {\tt DwParameter} object to the list managed by this //. {\tt DwDispositionType} object. static DwDispositionType* NewDispositionType(const DwString& aStr, DwMessageComponent* aParent); //. Creates a new {\tt DwDispositionType} object on the free store. //. If the static data member {\tt sNewDispositionType} is {\tt NULL}, //. this member function will create a new {\tt DwDispositionType} //. and return it. Otherwise, {\tt NewDispositionType()} will call //. the user-supplied function pointed to by {\tt sNewDispositionType}, //. which is assumed to return an object from a class derived from //. {\tt DwDispositionType}, and return that object. //+ Var sNewDispositionType static DwDispositionType* (*sNewDispositionType)(const DwString&, DwMessageComponent*); //. If {\tt sNewDispositionType} is not {\tt NULL}, it is assumed to //. point to a user-supplied function that returns an object from a //. class derived from {\tt DwDispositionType}. protected: void _AddParameter(DwParameter* aParam); //. Adds a parameter to the list without setting the is-modified flag. virtual void EnumToStr(); virtual void StrToEnum(); void DeleteParameterList(); void CopyParameterList(DwParameter* aFirst); int mDispositionType; DwString mDispositionTypeStr; DwString mFilenameStr; DwParameter* mFirstParameter; private: static const char* const sClassName; public: virtual void PrintDebugInfo(std::ostream& aStrm, int aDepth=0) const; //. This virtual function, inherited from {\tt DwMessageComponent}, //. prints debugging information about this object to {\tt aStrm}. //. It will also call {\tt PrintDebugInfo()} for any of its child //. components down to a level of {\tt aDepth}. //. //. This member function is available only in the debug version of //. the library. virtual void CheckInvariants() const; //. Aborts if one of the invariants of the object fails. Use this //. member function to track down bugs. //. //. This member function is available only in the debug version of //. the library. protected: void _PrintDebugInfo(std::ostream& aStrm) const; }; #endif mimelib1-1.1.4/mimelib/mimelib/field.h0000644000175000017500000002652211175345261017120 0ustar resivoresivo//============================================================================= // File: field.h // Contents: Declarations for DwField // Maintainer: Doug Sauder // WWW: http://www.fwb.gulf.net/~dwsauder/mimepp.html // // Copyright (c) 1996, 1997 Douglas W. Sauder // All rights reserved. // // IN NO EVENT SHALL DOUGLAS W. SAUDER BE LIABLE TO ANY PARTY FOR DIRECT, // INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF // THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF DOUGLAS W. SAUDER // HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // DOUGLAS W. SAUDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT // NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A // PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" // BASIS, AND DOUGLAS W. SAUDER HAS NO OBLIGATION TO PROVIDE MAINTENANCE, // SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. // //============================================================================= #ifndef DW_FIELD_H #define DW_FIELD_H #include #ifndef DW_CONFIG_H #include #endif #ifndef DW_STRING_H #include #endif #ifndef DW_MSGCMP_H #include #endif class DwHeaders; class DwFieldBody; //============================================================================= //+ Name DwField -- Class representing a MIME header field //+ Description //. {\tt DwField} represents a header field as described in RFC-822. //. According to RFC-822, a field contains a field name and a field body. //. In MIME++, a {\tt DwField} contains three elements: a {\tt DwString} //. that contains its field name, a {\tt DwString} that contains its //. field body, and a {\tt DwFieldBody} object that contains a broken-down //. (that is, parsed) version of its field body. //. //. In the tree (broken-down) representation of message, a {\tt DwField} //. object is always an intermediate node, having a parent node and a single //. child node. The parent node is the {\tt DwHeaders} object that contains //. it. The child node is the {\tt DwFieldBody} object it contains. //. //. To get and set the field name, use the member functions //. {\tt FieldNameStr()} and {\tt SetFieldNameStr()}. //. To get and set the field body, use the member functions //. {\tt FieldBodyStr()} and {\tt SetFieldBodyStr()}. //. To get and set the {\tt DwFieldBody} object, use {\tt FieldBody()} //. and {\tt SetFieldBody()}. //. //. A {\tt DwField} object can be included in a list of {\tt DwField} //. objects; usually this is the list of {\tt DwField} objects maintained //. by its parent {\tt DwHeaders} object. To get the next {\tt DwField} //. object in a list, use the member function {\tt Next()}. //============================================================================= // Last updated 1997-08-23 //+ Noentry ~DwField _CreateFieldBody mFieldNameStr mFieldBodyStr //+ Noentry mFieldBody _PrintDebugInfo class DW_EXPORT DwField : public DwMessageComponent { friend class DwHeaders; public: DwField(); DwField(const DwField& aField); DwField(const DwString& aStr, DwMessageComponent* aParent=0); //. The first constructor is the default constructor, which sets the //. {\tt DwField} object's field name and field body to the empty //. string, set its parent to {\tt NULL}, and sets its {\tt DwFieldBody} //. object to {\tt NULL}. //. //. The second constructor is the copy constructor, which performs //. a deep copy of {\tt aField}. //. The parent of the new {\tt DwField} object is set to {\tt NULL}. //. //. The third constructor copies {\tt aStr} to the {\tt DwField} //. object's string representation and sets {\tt aParent} as its parent. //. The virtual member function {\tt Parse()} should be called immediately //. after this constructor in order to parse the string representation. //. Unless it is {\tt NULL}, {\tt aParent} should point to an object of //. a class derived from {\tt DwHeaders}. virtual ~DwField(); const DwField& operator = (const DwField& aField); //. This is the assignment operator, which performs a deep copy of //. {\tt aField}. The parent node of the {\tt DwField} object //. is not changed. virtual void Parse(); //. This virtual function, inherited from {\tt DwMessageComponent}, //. executes the parse method for {\tt DwField} objects. The parse //. method creates or updates the broken-down representation from the //. string representation. For {\tt DwField} objects, the parse method //. parses the string representation, sets the values of the field //. name string and the field body string, and creates an instance //. of the appropriate subclass of {\tt DwFieldBody}. This member //. function also calls the {\tt Parse()} member function of its //. contained {\tt DwFieldBody} object. //. //. You should call this member function after you set or modify the //. string representation, and before you access the field name, the //. field body, or the contained {\tt DwFieldBody} object. //. //. This function clears the is-modified flag. virtual void Assemble(); //. This virtual function, inherited from {\tt DwMessageComponent}, //. executes the assemble method for {\tt DwField} objects. The //. assemble method creates or updates the string representation from //. the broken-down representation. In more concrete terms, the //. assemble method builds the string representation from the field //. name and the string representation of the contained {\tt DwFieldBody} //. object. This member function calls the {\tt Assemble()} member //. function of its contained {\tt DwFieldBody} object. //. //. You should call this member function after you modify either the //. field name or the contained {\tt DwFieldBody} object, and before //. you retrieve the string representation. //. //. This function clears the is-modified flag. virtual DwMessageComponent* Clone() const; //. This virtual function, inherited from {\tt DwMessageComponent}, //. creates a new {\tt DwField} on the free store that has the same //. value as this {\tt DwField} object. The basic idea is that of //. a virtual copy constructor. DwFieldBody* FieldBody() const; //. Returns the {\tt DwFieldBody} object contained by this {\tt DwField} //. object. If there is no field body, {\tt NULL} will be returned. const DwString& FieldNameStr() const; //. Returns the field name of this header field as a string. const DwString& FieldBodyStr() const; //. Returns the field body of this header field as a string. DwField* Next() const; //. Returns the next {\tt DwField} object following this //. {\tt DwField} object in the list contained in a {\tt DwHeaders}. //. Returns {\tt NULL} if this object is last in the list. void SetFieldBody(DwFieldBody* aFieldBody); //. Sets the {\tt DwFieldBody} object contained by this object. void SetFieldNameStr(const DwString& aStr); //. Sets the field name of this header field. void SetFieldBodyStr(const DwString& aStr); //. Sets the field body of this header field. void SetNext(const DwField* aField); //. This {\it advanced} function sets {\tt aField} as the next field //. following this field in the list of fields contained in the headers. //. Since {\tt DwHeaders} contains member functions for adding //. {\tt DwField} objects to its list, this function should be //. avoided for most applications. static DwField* NewField(const DwString& aStr, DwMessageComponent* aParent); //. Creates a new {\tt DwField} object on the free store. //. If the static data member {\tt sNewField} is {\tt NULL}, //. this member function will create a new {\tt DwField} //. and return it. Otherwise, {\tt NewField()} will call //. the user-supplied function pointed to by {\tt sNewField}, //. which is assumed to return an object from a class derived from //. {\tt DwField}, and return that object. static DwFieldBody* CreateFieldBody(const DwString& aFieldName, const DwString& aFieldBody, DwMessageComponent* aParent); //. The static member function {\tt CreateFieldBody()} is called from //. the {\tt Parse()} member function and is responsible for creating a //. {\tt DwFieldBody} object for this particular field. A typical //. scenario might go as follows: //. This member function examines the field name for this field, //. finds that it contains "To", creates a {\tt DwAddressList} object //. to contain the field body, calls the {\tt Parse()} member //. function for the {\tt DwAddressList}, and sets the {\tt DwAddressList} //. object as this {\tt DwField} object's {\tt DwFieldBody}. //. //. If you want to override the behavior of {\tt CreateFieldBody()}, //. you can do so by setting the public data member //. {\tt sCreateFieldBody} to point to your own function. //. {\tt CreateFieldBody()} first checks to see if //. {\tt sCreateFieldBody} is {\tt NULL}. If it is not, //. {\tt CreateFieldBody()} will assume that it points to a user-supplied //. function and will call that function. If it is {\tt NULL}, //. {\tt CreateFieldBody()} will call {\tt _CreateFieldBody()}, which //. actually creates the {\tt DwFieldBody} object. You may call //. {\tt _CreateFieldBody()} from your own function for fields you //. do not wish to handle. static DwFieldBody* _CreateFieldBody(const DwString& aFieldName, const DwString& aFieldBody, DwMessageComponent* aParent); //+ Var sNewField static DwField* (*sNewField)(const DwString&, DwMessageComponent*); //. If {\tt sNewField} is not {\tt NULL}, it is assumed to point //. to a user-supplied function that returns an object from a class //. derived from {\tt DwField}. //+ Var sCreateFieldBody static DwFieldBody* (*sCreateFieldBody)(const DwString& aFieldName, const DwString& aFieldBody, DwMessageComponent* aParent); //. See {\tt CreateFieldBody()}. protected: DwString mFieldNameStr; // the {\it field-name} DwString mFieldBodyStr; // the {\it field-body} DwFieldBody* mFieldBody; // pointer to the {\tt DwFieldBody} object void _SetFieldBody(DwFieldBody* aFieldBody); //. Sets the {\tt DwFieldBody} object contained by this object. This //. function differs from {\tt SetFieldBody()} in that it does not //. set the is-modified flag. private: const DwField* mNext; static const char* const sClassName; public: virtual void PrintDebugInfo(std::ostream& aStrm, int aDepth=0) const; //. This virtual function, inherited from {\tt DwMessageComponent}, //. prints debugging information about this object to {\tt aStrm}. //. It will also call {\tt PrintDebugInfo()} for any of its child //. components down to a level of {\tt aDepth}. //. //. This member function is available only in the debug version of //. the library. virtual void CheckInvariants() const; //. Aborts if one of the invariants of the object fails. Use this //. member function to track down bugs. //. //. This member function is available only in the debug version of //. the library. protected: void _PrintDebugInfo(std::ostream& aStrm) const; }; #endif mimelib1-1.1.4/mimelib/mimelib/text.h0000644000175000017500000001350111175345261017012 0ustar resivoresivo//============================================================================= // File: text.h // Contents: Declarations for DwText // Maintainer: Doug Sauder // WWW: http://www.fwb.gulf.net/~dwsauder/mimepp.html // // Copyright (c) 1996, 1997 Douglas W. Sauder // All rights reserved. // // IN NO EVENT SHALL DOUGLAS W. SAUDER BE LIABLE TO ANY PARTY FOR DIRECT, // INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF // THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF DOUGLAS W. SAUDER // HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // DOUGLAS W. SAUDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT // NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A // PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" // BASIS, AND DOUGLAS W. SAUDER HAS NO OBLIGATION TO PROVIDE MAINTENANCE, // SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. // //============================================================================= #ifndef DW_TEXT_H #define DW_TEXT_H #ifndef DW_CONFIG_H #include #endif #ifndef DW_STRING_H #include #endif #ifndef DW_FIELDBDY_H #include #endif //============================================================================= //+ Name DwText -- Class representing text in a RFC-822 header field-body //+ Description //. {\tt DwText} represents an unstructured field body in a header field. //. It roughly corresponds to the {\it text} element of the BNF grammar //. defined in RFC-822. //============================================================================= // Last modified 1997-07-30 //+ Noentry ~DwText sClassName _PrintDebugInfo class DW_EXPORT DwText : public DwFieldBody { public: DwText(); DwText(const DwText& aText); DwText(const DwString& aStr, DwMessageComponent* aParent=0); //. The first constructor is the default constructor, which sets the //. {\tt DwText} object's string representation to the empty string //. and sets its parent to NULL. //. //. The second constructor is the copy constructor, which copies the //. string representation from {\tt aText}. //. The parent of the new {\tt DwText} object is set to NULL. //. //. The third constructor copies {\tt aStr} to the {\tt DwText} //. object's string representation and sets {\tt aParent} as its parent. //. The virtual member function {\tt Parse()} should be called immediately //. after this constructor in order to parse the string representation. //. Unless it is NULL, {\tt aParent} should point to an object of a class //. derived from {\tt DwField}. virtual ~DwText(); const DwText& operator = (const DwText& aText); //. This is the assignment operator. virtual void Parse(); //. This virtual member function is inherited from //. {\tt DwMessageComponent}, where it is declared a pure virtual //. function. For a {\tt DwText} object, this member function does //. nothing, since {\tt DwText} represents an unstructured field body //. (like the Subject header field) that does not have a broken-down //. form. //. //. Note, however, that this function should still be called consistently, //. since a subclass of {\tt DwText} may implement a parse method. //. //. This function clears the is-modified flag. virtual void Assemble(); //. This virtual member function is inherited from //. {\tt DwMessageComponent}, where it is declared a pure virtual //. function. For a {\tt DwText} object, this member function does //. nothing, since {\tt DwText} represents an unstructured field body //. (like the Subject header field) that does not have a broken-down //. form. //. //. Note, however, that this function should still be called consistently, //. since a subclass of {\tt DwText} may implement an assemble method. //. //. This function clears the is-modified flag. virtual DwMessageComponent* Clone() const; //. This virtual function, inherited from {\tt DwMessageComponent}, //. creates a new {\tt DwText} on the free store that has the same //. value as this {\tt DwText} object. The basic idea is that of //. a ``virtual copy constructor.'' static DwText* NewText(const DwString& aStr, DwMessageComponent* aParent); //. Creates a new {\tt DwText} object on the free store. //. If the static data member {\tt sNewText} is NULL, //. this member function will create a new {\tt DwText} //. and return it. Otherwise, {\tt NewText()} will call //. the user-supplied function pointed to by {\tt sNewText}, //. which is assumed to return an object from a class derived from //. {\tt DwText}, and return that object. //+ Var sNewText static DwText* (*sNewText)(const DwString&, DwMessageComponent*); //. If {\tt sNewText} is not NULL, it is assumed to point to a //. user-supplied function that returns an object from a class derived from //. {\tt DwText}. private: static const char* const sClassName; public: virtual void PrintDebugInfo(std::ostream& aStrm, int aDepth=0) const; //. This virtual function, inherited from {\tt DwMessageComponent}, //. prints debugging information about this object to {\tt aStrm}. //. It will also call {\tt PrintDebugInfo()} for any of its child //. components down to a level of {\tt aDepth}. //. //. This member function is available only in the debug version of //. the library. virtual void CheckInvariants() const; //. Aborts if one of the invariants of the object fails. Use this //. member function to track down bugs. //. //. This member function is available only in the debug version of //. the library. protected: void _PrintDebugInfo(std::ostream& aStrm) const; }; #endif mimelib1-1.1.4/mimelib/mimelib/msgcmp.h0000644000175000017500000003072611175345261017324 0ustar resivoresivo//============================================================================= // File: msgcmp.h // Contents: Declarations for DwMessageComponent // Maintainer: Doug Sauder // WWW: http://www.fwb.gulf.net/~dwsauder/mimepp.html // // Copyright (c) 1996, 1997 Douglas W. Sauder // All rights reserved. // // IN NO EVENT SHALL DOUGLAS W. SAUDER BE LIABLE TO ANY PARTY FOR DIRECT, // INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF // THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF DOUGLAS W. SAUDER // HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // DOUGLAS W. SAUDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT // NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A // PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" // BASIS, AND DOUGLAS W. SAUDER HAS NO OBLIGATION TO PROVIDE MAINTENANCE, // SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. // //============================================================================= #ifndef DW_MSGCMP_H #define DW_MSGCMP_H #ifndef DW_CONFIG_H #include #endif #ifndef DW_STRING_H #include #endif #if !(defined(__DECCXX) && defined(__linux__)) #include #endif //============================================================================= //+ Name DwMessageComponent -- Abstract base class for all message components //+ Description //. {\tt DwMessageComponent} is the root of an inheritance hierarchy from //. which all MIME message components are derived. Thus, //. {\tt DwMessageComponent} defines important features that are inherited by //. nearly all other classes that represent components of a MIME message. //. These features are the following: //. //. \begin{enumerate} //. \item //. A string representation. The {\tt DwMessageComponent} class provides //. a member function {\tt FromString(const DwString&)} to set the string //. representation and a member function {\tt AsString()} to get the //. string representation. //. //. \item //. A broken-down, or parsed, representation. An RFC-822 date-time, //. for example, has a year, month, day, hour, minute, second, and //. time zone as elements of its broken-down representation. //. {\tt DwMessageComponent} does not deal directly with the //. broken-down representation, since it is component-specific. //. Derived classes bear all the responsibility for their broken-down //. representations. //. //. \item //. A parse method to extract the broken-down representation from //. the string representation. In the {\tt DwDateTime} class, for //. example, the parse method extracts the year, month, day, hour, //. minute, second, and time zone from the RFC-822 {\it date-time} //. contained in the string representation. {\tt DwMessageComponent} //. provides a pure virtual function {\tt Parse()}, which executes //. the parse method for a derived class. //. //. \item //. An assemble method to convert the broken-down representation to //. a string representation. This is the opposite of the parse method. //. In the {\tt DwDateTime} class, for example, the assemble method //. creates an RFC-822 {\it date-time} string from values of the //. year, month, day, hour, minute, second, and time zone. //. {\tt DwMessageComponent} provides a pure virtual function //. {\tt Assemble()}, which executes the assemble method for //. a derived class. //. //. \item //. An is-modified flag. When the string representation and the //. broken-down representation are consistent, the assemble //. method does not need to be executed. The is-modified flag is //. cleared when the two representations are consistent, and is set //. when they are inconsistent. The flag is set automatically //. whenever a {\tt DwMessageComponent} object's broken-down //. representation is changed by calling one of the object's member //. functions, and it is cleared when the assemble or parse method //. is executed. {\tt DwMessageComponent} also provides a member //. function {\tt SetModified()} which forces the is-modified flag //. to be set. //. //. \item //. A parent. Most message components are part of another component. //. A collection of headers is part of a message or body part, a header //. field is part of a collection of headers, a field-body is part //. of a header field, and so on. The parent of //. a component is the component that contains it. This tree structure //. is important, since a component's parent must be parsed before the //. component can be. Also, a component's string representation must //. be assembled before its parent's. To maintain consistency in the //. tree, whenever a component's is-modified flag is set, //. the component notifies its parent to also set its is-modified flag. //. In this way, an is-modified flag set anywhere in the tree always //. propagates up to the root component. //. //. \item //. Children. The preceding discussion about a component's parent is //. relevant to an understanding of a component's children. A component's //. parse method calls the parse methods of its children //. after it has executed its own parse method (and, in some cases, created //. all of its children). //. Also, a component typically calls the assemble method of its //. children before it executes its own. A component's child may request //. that the component set its is-modified flag. //. {\tt DwMessageComponent} does not deal directly with children. //. Derived classes bear all the responsibility for handling their //. children. //. \end{enumerate} //============================================================================= //+ Noentry ~DwMessageComponent _PrintDebugInfo mString mIsModified mParent //+ Noentry mClassId mClassName class DW_EXPORT DwMessageComponent { private: DwUint32 mMagicNumber; public: enum componentType { kCidError=-1, kCidUnknown=0, kCidAddress, kCidAddressList, kCidBody, kCidBodyPart, kCidDispositionType, kCidMechanism, kCidMediaType, kCidParameter, kCidDateTime, kCidEntity, kCidField, kCidFieldBody, kCidGroup, kCidHeaders, kCidMailbox, kCidMailboxList, kCidMessage, kCidMessageComponent, kCidMsgId, kCidText }; //. Class identifier enumeration DwMessageComponent(); DwMessageComponent(const DwMessageComponent& aCmp); DwMessageComponent(const DwString& aStr, DwMessageComponent* aParent=0); //. The first constructor is the default constructor, which sets the //. {\tt DwMessageComponent} object's string representation to the //. empty string and sets its parent to NULL. //. //. The second constructor is the copy constructor, which performs //. a deep copy of {\tt aCmp}. The parent of the new //. {\tt DwMessageComponent} object is set to NULL. //. //. The third constructor copies {\tt aStr} to the new //. {\tt DwMessageComponent} object's string representation and sets //. {\tt aParent} as its parent. In typical cases, the virtual //. member function {\tt Parse()} should be called immediately after //. this constructor to parse the new {\tt DwMessageComponent} object //. and all of its children into their broken-down representations. virtual ~DwMessageComponent(); const DwMessageComponent& operator = (const DwMessageComponent& aCmp); //. This is the assignment operator, which performs a deep copy of //. {\tt aCmp}. virtual void Parse() = 0; //. A pure virtual function which provides an interface to the parse //. method. The parse method, implemented in derived classes, is //. responsible for extracting the broken-down representation from //. the string representation. In some derived classes, such as //. {\tt DwHeaders}, the parse method is also responsible for creating the //. children of the object. (In the case of {\tt DwHeaders}, the children //. created are the {\tt DwField} objects that represent the {\it field}s //. contained in the {\it headers}.) The {\tt Parse()} function always //. calls the {\tt Parse()} function of all of its children. virtual void Assemble() = 0; //. A pure virtual function which provides an interface to the //. assemble method. The assemble method, implemented in derived //. classes, is responsible for creating the string representation //. from the broken-down representation. In other words, the //. assemble method is the opposite of the parse method. Before //. assembling its string representation, the assemble method calls //. the assemble method of each of its children. In this way, the //. entire tree structure that represents a message may be traversed. //. If the is-modifed flag for a {\tt DwMessageComponent} is cleared, //. the {\tt Assemble()} function will return immediately without //. calling the {\tt Assemble()} function of any of its children. virtual DwMessageComponent* Clone() const = 0; //. Creates a new {\tt DwMessageComponent} on the free store that is of //. the same type as, and has the same value as, this object. The //. basic idea is that of a ``virtual copy constructor.'' void FromString(const DwString& aStr); void FromString(const char* aCstr); //. Sets the object's string representation. {\tt aCstr} must be //. NUL-terminated. This member function does not invoke the parse //. method. Typically, the virtual member function {\tt Parse()} //. should be called immediately after this member function to parse //. the {\tt DwMessageComponent} object and all of its children into //. their broken-down representations. See also //. {\tt DwMessageComponent::Parse()} const DwString& AsString(); //. Returns the {\tt DwMessageComponent} object's string representation. //. The assemble method is not called automatically. Typically, the //. {\tt Assemble()} member function should be called immediately before //. this member function to insure that the broken-down representation //. and the string representation are consistent. See also //. {\tt DwMessageComponent::Assemble()}. DwMessageComponent* Parent(); //. Returns the {\tt DwMessageComponent} object that is the parent //. of this object. void SetParent(DwMessageComponent* aParent); //. Sets {\tt aParent} as the {\tt DwMessageComponent} object's parent. DwBool IsModified() const; //. Returns 1 if the is-modified flag is set for this //. {\tt DwMessageComponent} object. void SetModified(); //. Sets the is-modified (dirty) flag for this {\tt DwMessageComponent} //. object and notifies the object's parent to also set its is-modified //. flag. int ClassId() const; //. Returns an integer id for the object's class. const char* ClassName() const; //. Returns the name of the class as a NUL-terminated //. char string. int ObjectId() const; //. Returns a object id that is unique among all DwMessageComponent //. objects. const char* partId() const { return mId.c_str(); } void SetPartId( DwString id ) { mId = id; } // set or get a unique string for that part protected: DwString mString; // String representation DwBool mIsModified; // Is-modified flag DwMessageComponent* mParent; // Component that contains this component componentType mClassId; // Class identifier for runtime type identification const char* mClassName; // Class name for runtime type identification DwString mId; // unique indentifier private: static const char* const sClassName; public: virtual void PrintDebugInfo(std::ostream& aStrm, int aDepth=0) const; //. This virtual function //. prints debugging information about this object to {\tt aStrm}. //. It will also call {\tt PrintDebugInfo()} for any of its child //. components down to a level of {\tt aDepth}. //. //. This member function is available only in the debug version of //. the library. virtual void CheckInvariants() const; //. Aborts if one of the invariants of the object fails. Use this //. member function to track down bugs. //. //. This member function is available only in the debug version of //. the library. protected: void _PrintDebugInfo(std::ostream& aStrm) const; }; #endif mimelib1-1.1.4/mimelib/mimelib/token.h0000644000175000017500000001150111175345261017144 0ustar resivoresivo//============================================================================= // File: token.h // Contents: Declarations for DwTokenizer, DwRfc822Tokenizer // Maintainer: Doug Sauder // WWW: http://www.fwb.gulf.net/~dwsauder/mimepp.html // // Copyright (c) 1996, 1997 Douglas W. Sauder // All rights reserved. // // IN NO EVENT SHALL DOUGLAS W. SAUDER BE LIABLE TO ANY PARTY FOR DIRECT, // INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF // THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF DOUGLAS W. SAUDER // HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // DOUGLAS W. SAUDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT // NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A // PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" // BASIS, AND DOUGLAS W. SAUDER HAS NO OBLIGATION TO PROVIDE MAINTENANCE, // SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. // //============================================================================= #ifndef DW_TOKEN_H #define DW_TOKEN_H #ifndef DW_CONFIG_H #include #endif #ifndef DW_STRING_H #include #endif // RFC 822 and RFC 1521 define slightly different grammars for the field // bodies they define. The differences are that RFC 822 defines a basic // type 'atom' while RFC 1521 defines a basic type 'token', and RFC 822 // defines a character class 'special' while RFC 1521 defines a character // class 'tspecial'. For this reason, we have two tokenizer classes: // Rfc822Tokenizer and Rfc1521Tokenizer. Since the basic types // quoted string, comment, and domain literal are common to both RFC 822 // and RFC 1521, the common code of both tokenizer classes is // combined into a Tokenizer base class. The Tokenizer class has no public // constructors, since only objects of class Rfc822Tokenizer or // Rfc1521Tokenizer will ever be instantiated. // // Note that we do not use polymorphism here: Tokenizer has no virtual // functions. We do this for efficiency, since there is some overhead // involved with virtual functions. If the classes were more complicated // than they currently are, then virtual functions would be justified in // order to reduce the duplication of code. As it stands, though, the // classes are fairly simple and efficient. // In addition, polymorphism is not needed to use the tokenizer classes. #if !(defined(__DECCXX) && defined(__linux__)) #include #endif enum { eTkError=-1, eTkNull=0, eTkSpecial, eTkAtom, eTkComment, eTkQuotedString, eTkDomainLiteral, eTkTspecial, eTkToken }; class DW_EXPORT DwTokenizer { friend class DwTokenString; public: const DwString& Token() const { return mToken; } int Type() const { return mTkType; } void StripDelimiters(); static std::ostream* mDebugOut; protected: DwTokenizer(const DwString& aStr); DwTokenizer(const char* aCStr); virtual ~DwTokenizer(); void PrintToken(std::ostream*); // Quoted strings, comments, and domain literals are parsed // identically in RFC822 and RFC1521 void ParseQuotedString(); void ParseComment(); void ParseDomainLiteral(); // Data members const DwString mString; DwString mToken; size_t mTokenStart; size_t mTokenLength; size_t mNextStart; int mTkType; }; class DW_EXPORT DwRfc822Tokenizer : public DwTokenizer { friend class DwAddressParser; public: DwRfc822Tokenizer(const DwString& aStr); DwRfc822Tokenizer(const char* aCStr); virtual ~DwRfc822Tokenizer(); int Restart(); int operator ++ (); // prefix increment operator private: DwRfc822Tokenizer(); DwRfc822Tokenizer(const DwRfc822Tokenizer&); void ParseToken(); void ParseAtom(); }; class DW_EXPORT DwRfc1521Tokenizer : public DwTokenizer { public: DwRfc1521Tokenizer(const DwString& aStr); DwRfc1521Tokenizer(const char* aCStr); virtual ~DwRfc1521Tokenizer(); int Restart(); int operator ++ (); // prefix increment operator private: DwRfc1521Tokenizer(); DwRfc1521Tokenizer(const DwRfc1521Tokenizer&); void ParseToken(); void ParseAtom(); }; // DwTokenString allows us to build a DwString of tokens by concatenating // them. This is not the normal string concatenation: the tokens are // assumed to have the same string rep, and the concatenated string shares // the rep. class DW_EXPORT DwTokenString { public: DwTokenString(const DwString&); virtual ~DwTokenString(); const DwString& Tokens() const { return mTokens; } void SetFirst(const DwTokenizer&); void SetLast(const DwTokenizer&); void ExtendTo(const DwTokenizer&); // void Concatenate(const DwTokenizer&); protected: const DwString mString; DwString mTokens; size_t mTokensStart; size_t mTokensLength; }; #endif mimelib1-1.1.4/mimelib/mimelib/uuencode.h0000644000175000017500000001070511175345261017640 0ustar resivoresivo//============================================================================= // File: uuencode.h // Contents: Declarations for DwUuencode // Maintainer: Doug Sauder // WWW: http://www.fwb.gulf.net/~dwsauder/mimepp.html // // Copyright (c) 1996, 1997 Douglas W. Sauder // All rights reserved. // // IN NO EVENT SHALL DOUGLAS W. SAUDER BE LIABLE TO ANY PARTY FOR DIRECT, // INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF // THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF DOUGLAS W. SAUDER // HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // DOUGLAS W. SAUDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT // NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A // PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" // BASIS, AND DOUGLAS W. SAUDER HAS NO OBLIGATION TO PROVIDE MAINTENANCE, // SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. // //============================================================================= #ifndef DW_UUENCODE_H #define DW_UUENCODE_H #ifndef DW_CONFIG_H #include #endif #ifndef DW_STRING_H #include #endif //============================================================================= //+ Name DwUuencode -- Class for performing uuencode or uudecode operations //+ Description //. {\tt DwUuencode} performs uuencode or uudecode operations. Uuencode //. is a format for encoding binary data into text characters for transmission //. through the mail system. The format also includes the file name and the //. file mode. (Note: The file mode is significant only in UNIX.) In MIME, //. the use of uuencode is deprecated; base64 is the preferred encoding //. for sending binary data. //. //. To use {\tt DwUuencode} for encoding binary data into uuencode format, //. set the file name, file mode, and binary data string using the member //. functions {\tt SetFileName()}, {\tt SetFileMode()}, and //. {\tt SetBinaryChars()}. Then call the member function {\tt Encode()}. //. Finally, retrieve the uuencoded text characters by calling //. {\tt AsciiChars()}. //. //. To use {\tt DwUuencode} to decode uuencoded data, set the ASCII characters //. using the member function {\tt SetAsciiChars()}, then call {\tt Decode()}. //. Finally, retrieve the file name, file mode, and binary characters by //. calling {\tt FileName()}, {\tt FileMode()}, and {\tt BinaryChars()}. //============================================================================= // Last modified 1997-07-29 //+ Noentry ~DwUuencode mFileName mMode mBinaryChars mAsciiChars class DW_EXPORT DwUuencode { public: DwUuencode(); //. This is the default constructor. virtual ~DwUuencode(); void Initialize(); //. Resets the object's internal state to its initial state. Call //. this member function to reuse the object for more than one encode //. or decode operation. void SetFileName(const char* aName); //. Sets the file name to be included in the uuencoded output. The //. implementation limits the file name to 255 characters. const char* FileName() const; //. Returns the file name extracted while uudecoding. The implementation //. limits the file name to 255 characters. void SetFileMode(DwUint16 aMode); //. Sets the file mode to be included in the uuencoded output. If //. the file mode is not explicitly set using this member function, //. a default value of 0644 (octal) is assumed. DwUint16 FileMode() const; //. Returns the file mode extracted while uudecoding. void SetBinaryChars(const DwString& aStr); //. Sets the string of binary data to be used in the uuencode operation. const DwString& BinaryChars() const; //. Returns the string of binary data extracted during a uudecode //. operation. void SetAsciiChars(const DwString& aStr); //. Sets the string of ASCII characters to used in the decode operation. const DwString& AsciiChars() const; //. Returns the string of ASCII characters created during a uuencode //. operation. void Encode(); //. Creates an ASCII string of characters by uuencoding the file name, //. file mode, and binary data. int Decode(); //. Extracts the file name, file mode, and binary data from the ASCII //. characters via a uudecode operation. private: char mFileName[256]; DwUint16 mMode; DwString mBinaryChars; DwString mAsciiChars; }; #endif mimelib1-1.1.4/mimelib/mimelib/entity.h0000644000175000017500000001636511175345261017355 0ustar resivoresivo//============================================================================= // File: entity.h // Contents: Declarations for DwEntity // Maintainer: Doug Sauder // WWW: http://www.fwb.gulf.net/~dwsauder/mimepp.html // // Copyright (c) 1996, 1997 Douglas W. Sauder // All rights reserved. // // IN NO EVENT SHALL DOUGLAS W. SAUDER BE LIABLE TO ANY PARTY FOR DIRECT, // INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF // THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF DOUGLAS W. SAUDER // HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // DOUGLAS W. SAUDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT // NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A // PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" // BASIS, AND DOUGLAS W. SAUDER HAS NO OBLIGATION TO PROVIDE MAINTENANCE, // SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. // //============================================================================= #ifndef DW_ENTITY_H #define DW_ENTITY_H #ifndef DW_CONFIG_H #include #endif #ifndef DW_STRING_H #include #endif #ifndef DW_MSGCMP_H #include #endif class DwHeaders; class DwBody; //============================================================================= //+ Name DwEntity -- Abstract class representing a MIME entity //+ Description //. RFC-2045 defines an {\it entity} as either a {\it message} or a //. {\it body part}, both of which have a collection of headers and //. a {\it body}. In MIME++, an entity is represented by the class //. {\tt DwEntity}, which contains both a {\tt DwHeaders} object and //. a {\tt DwBody} object. //. //. In the tree (broken-down) representation of message, a {\tt DwEntity} //. object may be either a root node, having child nodes but no parent //. node, or an intermediate node, having both a parent node and child nodes. //. A {\tt DwEntity} object that is a root node must also be a {\tt DwMessage} //. object. If a {\tt DwEntity} object is an intermediate node, its parent //. must be a {\tt DwBody} object. The child nodes of a {\tt DwEntity} //. object are the {\tt DwHeaders} and {\tt DwBody} objects it contains. //. //. Since {\tt DwEntity} is an abstract base class, you cannot create //. instances of it directly. {\tt DwEntity} has two derived classes, //. {\tt DwMessage} and {\tt DwBodyPart}, which are concrete classes. //. //. To access the contained {\tt DwHeaders} object, use the member function //. {\tt Headers()}. To access the contained {\tt DwBody} object, use the //. member function {\tt Body()}. //============================================================================= // Last updated 1997-08-23 //+ Noentry ~DwEntity mHeaders mBody _PrintDebugInfo class DW_EXPORT DwEntity : public DwMessageComponent { public: DwEntity(); DwEntity(const DwEntity& aEntity); DwEntity(const DwString& aStr, DwMessageComponent* aParent=0); //. The first constructor is the default constructor, which sets the //. {\tt DwEntity} object's string representation to the empty string //. and sets its parent to {\tt NULL}. //. //. The second constructor is the copy constructor, which performs //. a deep copy of {\tt aEntity}. //. The parent of the new {\tt DwEntity} object is set to {\tt NULL}. //. //. The third constructor copies {\tt aStr} to the {\tt DwEntity} //. object's string representation and sets {\tt aParent} as its parent. //. The virtual member function {\tt Parse()} should be called immediately //. after this constructor in order to parse the string representation. //. Unless it is {\tt NULL}, {\tt aParent} should point to an object of //. a class derived from {\tt DwBody}. virtual ~DwEntity(); const DwEntity& operator = (const DwEntity& aEntity); //. This is the assignment operator, which performs a deep copy of //. {\tt aEntity}. The parent node of the {\tt DwEntity} object //. is not changed. virtual void Parse(); //. This virtual function, inherited from {\tt DwMessageComponent}, //. executes the parse method for {\tt DwEntity} objects. The parse //. method creates or updates the broken-down representation from the //. string representation. For {\tt DwEntity} objects, the parse //. method parses the string representation and sets the values of //. the {\tt DwHeaders} and {\tt DwBody} objects it contains. This //. member function also calls the {\tt Parse()} member functions //. of the contained {\tt DwHeaders} and {\tt DwBody} objects. //. //. You should call this member function after you set or modify the //. string representation, and before you access either the contained //. headers or body. //. //. This function clears the is-modified flag. virtual void Assemble(DwHeaders& aHeaders, DwBody& aBody); // Assemble *without* first assembling the Header and the Body. virtual void Assemble(); //. This virtual function, inherited from {\tt DwMessageComponent}, //. executes the assemble method for {\tt DwEntity} objects. The //. assemble method creates or updates the string representation from //. the broken-down representation. In more concrete terms, the //. assemble method builds the string representation from the string //. representations of the contained {\tt DwHeaders} and {\tt DwBody} //. objects. This member function calls the {\tt Assemble()} member //. functions of its {\tt DwHeaders} and {\tt DwBody} objects. //. //. You should call this member function after you modify either the //. contained headers or body, and before you retrieve the string //. representation. //. //. This function clears the is-modified flag. bool hasHeaders() const { return 0 != mHeaders; } DwHeaders& Headers() const; //. This function returns the {\tt DwHeaders} object contained by //. this object. DwBody& Body() const; //. This function returns the {\tt DwBody} object contained by this object. int BodySize() const; //. Get the size of the Body void SetBodySize( int size ) { mBodySize = size; } //. Explicitly set the size of the Body //. This is needed if the body is empty but you know the size and others //. should be able to access it protected: DwHeaders* mHeaders; DwBody* mBody; private: static const char* const sClassName; int mBodySize; // normally mBody->AsString().length() public: virtual void PrintDebugInfo(std::ostream& aStrm, int aDepth=0) const; //. This virtual function, inherited from {\tt DwMessageComponent}, //. prints debugging information about this object to {\tt aStrm}. //. It will also call {\tt PrintDebugInfo()} for any of its child //. components down to a level of {\tt aDepth}. //. //. This member function is available only in the debug version of //. the library. virtual void CheckInvariants() const; //. Aborts if one of the invariants of the object fails. Use this //. member function to track down bugs. //. //. This member function is available only in the debug version of //. the library. protected: void _PrintDebugInfo(std::ostream& aStrm) const; }; #endif mimelib1-1.1.4/mimelib/mimelib/msgid.h0000644000175000017500000001570711175345261017143 0ustar resivoresivo//============================================================================= // File: msgid.h // Contents: Declarations for DwMsgId // Maintainer: Doug Sauder // WWW: http://www.fwb.gulf.net/~dwsauder/mimepp.html // // Copyright (c) 1996, 1997 Douglas W. Sauder // All rights reserved. // // IN NO EVENT SHALL DOUGLAS W. SAUDER BE LIABLE TO ANY PARTY FOR DIRECT, // INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF // THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF DOUGLAS W. SAUDER // HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // DOUGLAS W. SAUDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT // NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A // PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" // BASIS, AND DOUGLAS W. SAUDER HAS NO OBLIGATION TO PROVIDE MAINTENANCE, // SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. // //============================================================================= #ifndef DW_MSGID_H #define DW_MSGID_H #ifndef DW_CONFIG_H #include #endif #ifndef DW_FIELDBDY_H #include #endif //============================================================================= //+ Name DwMsgId -- Class representing an RFC-822 msg-id //+ Description //. {\tt DwMsgId} represents a {\it msg-id} as described in RFC-822. In //. the BNF grammar in RFC-822, a msg-id has a {\it local-part} and a //. {\it domain}. In MIME++, a {\tt DwMsgId} contains strings that //. contain the local-part and the domain. //. //. In the tree (broken-down) representation of message, a {\tt DwMsgId} //. object may only be a leaf node, having a parent but no child nodes. //. Its parent node must be a {\tt DwField} object. //. //. {\tt DwMsgId} has member functions for getting or setting its local-part //. and its domain. You can have the library to create the contents of a //. {\tt DwMsgId} object for you by calling the member function //. {\tt CreateDefault()}. //============================================================================= // Last modified 1997-07-28 //+ Noentry ~DwMsgId mLocalPart mDomain sClassName _PrintDebugInfo class DW_EXPORT DwMsgId : public DwFieldBody { public: DwMsgId(); DwMsgId(const DwMsgId& aMsgId); DwMsgId(const DwString& aStr, DwMessageComponent* aParent=0); //. The first constructor is the default constructor, which sets the //. {\tt DwMsgId} object's string representation to the empty string //. and sets its parent to NULL. //. //. The second constructor is the copy constructor, which performs //. a deep copy of {\tt aMsgId}. //. The parent of the new {\tt DwMsgId} object is set to NULL. //. //. The third constructor copies {\tt aStr} to the {\tt DwMsgId} //. object's string representation and sets {\tt aParent} as its parent. //. The virtual member function {\tt Parse()} should be called immediately //. after this constructor in order to parse the string representation. //. Unless it is NULL, {\tt aParent} should point to an object of a class //. derived from {\tt DwField}. virtual ~DwMsgId(); const DwMsgId& operator = (const DwMsgId& aMsgId); //. This is the assignment operator, which performs a deep copy of //. {\tt aMsgId}. The parent node of the {\tt DwMsgId} object //. is not changed. virtual void Parse(); //. This virtual function, inherited from {\tt DwMessageComponent}, //. executes the parse method for {\tt DwMsgId} objects. The parse //. method parses the local-part and the domain from the string //. representation. //. //. You should call this member function after you set or modify the //. string representation, and before you retrieve local-part or //. domain. //. //. This function clears the is-modified flag. virtual void Assemble(); //. This virtual function, inherited from {\tt DwMessageComponent}, //. executes the assemble method for {\tt DwMsgId} objects. The //. assemble method creates or updates the string representation //. from the local-part and the domain. //. //. You should call this member function after you modify the //. local-part or the domain, and before you retrieve the string //. representation. //. //. This function clears the is-modified flag. virtual DwMessageComponent* Clone() const; //. This virtual function, inherited from {\tt DwMessageComponent}, //. creates a new {\tt DwMsgId} on the free store that has the same //. value as this {\tt DwMsgId} object. The basic idea is that of //. a ``virtual copy constructor.'' virtual void CreateDefault(); //. Creates a value for the msg-id. Uses the current time, //. process id, and fully qualified domain name for the host. const DwString& LocalPart() const; //. Returns the local-part of the msg-id. void SetLocalPart(const DwString& aLocalPart); //. Sets the local-part of the msg-id. const DwString& Domain() const; //. Returns the domain of the msg-id. void SetDomain(const DwString& aDomain); //. Sets the domain of the msg-id. static DwMsgId* NewMsgId(const DwString& aStr, DwMessageComponent* aParent); //. Creates a new {\tt DwMsgId} object on the free store. //. If the static data member {\tt sNewMsgId} is NULL, //. this member function will create a new {\tt DwMsgId} //. and return it. Otherwise, {\tt NewMsgId()} will call //. the user-supplied function pointed to by {\tt sNewMsgId}, //. which is assumed to return an object from a class derived from //. {\tt DwMsgId}, and return that object. //+ Var sNewMsgId static DwMsgId* (*sNewMsgId)(const DwString&, DwMessageComponent*); //. If {\tt sNewMsgId} is not NULL, it is assumed to point to a //. user-supplied function that returns an object from a class derived from //. {\tt DwMsgId}. static const char* sHostName; //. Host name of machine, used to create msg-id string. This data member //. is ignored if the platform supports a gethostname() function call. private: DwString mLocalPart; DwString mDomain; static const char* const sClassName; public: virtual void PrintDebugInfo(std::ostream& aStrm, int aDepth=0) const; //. This virtual function, inherited from {\tt DwMessageComponent}, //. prints debugging information about this object to {\tt aStrm}. //. It will also call {\tt PrintDebugInfo()} for any of its child //. components down to a level of {\tt aDepth}. //. //. This member function is available only in the debug version of //. the library. virtual void CheckInvariants() const; //. Aborts if one of the invariants of the object fails. Use this //. member function to track down bugs. //. //. This member function is available only in the debug version of //. the library. protected: void _PrintDebugInfo(std::ostream& aStrm) const; }; #endif mimelib1-1.1.4/mimelib/mimelib/nntp.h0000644000175000017500000004403711175345261017015 0ustar resivoresivo//============================================================================= // File: nntp.h // Contents: Declarations for DwNntpClient // Maintainer: Doug Sauder // WWW: http://www.fwb.gulf.net/~dwsauder/mimepp.html // // Copyright (c) 1996, 1997 Douglas W. Sauder // All rights reserved. // // IN NO EVENT SHALL DOUGLAS W. SAUDER BE LIABLE TO ANY PARTY FOR DIRECT, // INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF // THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF DOUGLAS W. SAUDER // HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // DOUGLAS W. SAUDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT // NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A // PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" // BASIS, AND DOUGLAS W. SAUDER HAS NO OBLIGATION TO PROVIDE MAINTENANCE, // SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. // //============================================================================= #ifndef DW_NNTP_H #define DW_NNTP_H #include #ifndef DW_CONFIG_H #include #endif #ifndef DW_PROTOCOL_H #include #endif #ifndef DW_STRING_H #include #endif //============================================================================= //+ Name DwNntpClient -- Class for handling the client side of an NNTP session //+ Description //. {\tt DwNntpClient} is a class that handles the client side of an NNTP //. session. Specifically, {\tt DwNntpClient} provides facilities for //. opening a connection to an NNTP server, sending commands and data to //. the server, receiving responses and data from the server, and closing //. the connection. The protocol implemented is the Network News Transport //. Protocol, as specified in RFC-977. //. //. {\tt DwNntpClient} is derived from {\tt DwProtocolClient}. For information //. about inherited member functions, especially member functions for detecting //. failures or errors, see the man page for {\tt DwProtocolClient}. //. //. In an NNTP session, the client sends commands to the server and receives //. responses from the server. A client command consists of a command word //. and zero or more argument words. A server response consists of a status //. line and possibly some additional lines of text. The status line consists //. of a three-digit numeric reply code followed by additional information. //. The reply code indicates a success or failure condition. In some cases, //. the server sends lines of text immediately after the status line. //. {\tt DwNntpClient} provides facilities for you to send commands to the //. server and receive responses from the server. //. //. {\tt DwNntpClient} has only a default constructor. On Win32 platforms, //. it is possible for the constructor to fail. (It calls WSAStartup().) //. You should verify that the constructor succeeded by calling the inherited //. member function {\tt DwProtocolClient::LastError()} and checking for a zero //. return value. //. //. To open a connection to the server, call the member function {\tt Open()} //. with the name of the server as an argument. {\tt Open()} accepts an //. optional argument that specifies the TCP port that the server listens to. //. The default port is the standard NNTP port (119). {\tt Open()} may fail, //. so you should check the return value to verify that it succeeded. To //. close the connection, call the inherited member function //. {\tt DwProtocolClient::Close()}. To check if a connection is open, call //. the inherited member function {\tt DwProtocolClient::IsOpen()}. //. {\tt IsOpen()} returns a boolean value that indicates whether or not //. a call to {\tt Open()} was successful; it will not detect failure in //. the network or a close operation by the remote host. //. //. For each NNTP command, {\tt DwNntpClient} has a member function that sends //. that command and receives the server's response. If the command takes any //. arguments, then those arguments are passed as function arguments to the //. command function. The command functions return the numeric value of the //. three-digit reply code returned by the server. Your program must check //. the reply code to determine whether or not the command was accepted and //. performed by the server. //. In some cases, because of a communications error or some other error, //. it is not possible for the command function to send the command or //. receive the response. When this happens, the command function will //. return 0. You can determine the precise error or failure by calling //. the inherited member functions {\tt DwProtocolClient::LastError()} or //. {\tt DwProtocolClient::LastFailure()}. //. //. After each command is sent, {\tt DwNntpClient} receives the server's //. response and remembers it. The member function {\tt ReplyCode()} //. returns the numeric value of the reply code received in response to //. the last command. {\tt StatusResponse()} returns the entire status //. response from the server, including the reply code. If no status //. response is received, possibly because of a communications error //. or failure, {\tt ReplyCode()} returns zero and {\tt StatusResponse()} //. returns an empty string. //. //. The server sends a status response, including a reply code, for all //. all NNTP commands. For some commands, such as when the client requests //. an article body, the server sends a multi-line text response immediately //. following the status response. Multi-line text responses //. can be received in either of two ways. The simplest way is to call the //. member function {\tt TextResponse()} after a command completes //. successfully. This simple method works fine for non-interactive //. applications. It can be a problem in interactive applications, however, //. because there is no data to display to a user until the entire text //. response is retrieved. An alternative method allows your program to //. retrieve the text response one line at a time as it is received. //. To use this method, you must define a subclass of {\tt DwObserver} //. and assign an object of that class to the {\tt DwNntpClient} object //. using the member function {\tt SetObserver()}. {\tt DwObserver} is an //. abstract class, declared in protocol.h, that has just one pure virtual //. member function {\tt Notify()}. After each line of the text response //. is received, {\tt DwNntpClient} will call the {\tt Notify()} member //. function of its assigned {\tt DwObserver} object. Each invocation of //. {\tt Notify()} should call the {\tt DwNntpClient} member function //. {\tt TextResponse()} to retrieve the next line of the text response. //. Note that you cannot use both of these methods at the same time: if //. an observer is assigned, {\tt TextResponse()} returns only the last //. line received, not the entire multi-line text response. //. //. Certain NNTP commands, such as the POST command, require the NNTP client //. to send multiple lines of text to the server. To perform this bulk data //. transfer, {\tt DwNntpClient} provides the member function //. {\tt SendData()}. In the current implementation, {\tt SendData()} does //. not convert end of line characters, so it is your responsibility to //. convert the end of line characters to CR LF, if necessary. (You may //. use the utility function {\tt DwToCrLfEol()} to do the conversion.) //. {\tt SendData()} will perform the character stuffing to protect '.' at //. the beginning of a line, and it will append the final [CR LF] '.' CR LF. //. It is possible to divide data and make multiple calls to {\tt SendData()}; //. however, if you do so, please note the following paragraph. //. //. Note: Because of a feature (some might say bug) in the current //. implementation, {\tt SendData()} will not detect a '.' at the beginning //. of a line if the CR LF '.' sequence is split between two calls to //. {\tt SendData()}. This problem will probably be resolved in a future //. version, but be aware that such a change will require a change in //. {\tt DwNntpClient}'s interface. //============================================================================= //+ Noentry ~DwNntpClient class DW_EXPORT DwNntpClient : public DwProtocolClient { friend class NNTP; friend class NNTPObserver; public: enum { kCmdNoCommand=0, kCmdArticle, kCmdBody, kCmdHead, kCmdStat, kCmdGroup, kCmdHelp, kCmdIhave, kCmdLast, kCmdList, kCmdNewgroups, kCmdNewnews, kCmdNext, kCmdPost, kCmdQuit, kCmdSlave }; DwNntpClient(); //. Initializes the {\tt DwNntpClient} object. //. It is possible for the constructor to fail. To verify that the //. constructor succeeded, call the member function {\tt LastError()} //. and check that it returns zero. (In the Win32 implementation, the //. constructor calls the Winsock function {\tt WSAStartup()}, which //. may fail.) virtual ~DwNntpClient(); virtual int Open(const char* aServer, DwUint16 aPort=119); //. Opens a TCP connection to the server {\tt aServer} at port {\tt aPort}. //. {\tt aServer} may be either a host name, such as "news.acme.com" or //. an IP number in dotted decimal format, such as "147.81.64.60". The //. default value for {\tt aPort} is 119, the well-known port for NNTP //. assigned by the Internet Assigned Numbers Authority (IANA). //. //. If the connection attempt succeeds, the server sends a response. //. {\tt Open()} returns the server's numeric reply code. The full //. response from the server can be retrieved by calling //. {\tt StatusResponse()}. //. //. If the connection attempt fails, {\tt Open()} returns 0. To determine //. what error occurred when a connection attempt fails, call the inherited //. member function {\tt DwProtocolClient::LastError()}. To determine if //. a failure also occurred, call the inherited member function //. {\tt DwProtocolClient::LastFailure()}. DwObserver* SetObserver(DwObserver* aObserver); //. Sets the observer object that interacts with the {\tt DwNntpClient} //. object to retrieve a multi-line text response. If an observer is set, //. {\tt DwNntpClient} will call the observer's {\tt Notify()} method //. after each line of the text response is received. To remove //. an observer, call {\tt SetObserver()} with a NULL argument. //. {\tt SetObserver()} returns the previously set observer, or NULL if //. no observer was previously set. int ReplyCode() const; //. Returns the numeric value of the three-digit reply code received //. from the server in response to the last client command. If no //. response was received, {\tt ReplyCode()} returns zero. const DwString& StatusResponse() const; //. Returns the entire status response last received from the server. //. If no response was received, perhaps because of a communications //. failure, {\tt StatusResponse()} returns an empty string. const DwString& TextResponse() const; //. If no observer is set for this object, {\tt TextResponse()} returns //. a string that comprises the entire sequence of lines received from //. the server. Otherwise, if an observer {\tt is} set for this object, //. {\tt TextResponse()} returns only the most recent line received. int Article(int aNumber=(-1)); int Article(const char* aMsgid); //. Sends the NNTP ARTICLE command and returns the reply code received //. from the server. If no response is received, the function returns //. zero. //. The optional argument {\tt aNumber} specifies the number of an //. article to retrieve. If {\tt Article()} is called with the default //. argument, the ARTICLE command is sent to the server with no argument. //. {\tt aMsgId} specifies the message id of an article to retrieve. int Body(int aNumber=(-1)); int Body(const char* aMsgid); //. Sends the NNTP BODY command and returns the reply code received //. from the server. If no response is received, the function returns //. zero. //. The optional argument {\tt aNumber} specifies the number of an //. article whose body should be retrieved. If {\tt Body()} is called //. with the default argument, the BODY command is sent to the server //. with no argument. {\tt aMsgId} specifies the message id of the //. article to access. int Head(int aNumber=(-1)); int Head(const char* aMsgid); //. Sends the NNTP HEAD command and returns the reply code received //. from the server. If no response is received, the function returns //. zero. //. The optional argument {\tt aNumber} specifies the number of an //. article whose header lines should be retrieved. If {\tt Head()} //. is called with the default argument, the HEAD command is sent to //. the server with no argument. {\tt aMsgId} specifies the message id //. of the article to access. int Stat(int aNumber=(-1)); int Stat(const char* aMsgid); //. Sends the NNTP STAT command and returns the reply code received //. from the server. If no response is received, the function returns //. zero. //. The optional argument {\tt aNumber} specifies the number of an //. article to access. If {\tt Stat()} is called with the default //. argument, the STAT command is sent to the server with no argument. //. {\tt aMsgId} specifies the message id of the article to access. int Group(const char* aNewsgroupName); //. Sends the NNTP GROUP command and returns the reply code received from //. the server. The argument {\tt aNewsgroupName} specifies the newgroup //. to be selected. If no response is received, the function returns zero. int Help(); //. Sends the NNTP HELP command and returns the reply code received from //. the server. If no response is received, the function returns zero. int Ihave(const char* aMsgId); //. Sends the NNTP IHAVE command and returns the reply code received from //. the server. {\tt aMsgId} specifies the message id of the article //. to be sent. If no response is received, the function returns zero. int Last(); //. Sends the NNTP LAST command and returns the reply code received from //. the server. If no response is received, the function returns zero. int List(); //. Sends the NNTP LIST command and returns the reply code received from //. the server. If no response is received, the function returns zero. int Newgroups(const char* aDate, const char* aTime, DwBool aIsGmt=DwFalse, const char* aDistributions=0); //. Sends the NNTP NEWGROUPS command and returns the reply code received //. from the server. If no response is received, the function returns //. zero. //. {\tt aDate} is the date in the form YYMMDD, where YY is the two //. digit year, MM is the month, and DD is the day of the month. //. {\tt aTime} is the time in the form HHMMSS, where HH is hours, //. MM is minutes, and SS is seconds. If {\tt aIsGmt} is true, //. the optional GMT argument will be sent. {\tt aDistributions} //. specifies the optional list of distribution groups. int Newnews(const char* aNewsgroups, const char* aDate, const char* aTime, DwBool aIsGmt=DwFalse, const char* aDistribution=0); //. Sends the NNTP NEWNEWS command and returns the reply code received //. from the server. If no response is received, the function returns //. zero. //. {\tt aNewsgroups} is the newsgroups argument for the command. //. {\tt aDate} is the date in the form YYMMDD, where YY is the two //. digit year, MM is the month, and DD is the day of the month. //. {\tt aTime} is the time in the form HHMMSS, where HH is hours, //. MM is minutes, and SS is seconds. If {\tt aIsGmt} is true, //. the optional GMT argument will be sent. {\tt aDistributions} //. specifies the optional list of distribution groups. int Next(); //. Sends the NNTP NEXT command and returns the reply code received from //. the server. If no response is received, perhaps because of an error, //. the function returns zero. int Post(); //. Sends the NNTP POST command and returns the reply code received from //. the server. If no response is received, perhaps because of an error, //. the function returns zero. int Quit(); //. Sends the NNTP QUIT command and returns the reply code received from //. the server. If no response is received, perhaps because of an error, //. the function returns zero. int Slave(); //. Sends the NNTP SLAVE command and returns the reply code received from //. the server. If no response is received, perhaps because of an error, //. the function returns zero. int SendData(const DwString& aStr); int SendData(const char* aBuf, int aBufLen); //. Sends bulk data to the server and returns the reply code received. //. A bulk data transfer follows a POST or IHAVE command and is used to //. send a complete article to the server. //. //. In the current implementation, {\tt SendData()} does not convert end //. of line characters, so it is your responsibility to convert the end //. of line characters to CR LF, if necessary. (You may use the utility //. function {\tt DwToCrLfEol()} to do the conversion.) {\tt SendData()} //. will perform the character stuffing to protect '.' at the beginning of //. a line, and it will append the final [CR LF] '.' CR LF. It is possible //. to divide the data and make multiple calls to {\tt SendData()}; however, //. this may cause problems in the current implementation if a CR LF '.' //. sequence is split between calls. private: char* mSendBuffer; char* mRecvBuffer; int mLastChar; int mLastLastChar; int mNumRecvBufferChars; int mRecvBufferPos; int mReplyCode; DwString mStatusResponse; DwString mTextResponse; DwObserver* mObserver; virtual int PGetLine(char** aPtr, int* aLen); virtual void PGetStatusResponse(); virtual void PGetTextResponse(); }; #endif mimelib1-1.1.4/mimelib/mimelib/mailbox.h0000644000175000017500000002065611175345261017472 0ustar resivoresivo//============================================================================= // File: mailbox.h // Contents: Declarations for DwMailbox // Maintainer: Doug Sauder // WWW: http://www.fwb.gulf.net/~dwsauder/mimepp.html // // Copyright (c) 1996, 1997 Douglas W. Sauder // All rights reserved. // // IN NO EVENT SHALL DOUGLAS W. SAUDER BE LIABLE TO ANY PARTY FOR DIRECT, // INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF // THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF DOUGLAS W. SAUDER // HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // DOUGLAS W. SAUDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT // NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A // PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" // BASIS, AND DOUGLAS W. SAUDER HAS NO OBLIGATION TO PROVIDE MAINTENANCE, // SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. // //============================================================================= #ifndef DW_MAILBOX_H #define DW_MAILBOX_H #ifndef DW_CONFIG_H #include #endif #ifndef DW_STRING_H #include #endif #ifndef DW_ADDRESS_H #include #endif //============================================================================= //+ Name DwMailbox -- Class representing an RFC-822 mailbox //+ Description //. RFC-822 defines a {\it mailbox} as an entity that can be the recipient //. of a message. A mailbox is more specific than an {\it address}, which //. may be either a mailbox or a {\it group}. An RFC-822 mailbox contains //. a full name, a {\it local-part}, an optional {\it route}, and a //. {\it domain}. For example, in the mailbox //. //. Joe Schmoe //. //. "Joe Schmoe" is the full name, "jschmoe" is the local-part, and //. "aol.com" is the domain. The optional route is rarely seen in current //. usage, and is deprecated according to RFC-1123. //. //. In MIME++, an RFC-822 mailbox is represented by a {\tt DwMailbox} object. //. {\tt DwMailbox} is a subclass of {\tt DwAddress}, which reflects the //. fact that a mailbox is also an address. A {\tt DwMailbox} contains //. strings representing the full name, local-part, route, and domain //. of a mailbox. //. //. In the tree (broken-down) representation of message, a {\tt DwMailbox} //. object may be only a leaf node, having a parent but no child nodes. //. Its parent node must be a {\tt DwField}, a {\tt DwAddressList}, or a //. {\tt DwMailboxList} object. //. //. {\tt DwMailbox} has member functions for getting or setting the strings //. it contains. //. //. {\tt DwMailbox} object can be included in a list of {\tt DwMailbox} //. objects. To get the next {\tt DwMailbox} object in a list, use the //. inherited member function {\tt DwAddress::Next()}. //============================================================================= // Last updated 1997-08-30 //+ Noentry ~DwMailbox //+ Noentry mFullName mRoute mLocalPart mDomain sClassName _PrintDebugInfo class DW_EXPORT DwMailbox : public DwAddress { friend class DwMailboxList; public: DwMailbox(); DwMailbox(const DwMailbox& aMailbox); DwMailbox(const DwString& aStr, DwMessageComponent* aParent=0); //. The first constructor is the default constructor, which sets the //. {\tt DwMailbox} object's string representation to the empty string //. and sets its parent to {\tt NULL}. //. //. The second constructor is the copy constructor, which performs //. a deep copy of {\tt aMailbox}. //. The parent of the new {\tt DwMailbox} is set to {\tt NULL}. //. //. The third constructor copies {\tt aStr} to the {\tt DwMailbox} //. object's string representation and sets {\tt aParent} as its parent. //. The virtual member function {\tt Parse()} should be called immediately //. after this constructor in order to parse the string representation. //. Unless it is {\tt NULL}, {\tt aParent} should point to an object of a class //. derived from {\tt DwField}. virtual ~DwMailbox(); const DwMailbox& operator = (const DwMailbox& aMailbox); //. This is the assignment operator, which performs a deep copy of //. {\tt aMailbox}. The parent node of the {\tt DwMailbox} object //. is not changed. virtual void Parse(); //. This virtual function, inherited from {\tt DwMessageComponent}, //. executes the parse method for {\tt DwMailbox} objects. The parse //. method creates or updates the broken-down representation from the //. string representation. For {\tt DwMailbox} objects, the parse //. method parses the string representation into the substrings for //. the full name, local-part, route, and domain. //. //. You should call this member function after you set or modify the //. string representation, and before you retrieve the full name, //. local-part, route, or domain. //. //. This function clears the is-modified flag. virtual void Assemble(); //. This virtual function, inherited from {\tt DwMessageComponent}, //. executes the assemble method for {\tt DwMailbox} objects. The //. assemble method creates or updates the string representation from //. the broken-down representation. For {\tt DwMailbox} objects, the //. assemble method builds the string representation from the full //. name, local-part, route, and domain strings. //. //. You should call this member function after you modify the full //. name, local-part, route, or domain, and before you retrieve the //. string representation. //. //. This function clears the is-modified flag. virtual DwMessageComponent* Clone() const; //. This virtual function, inherited from {\tt DwMessageComponent}, //. creates a new {\tt DwMailbox} on the free store that has the same //. value as this {\tt DwMailbox} object. The basic idea is that of //. a virtual copy constructor. const DwString& FullName() const; //. Returns the full name for this {\tt DwMailbox} object. void SetFullName(const DwString& aFullName); //. Sets the full name for this {\tt DwMailbox} object. const DwString& Route() const; //. Returns the route for this {\tt DwMailbox} object. void SetRoute(const DwString& aRoute); //. Sets the route for this {\tt DwMailbox} object. const DwString& LocalPart() const; //. Returns the local-part for this {\tt DwMailbox} object. void SetLocalPart(const DwString& aLocalPart); //. Sets the local-part for this {\tt DwMailbox} object. const DwString& Domain() const; //. Returns the domain for this {\tt DwMailbox} object. void SetDomain(const DwString& aDomain); //. Sets the domain for this {\tt DwMailbox} object. static DwMailbox* NewMailbox(const DwString& aStr, DwMessageComponent* aParent); //. Creates a new {\tt DwMailbox} object on the free store. //. If the static data member {\tt sNewMailbox} is {\tt NULL}, //. this member function will create a new {\tt DwMailbox} //. and return it. Otherwise, {\tt NewMailbox()} will call //. the user-supplied function pointed to by {\tt sNewMailbox}, //. which is assumed to return an object from a class derived from //. {\tt DwMailbox}, and return that object. //+ Var sNewMailbox static DwMailbox* (*sNewMailbox)(const DwString&, DwMessageComponent*); //. If {\tt sNewMailbox} is not {\tt NULL}, it is assumed to point to a //. user-supplied function that returns an object from a class derived //. from {\tt DwMailbox}. private: DwString mFullName; DwString mRoute; DwString mLocalPart; DwString mDomain; static const char* const sClassName; public: virtual void PrintDebugInfo(std::ostream& aStrm, int aDepth=0) const; //. This virtual function, inherited from {\tt DwMessageComponent}, //. prints debugging information about this object to {\tt aStrm}. //. It will also call {\tt PrintDebugInfo()} for any of its child //. components down to a level of {\tt aDepth}. //. //. This member function is available only in the debug version of //. the library. virtual void CheckInvariants() const; //. Aborts if one of the invariants of the object fails. Use this //. member function to track down bugs. //. //. This member function is available only in the debug version of //. the library. protected: void _PrintDebugInfo(std::ostream& aStrm) const; }; #endif mimelib1-1.1.4/mimelib/mimelib/utility.h0000644000175000017500000000424611175345261017537 0ustar resivoresivo//============================================================================= // File: utility.h // Contents: Declarations of utility functions for MIME++ // Maintainer: Doug Sauder // WWW: http://www.fwb.gulf.net/~dwsauder/mimepp.html // // Copyright (c) 1996, 1997 Douglas W. Sauder // All rights reserved. // // IN NO EVENT SHALL DOUGLAS W. SAUDER BE LIABLE TO ANY PARTY FOR DIRECT, // INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF // THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF DOUGLAS W. SAUDER // HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // DOUGLAS W. SAUDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT // NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A // PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" // BASIS, AND DOUGLAS W. SAUDER HAS NO OBLIGATION TO PROVIDE MAINTENANCE, // SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. // //============================================================================= #ifndef DW_UTILITY_H #define DW_UTILITY_H #ifndef DW_CONFIG_H #include #endif class DwString; void DW_EXPORT DwInitialize(); void DW_EXPORT DwFinalize(); int DW_EXPORT DwCteStrToEnum(const DwString& aStr); void DW_EXPORT DwCteEnumToStr(int aEnum, DwString& aStr); int DW_EXPORT DwTypeStrToEnum(const DwString& aStr); void DW_EXPORT DwTypeEnumToStr(int aEnum, DwString& aStr); int DW_EXPORT DwSubtypeStrToEnum(const DwString& aStr); void DW_EXPORT DwSubtypeEnumToStr(int aEnum, DwString& aStr); int DW_EXPORT DwToCrLfEol(const DwString& aSrcStr, DwString& aDestStr); int DW_EXPORT DwToLfEol(const DwString& aSrcStr, DwString& aDestStr); int DW_EXPORT DwToCrEol(const DwString& aSrcStr, DwString& aDestStr); int DW_EXPORT DwToLocalEol(const DwString& aSrcStr, DwString& aDestStr); int DW_EXPORT DwEncodeBase64(const DwString& aSrcStr, DwString& aDestStr); int DW_EXPORT DwDecodeBase64(const DwString& aSrcStr, DwString& aDestStr); int DW_EXPORT DwEncodeQuotedPrintable(const DwString& aSrcStr, DwString& aDestStr); int DW_EXPORT DwDecodeQuotedPrintable(const DwString& aSrcStr, DwString& aDestStr); #endif mimelib1-1.1.4/mimelib/mimelib/mechansm.h0000644000175000017500000001555611175345261017635 0ustar resivoresivo//============================================================================= // File: mechansm.h // Contents: Declarations for DwMechanism // Maintainer: Doug Sauder // WWW: http://www.fwb.gulf.net/~dwsauder/mimepp.html // // Copyright (c) 1996, 1997 Douglas W. Sauder // All rights reserved. // // IN NO EVENT SHALL DOUGLAS W. SAUDER BE LIABLE TO ANY PARTY FOR DIRECT, // INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF // THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF DOUGLAS W. SAUDER // HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // DOUGLAS W. SAUDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT // NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A // PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" // BASIS, AND DOUGLAS W. SAUDER HAS NO OBLIGATION TO PROVIDE MAINTENANCE, // SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. // //============================================================================= #ifndef DW_MECHANSM_H #define DW_MECHANSM_H #ifndef DW_CONFIG_H #include #endif #ifndef DW_STRING_H #include #endif #ifndef DW_FIELDBDY_H #include #endif //============================================================================= //+ Name DwMechanism -- Class representing a MIME content-transfer-encoding field-body //+ Description //. {\tt DwMechanism} represents a field body for the //. Content-Transfer-Encoding header field as described in RFC-2045. //. {\tt DwMechanism} provides convenience functions that allow you to //. set or get the content-transfer-encoding attribute as an enumerated //. value. //============================================================================= // Last updated 1997-08-30 //+ Noentry ~DwMechanism _PrintDebugInfo class DW_EXPORT DwMechanism : public DwFieldBody { public: DwMechanism(); DwMechanism(const DwMechanism& aCte); DwMechanism(const DwString& aStr, DwMessageComponent* aParent=0); //. The first constructor is the default constructor, which sets the //. {\tt DwMechanism} object's string representation to the empty //. string and sets its parent to {\tt NULL}. //. //. The second constructor is the copy constructor, which copies the //. string representation from {\tt aCte}. //. The parent of the new {\tt DwMechanism} object is set to {\tt NULL}. //. //. The third constructor copies {\tt aStr} to the {\tt DwMechanism} //. object's string representation and sets {\tt aParent} as its parent. //. The virtual member function {\tt Parse()} should be called immediately //. after this constructor in order to parse the string representation. //. Unless it is {\tt NULL}, {\tt aParent} should point to an object of //. a class derived from {\tt DwField}. virtual ~DwMechanism(); const DwMechanism& operator = (const DwMechanism& aCte); //. This is the assignment operator, which performs a deep copy of //. {\tt aCte}. The parent node of the {\tt DwMechanism} object //. is not changed. virtual void Parse(); //. This virtual function, inherited from {\tt DwMessageComponent}, //. executes the parse method for {\tt DwMechanism} objects. //. It should be called immediately after the string representation //. is modified and before any of the object's attributes are retrieved. //. //. This function clears the is-modified flag. virtual void Assemble(); //. This virtual function, inherited from {\tt DwMessageComponent}, //. executes the assemble method for {\tt DwMechanism} objects. //. It should be called whenever one of the object's attributes //. is changed in order to assemble the string representation. //. It will be called automatically for this object by the parent //. object's {\tt Assemble()} member function if the is-modified //. flag is set. //. //. This function clears the is-modified flag. virtual DwMessageComponent* Clone() const; //. This virtual function, inherited from {\tt DwMessageComponent}, //. creates a new {\tt DwMechanism} object on the free store that has //. the same value as this {\tt DwMechanism} object. The basic idea //. is that of a virtual copy constructor. int AsEnum() const; //. Returns the content transfer encoding as an enumerated value. //. Enumerated values are defined for all standard content transfer //. encodings in the file enum.h. If the content transfer encoding //. is non-standard {\tt DwMime::kCteUnknown} is returned. The //. inherited member function {\tt DwMessageComponent::AsString()} //. may be used to get the content transfer encoding, standard or //. non-standard, as a string. void FromEnum(int aCte); //. Sets the content transfer encoding from an enumerated value. //. Enumerated values are defined for all standard content transfer //. encodings in the file enum.h. You may set the content transfer //. encoding to any string value, standard or non-standard, by using the //. inherited member function {\tt DwMessageComponent::FromString()}. static DwMechanism* NewMechanism(const DwString& aStr, DwMessageComponent* aParent); //. Creates a new {\tt DwMechanism} object on the free store. //. If the static data member {\tt sNewMechanism} is {\tt NULL}, //. this member function will create a new {\tt DwMechanism} //. and return it. Otherwise, {\tt NewMechanism()} will call //. the user-supplied function pointed to by //. {\tt sNewMechanism}, which is assumed to return an //. object from a class derived from {\tt DwMechanism}, and //. return that object. //+ Var sNewMechanism static DwMechanism* (*sNewMechanism)(const DwString&, DwMessageComponent*); //. If {\tt sNewMechanism} is not {\tt NULL}, it is assumed //. to point to a user-supplied function that returns an object from //. a class derived from {\tt DwMechanism}. private: int mCteEnum; static const char* const sClassName; void EnumToString(); void StringToEnum(); public: virtual void PrintDebugInfo(std::ostream& aStrm, int aDepth=0) const; //. This virtual function, inherited from {\tt DwMessageComponent}, //. prints debugging information about this object to {\tt aStrm}. //. It will also call {\tt PrintDebugInfo()} for any of its child //. components down to a level of {\tt aDepth}. //. //. This member function is available only in the debug version of //. the library. virtual void CheckInvariants() const; //. Aborts if one of the invariants of the object fails. Use this //. member function to track down bugs. //. //. This member function is available only in the debug version of //. the library. protected: void _PrintDebugInfo(std::ostream& aStrm) const; }; #endif mimelib1-1.1.4/mimelib/mimelib/group.h0000644000175000017500000001765411175345261017177 0ustar resivoresivo//============================================================================= // File: group.h // Contents: Declarations for DwGroup // Maintainer: Doug Sauder // WWW: http://www.fwb.gulf.net/~dwsauder/mimepp.html // // Copyright (c) 1996, 1997 Douglas W. Sauder // All rights reserved. // // IN NO EVENT SHALL DOUGLAS W. SAUDER BE LIABLE TO ANY PARTY FOR DIRECT, // INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF // THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF DOUGLAS W. SAUDER // HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // DOUGLAS W. SAUDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT // NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A // PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" // BASIS, AND DOUGLAS W. SAUDER HAS NO OBLIGATION TO PROVIDE MAINTENANCE, // SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. // //============================================================================= #ifndef DW_GROUP_H #define DW_GROUP_H #ifndef DW_CONFIG_H #include #endif #ifndef DW_STRING_H #include #endif #ifndef DW_MAILBOX_H #include #endif #ifndef DW_MBOXLIST_H #include #endif #ifndef DW_ADDRESS_H #include #endif //============================================================================= //+ Name DwGroup -- Class representing an RFC-822 address group //+ Description //. {\tt DwGroup} represents a {\it group} as described in RFC-822. A group //. contains a group name and a (possibly empty) list of {\it mailboxes}. //. In MIME++, a {\tt DwGroup} object contains a string for the group name //. and a {\tt DwMailboxList} object for the list of mailboxes. //. //. In the tree (broken-down) representation of message, a {\tt DwGroup} //. object may be only an intermediate node, having both a parent and a single //. child node. Its parent node must be a {\tt DwField} or a //. {\tt DwAddressList}. Its child is a {\tt DwMailboxList}. //. //. A {\tt DwGroup} is a {\tt DwAddress}, and therefore it can be included //. in a list of {\tt DwAddress} objects. To get the next {\tt DwAddress} //. object in a list, use the inherited member function //. {\tt DwAddress::Next()}. //============================================================================= // Last updated 1997-08-24 //+ Noentry ~DwGroup _PrintDebugInfo class DW_EXPORT DwGroup : public DwAddress { public: DwGroup(); DwGroup(const DwGroup& aGroup); DwGroup(const DwString& aStr, DwMessageComponent* aParent=0); //. The first constructor is the default constructor, which sets the //. {\tt DwGroup} object's string representation to the empty string //. and sets its parent to {\tt NULL}. //. //. The second constructor is the copy constructor, which performs //. a deep copy of {\tt aGroup}. //. The parent of the new {\tt DwGroup} object is set to {\tt NULL}. //. //. The third constructor copies {\tt aStr} to the {\tt DwGroup} //. object's string representation and sets {\tt aParent} as its parent. //. The virtual member function {\tt Parse()} should be called immediately //. after this constructor in order to parse the string representation. //. Unless it is {\tt NULL}, {\tt aParent} should point to an object of //. a class derived from {\tt DwField} or {\tt DwAddressList}. virtual ~DwGroup(); const DwGroup& operator = (const DwGroup& aGroup); //. This is the assignment operator, which performs a deep copy of //. {\tt aGroup}. The parent node of the {\tt DwGroup} object //. is not changed. virtual void Parse(); //. This virtual function, inherited from {\tt DwMessageComponent}, //. executes the parse method for {\tt DwGroup} objects. The parse //. method creates or updates the broken-down representation from the //. string representation. For {\tt DwGroup} objects, the parse method //. parses the string representation to extract the group name and to //. create a {\tt DwMailboxList} object from the list of mailboxes. This //. member function also calls the {\tt Parse()} member function of //. the {\tt DwMailboxList} object it creates. //. //. You should call this member function after you set or modify the //. string representation, and before you access the group name or the //. mailbox list. //. //. This function clears the is-modified flag. virtual void Assemble(); //. This virtual function, inherited from {\tt DwMessageComponent}, //. executes the assemble method for {\tt DwGroup} objects. The //. assemble method creates or updates the string representation from //. the broken-down representation. That is, the assemble method //. builds the string representation from its group name and mailbox //. list. Before it builds the string representation, this function //. calls the {\tt Assemble()} member function of its contained //. {\tt DwMailboxList} object. //. //. You should call this member function after you set or modify either //. the group name or the contained {\tt DwMailboxList} object, and //. before you retrieve the string representation. //. //. This function clears the is-modified flag. virtual DwMessageComponent* Clone() const; //. This virtual function, inherited from {\tt DwMessageComponent}, //. creates a new {\tt DwGroup} on the free store that has the same //. value as this {\tt DwGroup} object. The basic idea is that of //. a virtual copy constructor. const DwString& GroupName() const; //. Returns the name of the group. const DwString& Phrase() const; //. Returns the name of the phrase part of a group as described in //. RFC-822. The phrase is the same as the group name. void SetGroupName(const DwString& aName); //. Sets the name of the group. void SetPhrase(const DwString& aPhrase); //. Sets the name of the phrase part of a group as described in RFC-822. //. The phrase is the same as the group name. DwMailboxList& MailboxList() const; //. Provides access to the list of mailboxes that is part of a group as //. described in RFC-822. static DwGroup* NewGroup(const DwString& aStr, DwMessageComponent* aParent); //. Creates a new {\tt DwGroup} object on the free store. //. If the static data member {\tt sNewGroup} is {\tt NULL}, //. this member function will create a new {\tt DwGroup} //. and return it. Otherwise, {\tt NewGroup()} will call //. the user-supplied function pointed to by {\tt sNewGroup}, //. which is assumed to return an object from a class derived from //. {\tt DwGroup}, and return that object. //+ Var sNewGroup static DwGroup* (*sNewGroup)(const DwString&, DwMessageComponent*); //. If {\tt sNewGroup} is not {\tt NULL}, it is assumed to point to a //. user-supplied function that returns an object from a class derived from //. {\tt DwGroup}. protected: DwMailboxList* mMailboxList; //. Points to the {\tt DwMailboxList} object. private: DwString mGroupName; static const char* const sClassName; public: virtual void PrintDebugInfo(std::ostream& aStrm, int aDepth=0) const; //. This virtual function, inherited from {\tt DwMessageComponent}, //. prints debugging information about this object to {\tt aStrm}. //. It will also call {\tt PrintDebugInfo()} for any of its child //. components down to a level of {\tt aDepth}. //. //. This member function is available only in the debug version of //. the library. virtual void CheckInvariants() const; //. Aborts if one of the invariants of the object fails. Use this //. member function to track down bugs. //. //. This member function is available only in the debug version of //. the library. protected: void _PrintDebugInfo(std::ostream& aStrm) const; }; #endif mimelib1-1.1.4/mimelib/mimelib/addrlist.h0000644000175000017500000002130511175345261017635 0ustar resivoresivo//============================================================================= // File: addrlist.h // Contents: Declarations for DwAddressList // Maintainer: Doug Sauder // WWW: http://www.fwb.gulf.net/~dwsauder/mimepp.html // // Copyright (c) 1996, 1997 Douglas W. Sauder // All rights reserved. // // IN NO EVENT SHALL DOUGLAS W. SAUDER BE LIABLE TO ANY PARTY FOR DIRECT, // INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF // THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF DOUGLAS W. SAUDER // HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // DOUGLAS W. SAUDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT // NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A // PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" // BASIS, AND DOUGLAS W. SAUDER HAS NO OBLIGATION TO PROVIDE MAINTENANCE, // SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. // //============================================================================= #ifndef DW_ADDRLIST_H #define DW_ADDRLIST_H #ifndef DW_CONFIG_H #include #endif //============================================================================= //+ Name DwAddressList -- Class representing a list of RFC-822 addresses //+ Description //. {\tt DwAddressList} represents a list of {\it addresses} as described //. in RFC-822. In MIME++, {\tt DwAddressList} is a container for objects //. of type {\tt DwAddress}, and it contains various member functions //. to manage its contained objects. {\tt DwAddressList} is also a //. {\tt DwFieldBody}. This reflects the fact that certain RFC-822 header //. fields, such as the ``To'' header field, have a list of addresses //. as their field bodies. //============================================================================= // Last modified 1997-08-23 //+ Noentry ~DwAddressList sClassName CopyList _PrintDebugInfo class DW_EXPORT DwAddressList : public DwFieldBody { public: DwAddressList(); DwAddressList(const DwAddressList& aList); DwAddressList(const DwString& aStr, DwMessageComponent* aParent=0); //. The first constructor is the default constructor, which sets the //. {\tt DwAddressList} object's string representation to the empty string //. and sets its parent to {\tt NULL}. //. //. The second constructor is the copy constructor, which copies the //. string representation and all {\tt DwAddress} objects from {\tt aList}. //. The parent of the new {\tt DwAddressList} object is set to {\tt NULL}. //. //. The third constructor copies {\tt aStr} to the {\tt DwAddressList} //. object's string representation and sets {\tt aParent} as its parent. //. The virtual member function {\tt Parse()} should be called immediately //. after this constructor in order to parse the string representation. //. Unless it is {\tt NULL}, {\tt aParent} should point to an object of //. a class derived from {\tt DwField}. virtual ~DwAddressList(); const DwAddressList& operator = (const DwAddressList& aList); //. This is the assignment operator, which performs a deep copy of //. {\tt aList}. The parent node of the {\tt DwAddressList} object //. is not changed. virtual void Parse(); //. This virtual function, inherited from {\tt DwMessageComponent}, //. executes the parse method for {\tt DwAddressList} objects. The parse //. method creates or updates the broken-down representation from the //. string representation. For {\tt DwAddressList} objects, the parse //. method parses the string representation to create a list of //. {\tt DwAddress} objects. This member function also calls the //. {\tt Parse()} member function of each {\tt DwAddress} object in //. its list. //. //. You should call this member function after you set or modify the //. string representation, and before you access any of the contained //. {\tt DwAddress} objects. //. //. This function clears the is-modified flag. virtual void Assemble(); //. This virtual function, inherited from {\tt DwMessageComponent}, //. executes the assemble method for {\tt DwAddressList} objects. The //. assemble method creates or updates the string representation from //. the broken-down representation. That is, the assemble method //. builds the string representation from its list of {\tt DwAddress} //. objects. Before it builds the string representation for the //. {\tt DwAddressList} object, this function first calls the //. {\tt Assemble()} member function of each {\tt DwAddress} object //. in its list. //. //. You should call this member function after you set or modify any //. of the contained {\tt DwAddress} objects, and before you retrieve //. the string representation. //. //. This function clears the is-modified flag. virtual DwMessageComponent* Clone() const; //. This virtual function, inherited from {\tt DwMessageComponent}, //. creates a new {\tt DwAddressList} on the free store that has the same //. value as this {\tt DwAddressList} object. The basic idea is that of //. a virtual copy constructor. DwAddress* FirstAddress() const; //. Gets the first {\tt DwAddress} object in the list. //. Use the member function {\tt DwAddress::Next()} to iterate. //. Returns {\tt NULL} if the list is empty. void Add(DwAddress* aAddr); //. Adds {\tt aAddr} to the end of the list of {\tt DwAddress} objects //. maintained by this {\tt DwAddressList} object. void Remove(DwAddress* aAddr); //. Removes {\tt aAddr} from the list of {\tt DwAddress} objects //. maintained by this {\tt DwAddressList} object. The {\tt DwAddress} //. object is not deleted by this member function. void DeleteAll(); //. Removes and deletes all {\tt DwAddress} objects from the list //. maintained by this {\tt DwAddressList} object. static DwAddressList* NewAddressList(const DwString& aStr, DwMessageComponent* aParent); //. Creates a new {\tt DwAddressList} object on the free store. //. If the static data member {\tt sNewAddressList} is {\tt NULL}, //. this member function will create a new {\tt DwAddressList} //. and return it. Otherwise, {\tt NewAddressList()} will call //. the user-supplied function pointed to by {\tt sNewAddressList}, //. which is assumed to return an object from a class derived from //. {\tt DwAddressList}, and return that object. //+ Var sNewAddressList static DwAddressList* (*sNewAddressList)(const DwString&, DwMessageComponent*); //. If {\tt sNewAddressList} is not {\tt NULL}, it is assumed to point //. to a user-supplied function that returns a pointer to an object //. from a class derived from {\tt DwAddressList}. protected: DwAddress* mFirstAddress; //. Points to first {\tt DwMailbox} object in list. private: static const char* const sClassName; void CopyList(const DwAddress* aFirstAddr); public: virtual void PrintDebugInfo(std::ostream& aStrm, int aDepth=0) const; //. This virtual function, inherited from {\tt DwMessageComponent}, //. prints debugging information about this object to {\tt aStrm}. //. It will also call {\tt PrintDebugInfo()} for any of its child //. components down to a level of {\tt aDepth}. //. //. This member function is available only in the debug version of //. the library. virtual void CheckInvariants() const; //. Aborts if one of the invariants of the object fails. Use this //. member function to track down bugs. //. //. This member function is available only in the debug version of //. the library. protected: void _PrintDebugInfo(std::ostream& aStrm) const; }; class DW_EXPORT DwAddressListParser { public: enum { eAddrError, eAddrGroup, eAddrMailbox, eAddrNull, eAddrEnd }; DwAddressListParser(const DwString& aStr); virtual ~DwAddressListParser(); const DwString& AddrString() { return mAddrString.Tokens(); } int AddrType() { return mAddrType; } int IsGroup() { return (mAddrType == eAddrGroup) ? 1 : 0; } int IsMailbox() { return (mAddrType == eAddrMailbox) ? 1 : 0; } int IsNull() { return (mAddrType == eAddrNull) ? 1 : 0; } int IsEnd() { return (mAddrType == eAddrEnd) ? 1 : 0; } int Restart(); int operator ++ (); // prefix increment operator protected: void ParseNextAddress(); DwRfc822Tokenizer mTokenizer; DwTokenString mAddrString; int mAddrType; private: DwAddressListParser(); DwAddressListParser(const DwAddressListParser&); const DwAddressListParser& operator = (const DwAddressListParser&); }; #endif mimelib1-1.1.4/mimelib/mimelib/protocol.h0000644000175000017500000002661411175345261017700 0ustar resivoresivo//============================================================================= // File: proto_un.h // Contents: Declarations for DwClientProtocol // Maintainer: Doug Sauder // WWW: http://www.fwb.gulf.net/~dwsauder/mimepp.html // // Copyright (c) 1996, 1997 Douglas W. Sauder // All rights reserved. // // IN NO EVENT SHALL DOUGLAS W. SAUDER BE LIABLE TO ANY PARTY FOR DIRECT, // INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF // THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF DOUGLAS W. SAUDER // HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // DOUGLAS W. SAUDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT // NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A // PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" // BASIS, AND DOUGLAS W. SAUDER HAS NO OBLIGATION TO PROVIDE MAINTENANCE, // SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. // //============================================================================= #ifndef DW_PROTOCOL_H #define DW_PROTOCOL_H #include #include #include #ifndef DW_CONFIG_H #include #endif #ifndef DW_STRING_H #include #endif class DwObserver { public: virtual ~DwObserver(){} virtual void Notify()=0; }; //============================================================================= //+ Name DwProtocolClient -- Base class for all protocol clients //+ Description //. {\tt DwProtocolClient} is the base class for other classes that implement //. specific protocols, such as SMTP, POP, and NNTP. {\tt DwProtocolClient} //. serves two purposes. First, It combines operations common to all its //. derived classes, such as opening a TCP connection to the server. Second, //. it provides a platform-independent interface to the network services //. required by its subclasses. //. //. There are two separate implementations of {\tt DwProtocolClient}: one for //. Berkeley sockets under UNIX, and one for Winsock under Win32. The //. interface is the same for both implementations, thus providing platform //. independence. //. //. There are two platform-specific details that you should be aware of. //. First, if you are writing a UNIX program, you should be sure to handle //. the SIGPIPE signal. This signal is raised when a program tries to write //. to a TCP connection that was shutdown by the remote host. The default //. action for this signal is to terminate the program. To prevent this //. from happening in your program, you should either catch the signal or //. tell the operating system to ignore it. Second, if you are writing a //. Win32 application for Windows NT or Windows95, you should be aware of //. the fact that the constructor calls the Winsock function //. {\tt WSAStartup()} to initialize the Winsock DLL. (The destructor //. calls {\tt WSACleanup()}.) Because it is possible for {\tt WSAStartup()} //. to fail, it is also possible that the constructor may fail. To verify //. that the constructor has succeeded, call the member function //. {\tt LastError()} and check that it returns zero. //. //. To open a connection to a server, call {\tt Open()} with the server name //. and TCP port number as arguments. {\tt Open()} is declared virtual; //. derived classes may override this member function. {\tt Open()} may fail, //. so you should check the return value to verify that it succeeded. To close //. the connection, call {\tt Close()}. To check if a connection is open, //. call {\tt IsOpen()}. {\tt IsOpen()} returns a value that indicates whether //. or not a call to {\tt Open()} was successful; it will not detect failure //. in the network or a close operation by the remote host. //. //. {\tt DwProtocolClient} sets a timeout on receive operations on the TCP //. connection. The default value of the timeout period is 90 seconds. To //. change the default value, call {\tt SetReceiveTimeout()} and pass the //. new value as an argument. //. //. Whenever {\tt DwProtocolClient} cannot complete an operation, it is because //. an error has occurred. Most member functions indicate that an error has //. occurred via their return values. For most member functions, a return //. value of -1 indicates an error. To get the specific error that has //. occurred, call {\tt LastError()}, which returns either the system error //. code or a MIME++ defined error code. To get a text string that describes //. the error, call {\tt LastErrorStr()}. //. //. Some errors are also considered "failures." A failure occurs when an //. operation cannot be completed because of conditions external to the //. program. For example, a failure occurs when the network is down or //. when an application's user enters bad input. Errors that occur because //. of programmer error are not considered failures. If an error occurs, //. you should call {\tt LastError()} to determine the error, but you should //. also call {\tt LastFailure()} to determine if a failure occurred. In //. interactive applications, failures should always be reported to the //. application's user. To get a text string that describes a failure, //. call {\tt LastFailureStr()}. //. //. It is possible to translate the error and failure message strings to a //. language other than English. To do this, you may override the virtual //. function {\tt HandleError()}. //============================================================================= //+ Noentry mFailureCode mFailureStr mErrorCode mErrorStr mLastCommand //+ Noentry mIsDllOpen mIsOpen mSocket mPort mServerName mReceiveTimeout class DW_EXPORT DwProtocolClient { public: enum Failure { kFailNoFailure = 0, // No failure kFailNoWinsock = 1, // A usable Winsock DLL could not be found kFailNetDown = 2, // The network is down kFailHostNotFound = 3, // The server was not found kFailConnReset = 4, // The connection was reset kFailNetUnreachable = 5, // The network is unreachable kFailTimedOut = 6, // Timed out while waiting for an operation // to complete kFailConnDropped = 7, kFailConnRefused = 8, kFailNoResources = 9 }; //. Enumerated values for failures. enum Error { kErrNoError = 0, kErrUnknownError = 0x4000, kErrBadParameter = 0x4001, kErrBadUsage = 0x4002, kErrNoWinsock = 0x4003, // Win32 kErrHostNotFound = 0x5000, // UNIX kErrTryAgain = 0x5001, // UNIX kErrNoRecovery = 0x5002, // UNIX kErrNoData = 0x5003, // UNIX kErrNoAddress = 0x5004 // UNIX }; //. MIME++-defined error codes. protected: DwProtocolClient(); //. Initializes the {\tt DwProtocolClient} object. //. In a Win32 environment, this constructor calls {\tt WSAStartup()} //. to initialize the Winsock DLL. To verify that the DLL was initialized //. successfully, call the member function {\tt LastError()} and verify //. that it returns zero. public: virtual ~DwProtocolClient(); //. Frees the resources used by this object. //. In a Win32 environment, the destructor calls {\tt WSACleanup()}. virtual int Open(const char* aServer, DwUint16 aPort); //. Opens a TCP connection to the server {\tt aServer} at port {\tt aPort}. //. {\tt aServer} may be either a host name, such as "smtp.acme.com" or an //. IP number in dotted decimal format, such as "147.81.64.59". If the //. connection attempt succeeds, {\tt Open()} returns 0; othewise, it //. returns -1. To determine what error occurred when the connection //. attempt fails, call the member function {\tt LastError()}. To //. determine if a failure also occurred, call the member function //. {\tt LastFailure()}. DwBool IsOpen() const; //. Returns true value if a connection to the server is open. //. {\tt IsOpen()} will return a true value if a call to {\tt Open()} was //. successful; it will not detect failure in the network or a close //. operation by the remote host. int Close(); //. Closes the connection to the server. Returns 0 if successful, or //. returns -1 if unsuccessful. int SetReceiveTimeout(int aSecs); //. Changes the default timeout for receive operations on the socket to //. {\tt aSecs} seconds. //. The default value is 90 seconds. int LastCommand() const; //. Returns an enumerated value indicating the last command sent to //. the server. Enumerated values are defined in subclasses of //. {\tt DwProtocolClient}. int LastFailure() const; //. Returns an enumerated value indicating what failure last occurred. const char* LastFailureStr() const; //. Returns a failure message string associated with the failure code //. returned by {\tt LastFailure()}. int LastError() const; //. Returns an error code for the last error that occurred. Normally, the //. error code returned is an error code returned by a system call; //. {\tt DwProtocolClient} does no translation of error codes returned //. by system calls. In some cases, an error code defined by MIME++ may //. returned to indicate improper use of the {\tt DwProtocolClient} class. const char* LastErrorStr() const; //. Returns an error message string associated with the error code returned //. by {\tt LastError()}. protected: enum { kWSAStartup=1, // Win32 kgethostbyname, ksocket, ksetsockopt, kconnect, ksend, krecv, kclose, // UNIX kclosesocket, // Win32 kselect }; // Enumerated values that indicate the system call that detected // an error DwBool mIsDllOpen; DwBool mIsOpen; int mSocket; DwUint16 mPort; char* mServerName; int mReceiveTimeout; int mLastCommand; int mFailureCode; const char* mFailureStr; int mErrorCode; const char* mErrorStr; virtual void HandleError(int aErrorCode, int aSystemCall); //. Interprets error codes. {\tt aErrorCode} is an error code, //. which may be a system error code, or an error code defined by //. {\tt DwProtocolClient}. {\tt aSystemCall} is an enumerated value //. defined by {\tt DwProtocolClient} that indicates the last system //. call made, which should be the system call that set the error code. //. {\tt HandleError()} sets values for {\tt mErrorStr}, //. {\tt mFailureCode}, and {\tt mFailureStr}. int PSend(const char* aBuf, int aBufLen); //. Sends {\tt aBufLen} characters from the buffer {\tt aBuf}. Returns //. the number of characters sent. If the number of characters sent //. is less than the number of characters specified in {\tt aBufLen}, //. the caller should call {\tt LastError()} to determine what, if any, //. error occurred. To determine if a failure also occurred, call the //. member function {\tt LastFailure()}. int PReceive(char* aBuf, int aBufSize); //. Receives up to {\tt aBufSize} characters into the buffer {\tt aBuf}. //. Returns the number of characters received. If zero is returned, the //. caller should call the member function {\tt LastError()} to determine //. what, if any, error occurred. To determine if a failure also occurred, //. call the member function {\tt LastFailure()}. }; #endif mimelib1-1.1.4/mimelib/mimelib/Makefile.am0000644000175000017500000000111211175345261017704 0ustar resivoresivo# $Id: Makefile.am 365583 2004-11-23 19:32:17Z dfaure $ mimelibdir = $(includedir)/mimelib mimelib_HEADERS= \ address.h \ addrlist.h \ body.h \ bodypart.h \ boyermor.h \ config.h \ datetime.h \ debug.h \ disptype.h \ entity.h \ enum.h \ field.h \ fieldbdy.h \ group.h \ headers.h \ mailbox.h \ mboxlist.h \ mechansm.h \ mediatyp.h \ message.h \ mimepp.h \ msgcmp.h \ msgid.h \ nntp.h \ param.h \ pop.h \ protocol.h \ string.h \ text.h \ token.h \ utility.h \ uuencode.h \ binhex.h mimelib1-1.1.4/mimelib/mimelib/fieldbdy.h0000644000175000017500000001372711175345261017622 0ustar resivoresivo//============================================================================= // File: fieldbdy.h // Contents: Declarations for DwFieldBody // Maintainer: Doug Sauder // WWW: http://www.fwb.gulf.net/~dwsauder/mimepp.html // // Copyright (c) 1996, 1997 Douglas W. Sauder // All rights reserved. // // IN NO EVENT SHALL DOUGLAS W. SAUDER BE LIABLE TO ANY PARTY FOR DIRECT, // INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF // THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF DOUGLAS W. SAUDER // HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // DOUGLAS W. SAUDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT // NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A // PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" // BASIS, AND DOUGLAS W. SAUDER HAS NO OBLIGATION TO PROVIDE MAINTENANCE, // SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. // //============================================================================= #ifndef DW_FIELDBDY_H #define DW_FIELDBDY_H #include #ifndef DW_CONFIG_H #include #endif #ifndef DW_STRING_H #include #endif #ifndef DW_MSGCMP_H #include #endif //============================================================================= //+ Name DwFieldBody -- Class representing a MIME header field body //+ Description //. {\tt DwFieldBody} represents the field-body element in the BNF grammar //. specified by RFC-822. It is an abstract base class that defines the //. interface common to all structured field bodies. //. //. In the tree (broken-down) representation of a message, a {\tt DwFieldBody} //. object may be either a leaf node, having a parent but no child nodes, or //. an intermediate node, having a parent and one or more child nodes. The //. parent node is the {\tt DwField} object that contains it. Child nodes, //. if present, depend on the particular subclass of {\tt DwFieldBody} that //. is instantiated. A {\tt DwAddressList} object, for example, has //. {\tt DwAddress} objects as its child nodes. //. //. Since {\tt DwFieldBody} is an abstract base class, you cannot create //. instances of it directly. Normally, objects of classes derived from //. {\tt DwFieldBody} are obtained by calling convenience member functions //. in the class {\tt DwHeaders}. //. //. Some MIME parsers are broken in that they do not handle the folding of //. some fields properly. {\tt DwFieldBody} folds its string representation //. by default. You can disable folding, however, by calling the //. {\tt SetFolding()} member function. To determine if folding is enabled, //. call {\tt IsFolding()}. //============================================================================= // Last updated 1997-08-24 //+ Noentry ~DwFieldBody mLineOffset mDoFolding _PrintDebugInfo class DW_EXPORT DwFieldBody : public DwMessageComponent { friend class DwField; public: DwFieldBody(); DwFieldBody(const DwFieldBody& aFieldBody); DwFieldBody(const DwString& aStr, DwMessageComponent* aParent=0); //. The first constructor is the default constructor, which sets the //. {\tt DwFieldBody} object's string representation to the empty //. string and sets its parent to {\tt NULL}. //. //. The second constructor is the copy constructor, which performs a //. deep copy of {\tt aFieldBody}. //. The parent of the new {\tt DwFieldBody} object is set to {\tt NULL}. //. //. The third constructor copies {\tt aStr} to the {\tt DwFieldBody} //. object's string representation and sets {\tt aParent} as its parent. //. The virtual member function {\tt Parse()} should be called immediately //. after this constructor in order to parse the string representation. //. Unless it is {\tt NULL}, {\tt aParent} should point to an object of //. a class derived from {\tt DwField}. virtual ~DwFieldBody(); const DwFieldBody& operator = (const DwFieldBody& aFieldBody); //. This is the assignment operator, which performs a deep copy of //. {\tt aFieldBody}. The parent node of the {\tt DwFieldBody} object //. is not changed. void SetOffset(int aOffset); //. Sets the offset to {\tt aOffset}. The offset is used when folding //. lines. It indicates how much the first line should be offset to //. account for the field name, colon, and initial white space. void SetFolding(DwBool aTrueOrFalse); //. Enables ({\tt aTrueOrFalse = DwTrue}) or disables //. ({\tt aTrueOrFalse = DwFalse}) the folding of fields. The default //. is to fold fields. Unfortunately, some parsers are broke and //. do not handle folded lines properly. This function allows a kludge //. to deal with these broken parsers. DwBool IsFolding() const; //. Returns a boolean indicating if folding of fields is enabled. protected: int mLineOffset; DwBool mDoFolding; private: static const char* const sClassName; public: virtual void PrintDebugInfo(std::ostream& aStrm, int aDepth=0) const; //. This virtual function, inherited from {\tt DwMessageComponent}, //. prints debugging information about this object to {\tt aStrm}. //. It will also call {\tt PrintDebugInfo()} for any of its child //. components down to a level of {\tt aDepth}. //. //. This member function is available only in the debug version of //. the library. virtual void CheckInvariants() const; //. Aborts if one of the invariants of the object fails. Use this //. member function to track down bugs. //. //. This member function is available only in the debug version of //. the library. protected: void _PrintDebugInfo(std::ostream& aStrm) const; }; inline void DwFieldBody::SetOffset(int aOffset) { mLineOffset = aOffset; } inline void DwFieldBody::SetFolding(DwBool aTrueOrFalse) { mDoFolding = aTrueOrFalse; } inline DwBool DwFieldBody::IsFolding() const { return mDoFolding; } #endif mimelib1-1.1.4/mimelib/mimelib/pop.h0000644000175000017500000003350111175345261016626 0ustar resivoresivo//============================================================================= // File: pop.h // Contents: Declarations for DwPopClient // Maintainer: Doug Sauder // WWW: http://www.fwb.gulf.net/~dwsauder/mimepp.html // // Copyright (c) 1996, 1997 Douglas W. Sauder // All rights reserved. // // IN NO EVENT SHALL DOUGLAS W. SAUDER BE LIABLE TO ANY PARTY FOR DIRECT, // INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF // THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF DOUGLAS W. SAUDER // HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // DOUGLAS W. SAUDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT // NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A // PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" // BASIS, AND DOUGLAS W. SAUDER HAS NO OBLIGATION TO PROVIDE MAINTENANCE, // SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. // //============================================================================= #ifndef DW_POP_H #define DW_POP_H #include #ifndef DW_CONFIG_H #include #endif #ifndef DW_PROTOCOL_H #include #endif #ifndef DW_STRING_H #include #endif //============================================================================= //+ Name DwPopClient -- Class for handling the client side of a POP session //+ Description //. {\tt DwPopClient} is a class that handles the client side of a POP //. session. Specifically, {\tt DwPopClient} provides facilities for //. opening a connection to a POP server, sending commands to the server, //. receiving responses from the server, and closing the connection. The //. protocol implemented is the Post Office Protocol version 3, as specified //. in RFC-1939. //. //. {\tt DwPopClient} is derived from {\tt DwProtocolClient}. For information //. about inherited member functions, especially member functions for detecting //. failures or errors, see the man page for {\tt DwProtocolClient}. //. //. In a POP session, the client sends commands to the server and receives //. responses from the server. A client command consists of a command word //. and zero or more argument words. A server response consists of a single //. line status response, which may be followed immediately by a multi-line //. response. The first word of the status response is either +OK or -ERR, //. indicating the success or failure of the command. The status line may //. also contain other information requested by the client. //. //. {\tt DwPopClient} has only a default constructor. On Win32 platforms, //. it is possible for the constructor to fail. (It calls WSAStartup().) //. You should verify that the constructor succeeded by calling the inherited //. member function {\tt DwProtocolClient::LastError()} and checking for a zero //. return value. //. //. To open a connection to the server, call the member function {\tt Open()} //. with the name of the server as an argument. {\tt Open()} accepts an //. optional argument that specifies the TCP port that the server listens to. //. The default port is the standard POP port (110). {\tt Open()} may fail, //. so you should check the return value to verify that it succeeded. To //. close the connection, call the inherited member function //. {\tt DwProtocolClient::Close()}. To check if a connection is open, call //. the inherited member function {\tt DwProtocolClient::IsOpen()}. //. {\tt IsOpen()} returns a boolean value that indicates whether or not //. a call to {\tt Open()} was successful; it will not detect failure in //. the network or a close operation by the remote host. //. //. For each POP command, {\tt DwPopClient} has a member function that sends //. that command and receives the server's response. If the command takes any //. arguments, then those arguments are passed as function arguments to the //. command function. The command functions return the first character //. of the server's response, which will be '+' if the command succeeded //. or '-' if the command failed. //. In some cases, because of a communications error or some other error, //. it is not possible for the command function to send the command or //. receive the response. When this happens, the command function will //. return 0. You can determine the precise error or failure by calling //. the inherited member functions {\tt DwProtocolClient::LastError()} or //. {\tt DwProtocolClient::LastFailure()}. //. //. After each command is sent, {\tt DwPopClient} receives the server's //. response and remembers it. The member function {\tt StatusCode()} //. returns the first character of the server's status response; it will be //. '+' or '-', indicating success or failure, or zero if no response was //. received from the server. {\tt SingleLineResponse()} returns the entire //. single line status response from the server, including the initial //. "+OK" or "-ERR" status word. //. //. The server sends a single-line response, including a status code, for all //. POP commands. For some commands, such as when the client requests a //. mail message, the server sends a multi-line text response immediately //. following the single-line status response. Multi-line text responses //. can be received in either of two ways. The simplest way is to call //. the member function {\tt MultiLineResponse()} after a command completes //. successfully. This simple method works fine for non-interactive //. applications. It can be a problem in interactive applications, however, //. because there is no data to display to a user until the entire multi-line //. response is retrieved. An alternative method allows your program to //. retrieve the multi-line response one line at a time as it is received. //. To use this method, you must define a subclass of {\tt DwObserver} //. and assign an object of that class to the {\tt DwPopClient} object //. using the member function {\tt SetObserver()}. {\tt DwObserver} is an //. abstract class, declared in protocol.h, that has just one pure virtual //. member function {\tt Notify()}. After each line of the multi-line response //. is received, {\tt DwPopClient} will call the {\tt Notify()} member //. function of its assigned {\tt DwObserver} object. Each invocation of //. {\tt Notify()} should call the {\tt DwPopClient} member function //. {\tt MultiLineResponse()} to retrieve the next line of the text response. //. Note that you cannot use both of these methods at the same time: if //. an observer is assigned, {\tt MultiLineResponse()} returns only the last //. line received, not the entire multi-line response. //============================================================================= //+ Noentry ~DwPopClient class DW_EXPORT DwPopClient : public DwProtocolClient { public: enum { kCmdNoCommand=0, kCmdUser, kCmdPass, kCmdQuit, kCmdStat, kCmdList, kCmdRetr, kCmdDele, kCmdNoop, kCmdRset, kCmdApop, kCmdTop, kCmdUidl }; DwPopClient(); //. Initializes the {\tt DwPopClient} object. //. It is possible for the constructor to fail. To verify that the //. constructor succeeded, call the member function {\tt LastError()} //. and check that it returns zero. (In the Win32 implementation, the //. constructor calls the Winsock function {\tt WSAStartup()}, which //. may fail.) virtual ~DwPopClient(); virtual int Open(const char* aServer, DwUint16 aPort=110); //. Opens a TCP connection to the server {\tt aServer} at port {\tt aPort}. //. {\tt aServer} may be either a host name, such as "news.acme.com" or //. an IP number in dotted decimal format, such as "147.81.64.60". The //. default value for {\tt aPort} is 110, the well-known port for POP3 //. assigned by the Internet Assigned Numbers Authority (IANA). //. //. If the connection attempt succeeds, the server sends a response. //. {\tt Open()} returns the server's status code ('+' or '-'). The full //. response from the server can be retrieved by calling //. {\tt SingleLineResponse()}. //. //. If the connection attempt fails, {\tt Open()} returns 0. To determine //. what error occurred when a connection attempt fails, call the inherited //. member function {\tt DwProtocolClient::LastError()}. To determine if //. a failure also occurred, call the inherited member function //. {\tt DwProtocolClient::LastFailure()}. DwObserver* SetObserver(DwObserver* aObserver); //. Sets the observer object that interacts with the {\tt DwPopClient} //. object to retrieve a multi-line response. If an observer is set, //. {\tt DwPopClient} will call the observer's {\tt Notify()} method //. after each line of the multi-line response is received. To remove //. an observer, call {\tt SetObserver()} with a NULL argument. //. {\tt SetObserver()} returns the previously set observer, or NULL if //. no observer was previously set. int StatusCode() const; //. Returns the status code received from the server in response to the //. last client command. The status codes in POP3 are '+', indicating //. success, and '-', indicating failure. If no response was received, //. {\tt StatusCode()} returns zero. const DwString& SingleLineResponse() const; //. Returns the single line status response last received from the server. //. If no response was received, perhaps because of a communications //. failure, {\tt SingleLineResponse()} returns an empty string. const DwString& MultiLineResponse() const; //. If no observer is set for this object, {\tt MultiLineResponse()} //. returns a string that comprises the entire sequence of lines //. received from the server. Otherwise, if an observer {\it is} set //. for this object, {\tt MultiLineResponse()} returns only the most //. recent line received. int User(const char* aName); //. Sends the USER command and returns the status code received from //. the server. If no response is received, the function returns zero. //. {\tt aName} is the name of the user, which is sent in the command. int Pass(const char* aPasswd); //. Sends the PASS command and returns the status code received from //. the server. If no response is received, the function returns zero. //. {\tt aPasswd} is the password, which is sent in the command. int Quit(); //. Sends the QUIT command and returns the status code received from //. the server. If no response is received, the function returns zero. int Stat(); //. Sends the STAT command and returns the status code received from //. the server. If no response is received, the function returns zero. int List(); int List(int aMsg); //. Sends the LIST command, with or without a message number, and //. returns the status code received from the server. If no response //. is received, the function returns zero. int Retr(int aMsg); //. Sends the RETR command and returns the status code received from //. the server. If no response is received, the function returns zero. //. {\tt aMsg} is the message number, which is sent in the command. int Dele(int aMsg); //. Sends the DELE command and returns the status code received from //. the server. If no response is received, the function returns zero. //. {\tt aMsg} is the message number, which is sent in the command. int Noop(); //. Sends the NOOP command and returns the status code received from //. the server. If no response is received, the function returns zero. int Rset(); //. Sends the RSET command and returns the status code received from //. the server. If no response is received, the function returns zero. int Apop(const char* aName, const char* aDigest); //. Sends the APOP command and returns the status code received from //. the server. If no response is received, the function returns zero. //. {\tt aName} is the name of the user, which is sent in the command. //. {\tt aDigest} is the digest argument for the command. int Top(int aMsg, int aNumLines); //. Sends the TOP command and returns the status code received from //. the server. If no response is received, the function returns zero. //. {\tt aMsg} is the message number. {\tt aNumLines} is the number //. of lines to send. int Uidl(); int Uidl(int aMsg); //. Sends the TOP command, with or without a message number, and //. returns the status code received from the server. If no response //. is received, the function returns zero. int Last(); //. Sends the LAST command and returns the status code received from //. the server. If no response is received, the function returns zero. private: char* mSendBuffer; char* mRecvBuffer; int mNumRecvBufferChars; int mRecvBufferPos; int mStatusCode; DwString mSingleLineResponse; DwString mMultiLineResponse; DwObserver* mObserver; int PGetLine(char** aPtr, int* aLen); // Tries to get one complete line of input from the socket. On success, // the function sets {\tt *aPtr} to point to the beginning of the line in // the object's internal buffer, sets {\tt *aLen} to the length of the // line, including the CR LF, and returns 0. On failure, the function // returns -1. void PGetSingleLineResponse(); // Gets a single line of input, assigns that line {\tt mSingleLineResponse}, and // sets {\tt mStatusCode}. On failure, clears {\tt mSingleLineResonse} // and sets {\tt mStatusCode} to -1. void PGetMultiLineResponse(); // Gets a complete multiline response and assigns it to {\tt mMultiLineResponse}, // or interacts with the {\tt DwObserver} object to deliver a multiline response // one line at a time. // If an error occurs, its sets {\tt mStatusCode} to -1. }; #endif mimelib1-1.1.4/mimelib/mimelib/param.h0000644000175000017500000001546011175345261017134 0ustar resivoresivo//============================================================================= // File: param.h // Contents: Declarations for DwParameter // Maintainer: Doug Sauder // WWW: http://www.fwb.gulf.net/~dwsauder/mimepp.html // // Copyright (c) 1996, 1997 Douglas W. Sauder // All rights reserved. // // IN NO EVENT SHALL DOUGLAS W. SAUDER BE LIABLE TO ANY PARTY FOR DIRECT, // INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF // THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF DOUGLAS W. SAUDER // HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // DOUGLAS W. SAUDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT // NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A // PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" // BASIS, AND DOUGLAS W. SAUDER HAS NO OBLIGATION TO PROVIDE MAINTENANCE, // SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. // //============================================================================= #ifndef DW_PARAM_H #define DW_PARAM_H #ifndef DW_CONFIG_H #include #endif #ifndef DW_STRING_H #include #endif #ifndef DW_MSGCMP_H #include #endif //============================================================================= //+ Name DwParameter -- Class representing a MIME field body parameter //+ Description //. {\tt DwParameter} represents the {\it parameter} component of the //. Content-Type header field as described in RFC-2045. A parameter //. consists of an attribute/value pair. {\tt DwParameter} has member //. functions for getting or setting a parameter's attribute and value. //. //. A {\tt DwParameter} object may be included in a list of {\tt DwParameter} //. objects. You can get the next {\tt DwParameter} object in the list by //. calling the member function {\tt Next()}. //============================================================================= // Last modified 1997-08-13 //+ Noentry ~DwParameter _PrintDebugInfo class DW_EXPORT DwParameter : public DwMessageComponent { friend class DwMediaType; public: DwParameter(); DwParameter(const DwParameter& aParam); DwParameter(const DwString& aStr, DwMessageComponent* aParent=0); //. The first constructor is the default constructor, which sets the //. {\tt DwParameter} object's string representation to the empty string //. and sets its parent to NULL. //. //. The second constructor is the copy constructor, which copies the //. string representation, attribute, and value from {\tt aParam}. //. The parent of the new {\tt DwParameter} object is set to NULL. //. //. The third constructor copies {\tt aStr} to the {\tt DwParameter} //. object's string representation and sets {\tt aParent} as its parent. //. The virtual member function {\tt Parse()} should be called immediately //. after this constructor in order to parse the string representation. //. Unless it is NULL, {\tt aParent} should point to an object of a class //. derived from {\tt DwMediaType}. virtual ~DwParameter(); const DwParameter& operator = (const DwParameter& aParam); //. This is the assignment operator. virtual void Parse(); //. This virtual function, inherited from {\tt DwMessageComponent}, //. executes the parse method for {\tt DwParameter} objects. //. It should be called immediately after the string representation //. is modified and before the parts of the broken-down //. representation are accessed. virtual void Assemble(); //. This virtual function, inherited from {\tt DwMessageComponent}, //. executes the assemble method for {\tt DwParameter} objects. //. It should be called whenever one of the object's attributes //. is changed in order to assemble the string representation from //. its broken-down representation. It will be called //. automatically for this object by the parent object's //. {\tt Assemble()} member function if the is-modified flag is set. virtual DwMessageComponent* Clone() const; //. This virtual function, inherited from {\tt DwMessageComponent}, //. creates a new {\tt DwParameter} on the free store that has the same //. value as this {\tt DwParameter} object. The basic idea is that of //. a ``virtual copy constructor.'' const DwString& Attribute() const; //. Returns the attribute contained by this parameter. void SetAttribute(const DwString& aAttribute); //. Sets the attribute contained by this parameter. const DwString& Value() const; //. Returns the value contained by this parameter. void SetValue(const DwString& aValue, bool forceNoQuotes=false); //. Sets the value contained by this parameter. DwParameter* Next() const ; //. Returns the next {\tt DwParameter} object in the list. void SetNext(DwParameter* aParam); //. Returns the next {\tt DwParameter} object in the list. Since //. {\tt DwMediaType} has member functions for adding {\tt DwParameter} //. objects to its list, you should avoid using this function. static DwParameter* NewParameter(const DwString& aStr, DwMessageComponent* aParent); //. Creates a new {\tt DwParameter} object on the free store. //. If the static data member {\tt sNewParameter} is NULL, //. this member function will create a new {\tt DwParameter} //. and return it. Otherwise, {\tt NewParameter()} will call //. the user-supplied function pointed to by {\tt sNewParameter}, //. which is assumed to return an object from a class derived from //. {\tt DwParameter}, and return that object. //+ Var sNewParameter static DwParameter* (*sNewParameter)(const DwString&, DwMessageComponent*); //. If {\tt sNewParameter} is not NULL, it is assumed to point to a //. user-supplied function that returns an object from a class derived from //. {\tt DwParameter}. private: DwString mAttribute; DwString mValue; bool mForceNoQuotes; DwParameter* mNext; static const char* const sClassName; public: virtual void PrintDebugInfo(std::ostream& aStrm, int aDepth=0) const; //. This virtual function, inherited from {\tt DwMessageComponent}, //. prints debugging information about this object to {\tt aStrm}. //. It will also call {\tt PrintDebugInfo()} for any of its child //. components down to a level of {\tt aDepth}. //. //. This member function is available only in the debug version of //. the library. virtual void CheckInvariants() const; //. Aborts if one of the invariants of the object fails. Use this //. member function to track down bugs. //. //. This member function is available only in the debug version of //. the library. protected: void _PrintDebugInfo(std::ostream& aStrm) const; }; #endif mimelib1-1.1.4/mimelib/mimelib/mboxlist.h0000644000175000017500000002142611175345261017674 0ustar resivoresivo//============================================================================= // File: mboxlist.h // Contents: Declarations for DwMailboxList // Maintainer: Doug Sauder // WWW: http://www.fwb.gulf.net/~dwsauder/mimepp.html // // Copyright (c) 1996, 1997 Douglas W. Sauder // All rights reserved. // // IN NO EVENT SHALL DOUGLAS W. SAUDER BE LIABLE TO ANY PARTY FOR DIRECT, // INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF // THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF DOUGLAS W. SAUDER // HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // DOUGLAS W. SAUDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT // NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A // PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" // BASIS, AND DOUGLAS W. SAUDER HAS NO OBLIGATION TO PROVIDE MAINTENANCE, // SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. // //============================================================================= #ifndef DW_MBOXLIST_H #define DW_MBOXLIST_H #ifndef DW_CONFIG_H #include #endif #ifndef DW_STRING_H #include #endif #ifndef DW_ADDRESS_H #include #endif //============================================================================= //+ Name DwMailboxList -- Class representing a list of RFC-822 mailboxes //+ Description //. {\tt DwMailboxList} represents a list of {\it mailboxes} as described //. in RFC-822. In MIME++, {\tt DwMailboxList} is a container for objects //. of type {\tt DwMailbox}, and it contains various member functions to //. manage its contained objects. {\tt DwAddressList} is also a //. {\tt DwFieldBody}. This reflects the fact that certain RFC-822 header //. fields, such as the "From" header field, have a list of mailboxes as //. their field bodies. //============================================================================= // Last modified 1997-08-30 //+ Noentry ~DwMailboxList _PrintDebugInfo class DW_EXPORT DwMailboxList : public DwFieldBody { public: DwMailboxList(); DwMailboxList(const DwMailboxList& aList); DwMailboxList(const DwString& aStr, DwMessageComponent* aParent=0); //. The first constructor is the default constructor, which sets the //. {\tt DwMailboxList} object's string representation to the empty string //. and sets its parent to {\tt NULL}. //. //. The second constructor is the copy constructor, which copies the //. string representation and all {\tt DwMailbox} objects from {\tt aList}. //. The parent of the new {\tt DwMailboxList} object is set to {\tt NULL}. //. //. The third constructor copies {\tt aStr} to the {\tt DwMailboxList} //. object's string representation and sets {\tt aParent} as its parent. //. The virtual member function {\tt Parse()} should be called immediately //. after this constructor in order to parse the string representation. //. Unless it is {\tt NULL}, {\tt aParent} should point to an object of //. a class derived from {\tt DwField}. virtual ~DwMailboxList(); const DwMailboxList& operator = (const DwMailboxList& aList); //. This is the assignment operator, which performs a deep copy of //. {\tt aList}. The parent node of the {\tt DwMailboxList} object //. is not changed. virtual void Parse(); //. This virtual function, inherited from {\tt DwMessageComponent}, //. executes the parse method for {\tt DwMailboxList} objects. The parse //. method creates or updates the broken-down representation from the //. string representation. For {\tt DwMailboxList} objects, the parse //. method parses the string representation to create a list of //. {\tt DwMailbox} objects. This member function also calls the //. {\tt Parse()} member function of each {\tt DwMailbox} object in //. its list. //. //. You should call this member function after you set or modify the //. string representation, and before you access any of the contained //. {\tt DwMailbox} objects. //. //. This function clears the is-modified flag. virtual void Assemble(); //. This virtual function, inherited from {\tt DwMessageComponent}, //. executes the assemble method for {\tt DwMailboxList} objects. The //. assemble method creates or updates the string representation from //. the broken-down representation. For {\tt DwMailboxList} objects, //. the assemble method builds the string representation from its list //. of {\tt DwMailbox} objects. Before it builds the string representation //. for the {\tt DwMailboxList} object, this function first calls the //. {\tt Assemble()} member function of each {\tt DwMailbox} object //. in its list. //. //. You should call this member function after you set or modify any //. of the contained {\tt DwMailbox} objects, and before you retrieve //. the string representation. //. //. This function clears the is-modified flag. virtual DwMessageComponent* Clone() const; //. This virtual function, inherited from {\tt DwMessageComponent}, //. creates a new {\tt DwMailboxList} on the free store that has the same //. value as this {\tt DwMailboxList} object. The basic idea is that of //. a virtual copy constructor. DwMailbox* FirstMailbox() const; //. Gets the first {\tt DwMailbox} object in the list. //. Use the member function {\tt DwMailbox::Next()} to iterate. //. Returns {\tt NULL} if the list is empty. void Add(DwMailbox* aMailbox); //. Adds {\tt aMailbox} to the end of the list of {\tt DwMailbox} objects //. maintained by this {\tt DwMailboxList} object. void Remove(DwMailbox* aMailbox); //. Removes {\tt aMailbox} from the list of {\tt DwMailbox} objects //. maintained by this {\tt DwMailboxList} object. The {\tt DwMailbox} //. object is not deleted by this member function. void DeleteAll(); //. Removes and deletes all {\tt DwMailbox} objects from the list //. maintained by this {\tt DwMailboxList} object. static DwMailboxList* NewMailboxList(const DwString& aStr, DwMessageComponent* aParent); //. Creates a new {\tt DwMailboxList} object on the free store. //. If the static data member {\tt sNewMailboxList} is {\tt NULL}, //. this member function will create a new {\tt DwMailboxList} //. and return it. Otherwise, {\tt NewMailboxList()} will call //. the user-supplied function pointed to by {\tt sNewMailboxList}, //. which is assumed to return an object from a class derived from //. {\tt DwMailboxList}, and return that object. //+ Var sNewMailboxList static DwMailboxList* (*sNewMailboxList)(const DwString&, DwMessageComponent*); //. If {\tt sNewMailboxList} is not {\tt NULL}, it is assumed to point //. to a user-supplied function that returns an object from a class //. derived from {\tt DwMailboxList}. protected: DwMailbox* mFirstMailbox; //. Points to first {\tt DwMailbox} object in list. void _AddMailbox(DwMailbox* aMailbox); //. Adds a mailbox, but does not set the is-modified flag. void _DeleteAll(); //. Removes and deletes all {\tt DwMailbox} objects from the list //. maintained by this {\tt DwMailboxList} object. Doesn't set the //. is-modified flag. private: static const char* const sClassName; void CopyList(const DwMailbox* aFirst); public: virtual void PrintDebugInfo(std::ostream& aStrm, int aDepth=0) const; //. This virtual function, inherited from {\tt DwMessageComponent}, //. prints debugging information about this object to {\tt aStrm}. //. It will also call {\tt PrintDebugInfo()} for any of its child //. components down to a level of {\tt aDepth}. //. //. This member function is available only in the debug version of //. the library. virtual void CheckInvariants() const; //. Aborts if one of the invariants of the object fails. Use this //. member function to track down bugs. //. //. This member function is available only in the debug version of //. the library. protected: void _PrintDebugInfo(std::ostream& aStrm) const; }; class DW_EXPORT DwMailboxListParser { public: enum { eMbError, eMbGroup, eMbMailbox, eMbNull, eMbEnd }; DwMailboxListParser(const DwString& aStr); virtual ~DwMailboxListParser(); const DwString& MbString() { return mMbString.Tokens(); } int MbType() { return mMbType; } int IsNull() { return (mMbType == eMbNull) ? 1 : 0; } int IsEnd() { return (mMbType == eMbEnd) ? 1 : 0; } int Restart(); int operator ++ (); // prefix increment operator protected: void ParseNextMailbox(); DwRfc822Tokenizer mTokenizer; DwTokenString mMbString; int mMbType; }; #endif mimelib1-1.1.4/mimelib/mimelib/debug.h0000644000175000017500000000274311175345261017122 0ustar resivoresivo//============================================================================= // File: dw_debug.h // Contents: Macros for debugging // Maintainer: Doug Sauder // WWW: http://www.fwb.gulf.net/~dwsauder/mimepp.html // // Copyright (c) 1996, 1997 Douglas W. Sauder // All rights reserved. // // IN NO EVENT SHALL DOUGLAS W. SAUDER BE LIABLE TO ANY PARTY FOR DIRECT, // INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF // THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF DOUGLAS W. SAUDER // HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // DOUGLAS W. SAUDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT // NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A // PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" // BASIS, AND DOUGLAS W. SAUDER HAS NO OBLIGATION TO PROVIDE MAINTENANCE, // SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. // //============================================================================= #ifndef DW_DEBUG_H #define DW_DEBUG_H #ifndef DW_CONFIG_H #include #endif #if !defined (DW_DEBUG_VERSION) && !defined (DW_DEVELOPMENT_VERSION) #define NDEBUG #endif #if defined (DW_DEBUG_VERSION) #define DBG_STMT(x) x; #else #define DBG_STMT(x) ; #endif #if defined (DW_DEBUG_VERSION) || defined (DW_DEVELOPMENT_VERSION) #define DEV_STMT(x) x; #else #define DEV_STMT(x) ; #endif #include #define ASSERT assert #endif mimelib1-1.1.4/mimelib/mimelib/string.h0000644000175000017500000007706211175345261017350 0ustar resivoresivo//============================================================================= // File: dwstring.h // Contents: Declarations for DwString // Maintainer: Doug Sauder // WWW: http://www.fwb.gulf.net/~dwsauder/mimepp.html // // Copyright (c) 1996, 1997 Douglas W. Sauder // All rights reserved. // // IN NO EVENT SHALL DOUGLAS W. SAUDER BE LIABLE TO ANY PARTY FOR DIRECT, // INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF // THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF DOUGLAS W. SAUDER // HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // DOUGLAS W. SAUDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT // NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A // PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" // BASIS, AND DOUGLAS W. SAUDER HAS NO OBLIGATION TO PROVIDE MAINTENANCE, // SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. // //============================================================================= #ifndef DW_STRING_H #define DW_STRING_H #include #include #include #include #ifndef DW_CONFIG_H #include #endif #if defined(DW_USE_ANSI_STRING) #include typedef std::string DwString; #else // ! defined(DW_USE_ANSI_STRING) //============================================================================= // DwStringRep is an implementation class that should not be used externally. //============================================================================= struct DW_EXPORT DwStringRep { DwStringRep(char* aBuf, size_t aSize); DwStringRep(FILE* aFile, size_t aSize); ~DwStringRep(); // void* operator new(size_t); // void operator delete(void*, size_t); size_t mSize; char* mBuffer; int mRefCount, mPageMod; //private: // memory management // DwStringRep* mNext; // static DwStringRep* theirPool; // static int theirPoolCount; public: void CheckInvariants() const; }; //============================================================================= //+ Name DwString -- String class //+ Description //. {\tt DwString} is the workhorse of the MIME++ library. Creating, parsing, //. or otherwise manipulating MIME messages is basically a matter of //. manipulating strings. {\tt DwString} provides all the basic functionality //. required of a string object, including copying, comparing, concatenating, //. and so on. //. //. {\tt DwString} is similar to the {\tt string} class that is part of //. the proposed ANSI standard C++ library. Some of the member functions //. present in the ANSI {\tt string} are not present in {\tt DwString}: //. mostly these are the functions that deal with iterators. {\tt DwString} //. also includes some member functions and class utility functions that //. are not a part of the ANSI {\tt string} class. These non-ANSI //. functions are easy to distinguish: they all begin with upper-case //. letters, and all ANSI functions begin with lower-case letters. The //. library classes themselves use only the ANSI {\tt string} functions. //. At some point in the future, MIME++ will probably allow the option to //. substitute the ANSI {\tt string} class for {\tt DwString}. //. //. {\tt DwString} makes extensive use of copy-on-write, even when extracting //. substrings. It is this feature that distiguishes {\tt DwString} from most //. other string classes. {\tt DwString} also handles binary data, which can //. contain embedded NUL characters. //============================================================================= //+ Noentry _copy _replace Length AsCharBuf Substring Prefix Suffix Prepend //+ Noentry Append Insert Replace Delete mRep mStart mLength sEmptyString //+ Noentry ~DwString class DW_EXPORT DwString { public: static const size_t npos; //. {\tt npos} is assigned the value (size_t)-1. DwString(); DwString(const DwString& aStr, size_t aPos=0, size_t aLen=npos); DwString(const char* aBuf, size_t aLen); DwString(FILE* aFile , size_t aLen); DwString(const char* aCstr); DwString(size_t aLen, char aChar); DwString(char* aBuf, size_t aSize, size_t aStart, size_t aLen); //. The first constructor is the default constructor, which sets the //. {\tt DwString} object's contents to be empty. //. //. The second constructor is the copy constructor, which copies at most //. {\tt aLen} characters beginning at position //. {\tt aPos} from {\tt aStr} to the new {\tt DwString} object. It will //. not copy more characters than what are available in {\tt aStr}. //. {\tt aPos} must be less than or equal to {\tt aStr.size()}. //. //. The third constructor copies {\tt aLen} characters from the buffer //. {\tt aBuf} into the new {\tt DwString} object. {\tt aBuf} need not be //. NUL-terminated and may contain NUL characters. //. //. The fourth constructor copies the contents of the NUL-terminated string //. {\tt aCstr} into the new {\tt DwString} object. //. //. The fifth constructor sets the contents of the new {\tt DwString} //. object to be the character {\tt aChar} repeated {\tt aLen} times. //. //. The sixth constructor is an {\it advanced} constructor that sets //. the contents of the new {\tt DwString} object to the {\tt aLen} //. characters starting at offset {\tt aStart} in the buffer {\tt aBuf}. //. {\tt aSize} is the allocated size of {\tt aBuf}. //. This constructor is provided for efficiency in setting a new //. {\tt DwString}'s contents from a large buffer. It is efficient //. because no copying takes place. Instead, {\tt aBuf} becomes the //. buffer used internally by the {\tt DwString} object, which //. takes responsibility for deleting the buffer. //. Because {\tt DwString} will free the buffer using {\tt delete []}, //. the buffer should have been allocated using {\tt new}. //. See also: TakeBuffer(), and ReleaseBuffer(). virtual ~DwString(); DwString& operator = (const DwString& aStr); DwString& operator = (const char* aCstr); DwString& operator = (char aChar); //. Assigns the contents of the operand to this string. //. {\tt aCstr} must point to a NUL-terminated array of characters //. (a C string). //. Returns {\tt *this}. size_t size() const; //. Returns the number of characters in this string's contents. This //. member function is identical to {\tt length()} size_t length() const; //. Returns the number of characters in this string's contents. This //. member function is identical to {\tt size()} size_t max_size() const; //. Returns the maximum length that this string can ever attain. void resize(size_t aLen, char aChar); void resize(size_t aLen); //. Changes the length of this string. If the string shortened, the final //. characters are truncated. If the string is expanded, the added //. characters will be NULs or the character specified by {\tt aChar}. size_t capacity() const; //. Returns the size of the internal buffer used for this string, which //. will always be greater than or equal to the length of the string. void reserve(size_t aSize); //. If {\tt aSize} is greater than the current capacity of this string, //. this member function will increase the capacity to be at least //. {\tt aSize}. void clear(); //. Sets this string's contents to be empty. DwBool empty() const; //. Returns a true value if and only if the contents of this string //. are empty. const char& operator [] (size_t aPos) const; char& operator [] (size_t aPos); //. Returns {\tt DwString::at(aPos) const} or {\tt DwString::at(aPos)}. //. Note that the non-const version always assumes that the contents //. will be modified and therefore always copies a shared internal //. buffer before it returns. const char& at(size_t aPos) const; char& at(size_t aPos); //. Returns the character at position {\tt aPos} in the string's contents. //. The non-const version returns an lvalue that may be assigned to. //. Note that the non-const version always assumes that the contents //. will be modified and therefore always copies a shared internal //. buffer before it returns. DwString& operator += (const DwString& aStr); DwString& operator += (const char* aCstr); DwString& operator += (char aChar); //. Appends the contents of the operand to this string. //. {\tt aCstr} must point to a NUL-terminated array of characters //. (a C string). //. Returns {\tt *this}. DwString& append(const DwString& aStr); DwString& append(const DwString& aStr, size_t aPos, size_t aLen); DwString& append(const char* aBuf, size_t aLen); DwString& append(const char* aCstr); DwString& append(size_t aLen, char aChar); //. Appends characters to (the end of) this string. //. Returns {\tt *this}. //. //. The first version appends all of the characters from {\tt aStr}. //. //. The second version appends at most {\tt aLen} characters from //. {\tt aStr} beginning at position {\tt aPos}. {\tt aPos} must be //. less than or equal to {\tt aStr.size()}. The function will not //. append more characters than what are available in {\tt aStr}. //. //. The third version appends {\tt aLen} characters from {\tt aBuf}, //. which is not assumed to be NUL-terminated and can contain embedded //. NULs. //. //. The fourth version appends characters from the NUL-terminated //. string {\tt aCstr}. //. //. The fifth version appends {\tt aChar} repeated {\tt aLen} times. DwString& assign(const DwString& aStr); DwString& assign(const DwString& aStr, size_t aPos, size_t aLen); DwString& assign(const char* aBuf, size_t aLen); DwString& assign(const char* aCstr); DwString& assign(size_t aLen, char aChar); //. Assigns characters to this string. //. Returns {\tt *this}. //. //. The first version assigns all of the characters from {\tt aStr}. //. //. The second version assigns at most {\tt aLen} characters from //. {\tt aStr} beginning at position {\tt aPos}. {\tt aPos} must be //. less than or equal to {\tt aStr.size()}. The function will not //. assign more characters than what are available in {\tt aStr}. //. //. The third version assigns {\tt aLen} characters from {\tt aBuf}, //. which is not assumed to be NUL-terminated and can contain embedded //. NULs. //. //. The fourth version assigns characters from the NUL-terminated //. string {\tt aCstr}. //. //. The fifth version assigns {\tt aChar} repeated {\tt aLen} times. DwString& insert(size_t aPos1, const DwString& aStr); DwString& insert(size_t aPos1, const DwString& aStr, size_t aPos2, size_t aLen2); DwString& insert(size_t aPos1, const char* aBuf, size_t aLen2); DwString& insert(size_t aPos1, const char* aCstr); DwString& insert(size_t aPos1, size_t aLen2, char aChar); //. Inserts characters into this string beginning at position {\tt aPos1}. //. Returns {\tt *this}. //. //. The first version inserts all of the characters from {\tt aStr}. //. //. The second version inserts at most {\tt aLen2} characters from //. {\tt aStr} beginning at position {\tt aPos2}. {\tt aPos1} must be //. less than or equal to {\tt aStr.size()}. The function will not //. assign more characters than what are available in {\tt aStr}. //. //. The third version inserts {\tt aLen2} characters from {\tt aBuf}, //. which is not assumed to be NUL-terminated and can contain embedded //. NULs. //. //. The fourth version inserts characters from the NUL-terminated //. string {\tt aCstr}. //. //. The fifth version inserts {\tt aChar} repeated {\tt aLen2} times. DwString& erase(size_t aPos=0, size_t aLen=npos); //. Erases (removes) at most {\tt aLen} characters beginning at position //. {\tt aPos} from this string. //. The function will not erase more characters than what are //. available. //. Returns {\tt *this}. DwString& replace(size_t aPos1, size_t aLen1, const DwString& aStr); DwString& replace(size_t aPos1, size_t aLen1, const DwString& aStr, size_t aPos2, size_t aLen2); DwString& replace(size_t aPos1, size_t aLen1, const char* aBuf, size_t aLen2); DwString& replace(size_t aPos1, size_t aLen1, const char* aCstr); DwString& replace(size_t aPos1, size_t aLen1, size_t aLen2, char aChar); //. Removes {\tt aLen1} characters beginning at position {\tt aPos1} //. and inserts other characters. //. Returns {\tt *this}. //. //. The first version inserts all of the characters from {\tt aStr}. //. //. The second version inserts at most {\tt aLen2} characters from //. {\tt aStr} beginning at position {\tt aPos2}. {\tt aPos1} must be //. less than or equal to {\tt aStr.size()}. The function will not //. assign more characters than what are available in {\tt aStr}. //. //. The third version inserts {\tt aLen2} characters from {\tt aBuf}, //. which is not assumed to be NUL-terminated and can contain embedded //. NULs. //. //. The fourth version inserts characters from the NUL-terminated //. string {\tt aCstr}. //. //. The fifth version inserts {\tt aChar} repeated {\tt aLen2} times. size_t copy(char* aBuf, size_t aLen, size_t aPos=0) const; //. Copies at most {\tt aLen} characters beginning at position {\tt aPos} //. from this string to the buffer pointed to by {\tt aBuf}. //. Returns the number of characters copied. void swap(DwString& aStr); //. Swaps the contents of this string and {\tt aStr}. const char* c_str() const; const char* data() const; //. These member functions permit access to the internal buffer used //. by the {\tt DwString} object. {\tt c_str()} returns a NUL-terminated //. string suitable for use in C library functions. {\tt data()} //. returns a pointer to the internal buffer, which may not be //. NUL-terminated. //. //. {\tt c_str()} may copy the internal buffer in order to place the //. terminating NUL. This is not a violation of the const declaration: //. it is a logical const, not a bit-representation const. It could //. have the side effect of invalidating a pointer previously returned //. by {\tt c_str()} or {\tt data()}. //. //. The characters in the returned string should not be modified, and //. should be considered invalid after any call to a non-const member //. function or another call to {\tt c_str()}. size_t find(const DwString& aStr, size_t aPos=0) const; size_t find(const char* aBuf, size_t aPos, size_t aLen) const; size_t find(const char* aCstr, size_t aPos=0) const; size_t find(char aChar, size_t aPos=0) const; //. Performs a forward search for a sequence of characters in the //. {\tt DwString} object. The return value is the position of the //. sequence in the string if found, or {\tt DwString::npos} if not //. found. //. //. The first version searches beginning at position {\tt aPos} for //. the sequence of characters in {\tt aStr}. //. //. The second version searches beginning at position {\tt aPos} for //. the sequence of {\tt aLen} characters in {\tt aBuf}, which need not //. be NUL-terminated and can contain embedded NULs. //. //. The third version searches beginning at position {\tt aPos} for //. the sequence of characters in the NUL-terminated string {\tt aCstr}. //. //. The fourth version searches beginning at position {\tt aPos} for //. the character {\tt aChar}. size_t rfind(const DwString& aStr, size_t aPos=npos) const; size_t rfind(const char* aBuf, size_t aPos, size_t aLen) const; size_t rfind(const char* aCstr, size_t aPos=npos) const; size_t rfind(char aChar, size_t aPos=npos) const; //. Performs a reverse search for a sequence of characters in the //. {\tt DwString} object. The return value is the position of the //. sequence in the string if found, or {\tt DwString::npos} if not //. found. //. //. The first version searches beginning at position {\tt aPos} for //. the sequence of characters in {\tt aStr}. //. //. The second version searches beginning at position {\tt aPos} for //. the sequence of {\tt aLen} characters in {\tt aBuf}, which need not //. be NUL-terminated and can contain embedded NULs. //. //. The third version searches beginning at position {\tt aPos} for //. the sequence of characters in the NUL-terminated string {\tt aCstr}. //. //. The fourth version searches beginning at position {\tt aPos} for //. the character {\tt aChar}. size_t find_first_of(const DwString& aStr, size_t aPos=0) const; size_t find_first_of(const char* aBuf, size_t aPos, size_t aLen) const; size_t find_first_of(const char* aCstr, size_t aPos=0) const; //. Performs a forward search beginning at position {\tt aPos} for //. the first occurrence of any character from a specified set of //. characters. The return value is the position of the character //. if found, or {\tt DwString::npos} if not found. //. //. The first version searches for any character in the string {\tt aStr}. //. //. The second version searches for any of the {\tt aLen} characters in //. {\tt aBuf}. //. //. The third version searches for any character in the NUL-terminated //. string {\tt aCstr}. size_t find_last_of(const DwString& aStr, size_t aPos=npos) const; size_t find_last_of(const char* aBuf, size_t aPos, size_t aLen) const; size_t find_last_of(const char* aCstr, size_t aPos=npos) const; //. Performs a reverse search beginning at position {\tt aPos} for //. the first occurrence of any character from a specified set of //. characters. If {\tt aPos} is greater than or equal to the number //. of characters in the string, then the search starts at the end //. of the string. The return value is the position of the character //. if found, or {\tt DwString::npos} if not found. //. //. The first version searches for any character in the string {\tt aStr}. //. //. The second version searches for any of the {\tt aLen} characters in //. {\tt aBuf}. //. //. The third version searches for any character in the NUL-terminated //. string {\tt aCstr}. size_t find_first_not_of(const DwString& aStr, size_t aPos=0) const; size_t find_first_not_of(const char* aBuf, size_t aPos, size_t aLen) const; size_t find_first_not_of(const char* aCstr, size_t aPos=0) const; //. Performs a forward search beginning at position {\tt aPos} for //. the first occurrence of any character {\it not} in a specified set //. of characters. The return value is the position of the character //. if found, or {\tt DwString::npos} if not found. //. //. The first version searches for any character not in the string //. {\tt aStr}. //. //. The second version searches for any character not among the //. {\tt aLen} characters in {\tt aBuf}. //. //. The third version searches for any character not in the NUL-terminated //. string {\tt aCstr}. size_t find_last_not_of(const DwString& aStr, size_t aPos=npos) const; size_t find_last_not_of(const char* aBuf, size_t aPos, size_t aLen) const; size_t find_last_not_of(const char* aCstr, size_t aPos=npos) const; //. Performs a reverse search beginning at position {\tt aPos} for //. the first occurrence of any character {\it not} in a specified set //. of characters. If {\tt aPos} is greater than or equal to the number //. of characters in the string, then the search starts at the end //. of the string. The return value is the position of the character //. if found, or {\tt DwString::npos} if not found. //. //. The first version searches for any character not in the string //. {\tt aStr}. //. //. The second version searches for any character not among the //. {\tt aLen} characters in {\tt aBuf}. //. //. The third version searches for any character not in the NUL-terminated //. string {\tt aCstr}. DwString substr(size_t aPos=0, size_t aLen=npos) const; //. Returns a string that contains at most {\tt aLen} characters from //. the {\tt DwString} object beginning at position {\tt aPos}. The //. returned substring will not contain more characters than what are //. available in the superstring {\tt DwString} object. int compare(const DwString& aStr) const; int compare(size_t aPos1, size_t aLen1, const DwString& aStr) const; int compare(size_t aPos1, size_t aLen1, const DwString& aStr, size_t aPos2, size_t aLen2) const; int compare(const char* aCstr) const; int compare(size_t aPos1, size_t aLen1, const char* aBuf, size_t aLen2=npos) const; //. These member functions compare a sequence of characters to this //. {\tt DwString} object, or a segment of this {\tt DwString} object. //. They return -1, 0, or 1, depending on whether this {\tt DwString} //. object is less than, equal to, or greater than the compared sequence //. of characters, respectively. //. //. The first version compares {\tt aStr} to this string. //. //. The second version compares {\tt aStr} with the {\tt aLen1} characters //. beginning at position {\tt aPos1} in this {\tt DwString} object. //. //. The third version compares the {tt aLen2} characters beginning at //. position {\tt aPos2} in {\tt aStr} with the {\tt aLen1} characters //. beginning at position {\tt aPos1} in this {\tt DwString} object. //. //. The fourth version compares the NUL-terminated string {\tt aCstr} //. to this {\tt DwString}. //. //. The fifth version compares the {\tt aLen2} characters in {\tt aBuf} //. with the {\tt aLen1} characters beginning at position {\tt aPos1} in //. this {\tt DwString} object. // Non-ANSI member functions virtual const char* ClassName() const; //. This virtual function returns the name of the class as a NUL-terminated //. char string. int ObjectId() const; //. Returns the unique object id for this {\tt DwString}. void ConvertToLowerCase(); void ConvertToUpperCase(); //. Converts this {\tt DwString} object's characters to all lower case or //. all upper case. void Trim(); //. Removes all white space from the beginning and the end of this //. {\tt DwString} object. White space characters include ASCII HT, //. LF, and SPACE. void WriteTo(std::ostream& aStrm) const; //. Writes the contents of this {\tt DwString} object to the stream //. {\tt aStrm}. int RefCount() const; //. This {\it advanced} member function returns the number of //. references to the internal buffer used by the {\tt DwString} object. void TakeBuffer(char* aBuf, size_t aSize, size_t aStart, size_t aLen); //. This {\it advanced} member function sets the contents of the //. {\tt DwString} object to the {\tt aLen} characters starting at //. offset {\tt aStart} in the buffer {\tt aBuf}. {\tt aSize} is //. the allocated size of {\tt aBuf}. //. This member function is provided for efficiency in setting a //. {\tt DwString}'s contents from a large buffer. It is efficient //. because no copying takes place. Instead, {\tt aBuf} becomes the //. buffer used internally by the {\tt DwString} object, which //. takes responsibility for deleting the buffer. //. Because DwString will free the buffer using {\tt delete []}, the //. buffer should have been allocated using {\tt new}. //. See also: ReleaseBuffer(). void ReleaseBuffer(char** aBuf, size_t* aSize, size_t* aStart, size_t* aLen); //. This {\it advanced} member function is the symmetric opposite of //. {\tt TakeBuffer()}, to the extent that such an opposite is possible. //. It provides a way to ``export'' the buffer used internally by the //. {\tt DwString} object. //. Note, however, that because of the copy-on-modify feature of //. {\tt DwString}, the {\tt DwString} object may not have sole //. ownership of its internal buffer. When that is case, //. {\tt ReleaseBuffer()} will return a copy of the buffer. You can check //. to see if the internal buffer is shared by calling {\tt RefCount()}. //. On return from this member function, the {\tt DwString} object will //. have valid, but empty, contents. //. It is recommended that you use this function only on rare occasions //. where you need to export efficiently a large buffer. void CopyTo(DwString* aStr) const; //. This {\it advanced} member function copies this {\tt DwString} //. object to {\tt aStr}. This member //. function is different from the assignment operator, because it //. physically copies the buffer instead of just duplicating a reference //. to it. protected: DwStringRep* mRep; size_t mStart; size_t mLength; void _copy(); void _replace(size_t aPos1, size_t aLen1, const char* aBuf, size_t aLen2); void _replace(size_t aPos1, size_t aLen1, size_t aLen2, char aChar); private: static const size_t kEmptyBufferSize; static char sEmptyBuffer[]; static DwStringRep* sEmptyRep; friend void mem_free(char*); public: virtual void PrintDebugInfo(std::ostream& aStrm) const; //. Prints debugging information about the object to {\tt aStrm}. //. //. This member function is available only in the debug version of //. the library. virtual void CheckInvariants() const; //. Aborts if one of the invariants of the object fails. Use this //. member function to track down bugs. //. //. This member function is available only in the debug version of //. the library. }; //--------------------------------------------------------------------------- // inline functions //--------------------------------------------------------------------------- inline size_t DwString::size() const { return mLength; } inline size_t DwString::length() const { return mLength; } inline size_t DwString::capacity() const { return mRep->mSize - 1; } inline DwBool DwString::empty() const { return mLength == 0; } inline int DwString::RefCount() const { return mRep->mRefCount; } inline const char* DwString::c_str() const { if (mRep->mRefCount > 1 && mRep != sEmptyRep) { DwString* xthis = (DwString*) this; xthis->_copy(); } return &mRep->mBuffer[mStart]; } inline const char* DwString::data() const { return &mRep->mBuffer[mStart]; } // Returning const char& instead of char will allow us to use DwString::at() // in the following way: // if (&s.at(1) == ' ') { /* ... */ } inline const char& DwString::at(size_t aPos) const { assert(aPos <= mLength); if (aPos < mLength) { return data()[aPos]; } else if (aPos == mLength) { return sEmptyRep->mBuffer[0]; } else { // This "undefined behavior" // Normally, this will not occur. The assert() macro will catch it, // or at some point we may throw an exception. return data()[0]; } } inline char& DwString::at(size_t aPos) { assert(aPos < mLength); if (aPos < mLength) { return (char&) c_str()[aPos]; } else { // This is "undefined behavior" assert(0); return (char&) c_str()[0]; } } // Returning const char& instead of char will allow us to use operator[] // in the following way: // if (&s[1] == ' ') { /* ... */ } inline const char& DwString::operator [] (size_t aPos) const { return at(aPos); } inline char& DwString::operator [] (size_t aPos) { return at(aPos); } inline DwString& DwString::operator = (const DwString& aStr) { return assign(aStr); } inline DwString& DwString::operator = (const char* aCstr) { return assign(aCstr); } inline DwString& DwString::operator = (char aChar) { return assign(1, aChar); } inline DwString& DwString::operator += (const DwString& aStr) { return append(aStr); } inline DwString& DwString::operator += (const char* aCstr) { return append(aCstr); } inline DwString& DwString::operator += (char aChar) { return append(1, aChar); } #endif // ! defined(DW_USE_ANSI_STRING) DW_EXPORT DwString operator + (const DwString& aStr1, const DwString& aStr2); DW_EXPORT DwString operator + (const char* aCstr, const DwString& aStr2); DW_EXPORT DwString operator + (char aChar, const DwString& aStr2); DW_EXPORT DwString operator + (const DwString& aStr1, const char* aCstr); DW_EXPORT DwString operator + (const DwString& aStr1, char aChar); DW_EXPORT DwBool operator == (const DwString& aStr1, const DwString& aStr2); DW_EXPORT DwBool operator == (const DwString& aStr1, const char* aCstr); DW_EXPORT DwBool operator == (const char* aCstr, const DwString& aStr2); DW_EXPORT DwBool operator != (const DwString& aStr1, const DwString& aStr2); DW_EXPORT DwBool operator != (const DwString& aStr1, const char* aCstr); DW_EXPORT DwBool operator != (const char* aCstr, const DwString& aStr2); DW_EXPORT DwBool operator < (const DwString& aStr1, const DwString& aStr2); DW_EXPORT DwBool operator < (const DwString& aStr1, const char* aCstr); DW_EXPORT DwBool operator < (const char* aCstr, const DwString& aStr2); DW_EXPORT DwBool operator > (const DwString& aStr1, const DwString& aStr2); DW_EXPORT DwBool operator > (const DwString& aStr1, const char* aCstr); DW_EXPORT DwBool operator > (const char* aCstr, const DwString& aStr2); DW_EXPORT DwBool operator <= (const DwString& aStr1, const DwString& aStr2); DW_EXPORT DwBool operator <= (const DwString& aStr1, const char* aCstr); DW_EXPORT DwBool operator <= (const char* aCstr, const DwString& aStr2); DW_EXPORT DwBool operator >= (const DwString& aStr1, const DwString& aStr2); DW_EXPORT DwBool operator >= (const DwString& aStr1, const char* aCstr); DW_EXPORT DwBool operator >= (const char* aCstr, const DwString& aStr2); DW_EXPORT std::ostream& operator << (std::ostream& aOstrm, const DwString& aStr); //. Writes the contents of {\tt aStr} to the stream {\tt aOstrm}. DW_EXPORT std::istream& getline (std::istream& aIstrm, DwString& aStr, char aDelim); DW_EXPORT std::istream& getline (std::istream& aIstrm, DwString& aStr); DW_EXPORT int DwStrcasecmp(const DwString& aStr1, const DwString& aStr2); DW_EXPORT int DwStrcasecmp(const DwString& aStr1, const char* aCstr); DW_EXPORT int DwStrcasecmp(const char* aCstr, const DwString& aStr2); DW_EXPORT int DwStrncasecmp(const DwString& aStr1, const DwString& aStr2, size_t aLen); DW_EXPORT int DwStrncasecmp(const DwString& aStr, const char* aCstr, size_t aLen); DW_EXPORT int DwStrncasecmp(const char* aCstr, const DwString& aStr, size_t aLen); DW_EXPORT int DwStrcmp(const DwString& aStr1, const DwString& aStr2); DW_EXPORT int DwStrcmp(const DwString& aStr, const char* aCstr); DW_EXPORT int DwStrcmp(const char* aCstr, const DwString& aStr); DW_EXPORT int DwStrncmp(const DwString& aStr1, const DwString& aStr2, size_t aLen); DW_EXPORT int DwStrncmp(const DwString& aStr, const char* aCstr, size_t aLen); DW_EXPORT int DwStrncmp(const char* aCstr, const DwString& aStr, size_t aLen); DW_EXPORT void DwStrcpy(DwString& aStrDest, const DwString& aStrSrc); DW_EXPORT void DwStrcpy(DwString& aStrDest, const char* aCstrSrc); DW_EXPORT void DwStrcpy(char* aCstrDest, const DwString& aStrSrc); DW_EXPORT void DwStrncpy(DwString& aStrDest, const DwString& aStrSrc, size_t aLen); DW_EXPORT void DwStrncpy(DwString& aStrDest, const char* aCstrSrc, size_t aLen); DW_EXPORT void DwStrncpy(char* aCstrDest, const DwString& aStrSrc, size_t aLen); DW_EXPORT char* DwStrdup(const DwString& aStr); #endif mimelib1-1.1.4/mimelib/mimelib/boyermor.h0000644000175000017500000000546111175345261017672 0ustar resivoresivo//============================================================================= // File: boyermor.h // Contents: Declarations for DwBoyerMoore // Maintainer: Doug Sauder // WWW: http://www.fwb.gulf.net/~dwsauder/mimepp.html // // Copyright (c) 1996, 1997 Douglas W. Sauder // All rights reserved. // // IN NO EVENT SHALL DOUGLAS W. SAUDER BE LIABLE TO ANY PARTY FOR DIRECT, // INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF // THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF DOUGLAS W. SAUDER // HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // DOUGLAS W. SAUDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT // NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A // PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" // BASIS, AND DOUGLAS W. SAUDER HAS NO OBLIGATION TO PROVIDE MAINTENANCE, // SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. // //============================================================================= #ifndef DW_BOYERMOR_H #define DW_BOYERMOR_H #include #ifndef DW_CONFIG_H #include #endif #ifndef DW_STRING_H #include #endif //============================================================================= //+ Name DwBoyerMoore -- Class for executing Boyer-Moore string search algorithm //+ Description //. {\tt DwBoyerMoore} implements the Boyer-Moore algorithm for searching //. for a string. The Boyer-Moore algorithm is fast, but requires a bit //. of start-up overhead compared to a brute force algorithm. //============================================================================= // Last modified 1997-08-23 //+ Noentry ~DwBoyerMoore class DW_EXPORT DwBoyerMoore { public: DwBoyerMoore(const char* aCstr); DwBoyerMoore(const DwString& aStr); DwBoyerMoore(const DwBoyerMoore& other); //. Constructs a {\tt DwBoyerMoore} object for searching for a particular //. string. virtual ~DwBoyerMoore(); const DwBoyerMoore & operator=( const DwBoyerMoore & other ); void Assign(const char* aCstr); void Assign(const DwString& aStr); //. Sets the string to search for. size_t FindIn(const DwString& aStr, size_t aPos, bool aCs = true) const; //. Searches for the search string in {\tt aStr} starting at position //. {\tt aPos}. If found, the function returns the first position in //. {\tt aStr} where the search string was found. If not found, the //. function returns {\tt DwString::npos}. Search is case sensitive iff //. {\tt aCs} is true. private: size_t mPatLen; char* mPat; char* mCiPat; unsigned char mSkipAmt[256]; unsigned char mCiSkipAmt[256]; // case insensitive skip table void _Assign(const char* aPat, size_t aPatLen); }; #endif mimelib1-1.1.4/mimelib/mimelib/enum.h0000644000175000017500000001007411175345261016774 0ustar resivoresivo//============================================================================= // File: enum.h // Contents: Declarations of global constants and function prototypes // Maintainer: Doug Sauder // WWW: http://www.fwb.gulf.net/~dwsauder/mimepp.html // // Copyright (c) 1996, 1997 Douglas W. Sauder // All rights reserved. // // IN NO EVENT SHALL DOUGLAS W. SAUDER BE LIABLE TO ANY PARTY FOR DIRECT, // INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF // THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF DOUGLAS W. SAUDER // HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // DOUGLAS W. SAUDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT // NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A // PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" // BASIS, AND DOUGLAS W. SAUDER HAS NO OBLIGATION TO PROVIDE MAINTENANCE, // SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. // //============================================================================= #ifndef DW_ENUM_H #define DW_ENUM_H #ifndef DW_CONFIG_H #include #endif //----------------------------------------------------------------------------- // Enumerated values //----------------------------------------------------------------------------- #if defined(DW_USE_NAMESPACES) namespace DwMime { #else struct DwMime { #endif // Content transfer encoding enum { kCteNull, kCteUnknown, kCte7bit, kCte8bit, kCteBinary, kCteQuotedPrintable, kCteQp = kCteQuotedPrintable, kCteBase64, kCteLast }; // Content types enum { kTypeNull, kTypeUnknown, kTypeText, kTypeMultipart, kTypeMessage, kTypeApplication, kTypeImage, kTypeAudio, kTypeVideo, kTypeModel, kTypeLast }; // Content subtypes enum { kSubtypeNull, kSubtypeUnknown, // Text kSubtypePlain, // RFC-1521 kSubtypeRichtext, // RFC-1341 kSubtypeEnriched, kSubtypeHtml, kSubtypeXVCard, kSubtypeDirectory, kSubtypeVCal, kSubtypeRtf, kSubtypeXDiff, // Multipart kSubtypeMixed, kSubtypeAlternative, kSubtypeDigest, kSubtypeParallel, kSubtypeSigned, kSubtypeEncrypted, kSubtypeReport, kSubtypeRelated, // Message kSubtypeRfc822, kSubtypeDispositionNotification, // Signed content kSubtypePartial, kSubtypeExternalBody, // Application kSubtypePostscript, kSubtypeOctetStream, kSubtypePgpSignature, kSubtypePgpEncrypted, kSubtypePgpClearsigned, kSubtypePkcs7Signature, kSubtypePkcs7Mime, kSubtypeMsTNEF, kSubtypeChiasmusText, // Image kSubtypeJpeg, kSubtypeGif, // Audio kSubtypeBasic, // Video kSubtypeMpeg, // Last kSubtypeLast }; // Well-known header fields enum { kFldNull, kFldUnknown, // RFC-822 kFldBcc, kFldCc, kFldComments, kFldDate, kFldEncrypted, kFldFrom, kFldInReplyTo, kFldKeywords, kFldMessageId, kFldReceived, kFldReferences, kFldReplyTo, kFldResentBcc, kFldResentCc, kFldResentDate, kFldResentFrom, kFldResentMessageId, kFldResentReplyTo, kFldResentSender, kFldResentTo, kFldReturnPath, kFldSender, kFldTo, kFldSubject, // RFC-1036 kFldApproved, kFldControl, kFldDistribution, kFldExpires, kFldFollowupTo, kFldLines, kFldNewsgroups, kFldOrganization, kFldPath, kFldSummary, kFldXref, // RFC-1521 kFldContentDescription, kFldContentId, kFldContentTransferEncoding, kFldCte = kFldContentTransferEncoding, kFldContentType, kFldMimeVersion, // RFC-1544 kFldContentMd5, // RFC-1806 kFldContentDisposition, // Last kFldLast }; // Disposition type (Content-Disposition header field, see RFC-1806) enum { kDispTypeNull, kDispTypeUnknown, kDispTypeInline, kDispTypeAttachment }; #if defined(DW_USE_NAMESPACES) } // end namespace DwMime #else }; // end DwMime class declaration #endif #endif mimelib1-1.1.4/mimelib/mimelib/mediatyp.h0000644000175000017500000002736211175345261017654 0ustar resivoresivo//============================================================================= // File: mediatyp.h // Contents: Declarations for DwMediaType // Maintainer: Doug Sauder // WWW: http://www.fwb.gulf.net/~dwsauder/mimepp.html // // Copyright (c) 1996, 1997 Douglas W. Sauder // All rights reserved. // // IN NO EVENT SHALL DOUGLAS W. SAUDER BE LIABLE TO ANY PARTY FOR DIRECT, // INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF // THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF DOUGLAS W. SAUDER // HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // DOUGLAS W. SAUDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT // NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A // PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" // BASIS, AND DOUGLAS W. SAUDER HAS NO OBLIGATION TO PROVIDE MAINTENANCE, // SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. // //============================================================================= #ifndef DW_MEDIATYP_H #define DW_MEDIATYP_H #ifndef DW_CONFIG_H #include #endif #ifndef DW_STRING_H #include #endif #ifndef DW_FIELDBDY_H #include #endif class DwParameter; //============================================================================= //+ Name DwMediaType -- Class representing a MIME media-type //+ Description //. {\tt DwMediaType} represents a field body for the Content-Type header //. field as described in RFC-2045. This field body specifies the kind of //. data contained in the body of a message or a body part. A media type //. is described by two keywords: a primary type (or just {\it type}) and //. a {\it subtype}. RFC-2046 specifies the seven primary types text, //. multipart, message, image, audio, video, and application. RFC-2077 //. adds the new primary type model. //. //. {\tt DwMediaType} has member functions that allow you to set or get //. the type and subtype as either enumerated values or as strings. It //. also contains a list of {\tt DwParameter} objects that represent the //. parameters of the field body. You can use convenience functions to //. directly access the boundary parameter of a multipart media type, or //. to access the name parameter that is often used with several media //. types, such as application/octet-stream. //. //. Some MIME parsers have problems with folded header fields, and this //. especially seems to be a problem with the Content-Type field. //. To disable folding when the {\tt DwMediaType} object is assembled, //. call the inherited member function {\tt DwFieldBody::SetFolding()} //. with an argument of {\tt DwFalse}. //============================================================================= // Last updated 1997-08-30 //+ Noentry ~DwMediaType //+ Noentry _AddParameter TypeEnumToStr TypeStrToEnum SubtypeEnumToStr //+ Noentry SubtypeStrToEnum DeleteParameterList CopyParameterList //+ Noentry mType mSubtype mTypeStr mSubtypeStr mBoundaryStr mFirstParameter //+ Noentry _PrintDebugInfo mNameStr class DW_EXPORT DwMediaType : public DwFieldBody { public: DwMediaType(); DwMediaType(const DwMediaType& aMediaType); DwMediaType(const DwString& aStr, DwMessageComponent* aParent=0); //. The first constructor is the default constructor, which sets the //. {\tt DwMediaType} object's string representation to the empty string //. and sets its parent to {\tt NULL}. //. //. The second constructor is the copy constructor, which performs //. deep copy of {\tt aMediaType}. //. The parent of the new {\tt DwMediaType} object is set to {\tt NULL}. //. //. The third constructor copies {\tt aStr} to the {\tt DwMediaType} //. object's string representation and sets {\tt aParent} as its parent. //. The virtual member function {\tt Parse()} should be called immediately //. after this constructor in order to parse the string representation. //. Unless it is {\tt NULL}, {\tt aParent} should point to an object of //. a class derived from {\tt DwField}. virtual ~DwMediaType(); const DwMediaType& operator = (const DwMediaType& aMediaType); //. This is the assignment operator, which performs a deep copy of //. {\tt aMediaType}. The parent node of the {\tt DwMediaType} //. object is not changed. virtual void Parse(); //. This virtual function, inherited from {\tt DwMessageComponent}, //. executes the parse method for {\tt DwMediaType} objects. //. It should be called immediately after the string representation //. is modified and before the parts of the broken-down //. representation are accessed. //. //. This function clears the is-modified flag. virtual void Assemble(); //. This virtual function, inherited from {\tt DwMessageComponent}, //. executes the assemble method for {\tt DwMediaType} objects. //. It should be called whenever one of the object's attributes //. is changed in order to assemble the string representation from //. its broken-down representation. It will be called //. automatically for this object by the parent object's //. {\tt Assemble()} member function if the is-modified flag is set. //. //. This function clears the is-modified flag. virtual DwMessageComponent* Clone() const; //. This virtual function, inherited from {\tt DwMessageComponent}, //. creates a new {\tt DwMediaType} object on the free store that //. has the same value as this {\tt DwMediaType} object. The basic //. idea is that of a virtual copy constructor. int Type() const; //. Returns the primary type as an enumerated value. Enumerated values //. are defined for all standard types in the file enum.h. If the type //. is non-standard, {\tt DwMime::kTypeUnknown} is returned. The member //. function {\tt TypeStr()} may be used to get the value of any type, //. standard or non-standard, as a string. void SetType(int aType); //. Sets the primary type from the enumerated value {\tt aType}. //. Enumerated values are defined for all standard types in the file //. enum.h. The member function {\tt SetTypeStr()} may be used to //. set the value of any type, standard or non-standard, from a string. const DwString& TypeStr() const; //. Returns the primary type as a string. void SetTypeStr(const DwString& aStr); //. Sets the primary type from a string. int Subtype() const; //. Returns the subtype as an enumerated value. Enumerated values //. are defined for all standard subtypes in the file enum.h. If //. the subtype is non-standard, {\tt DwMime::kSubtypeUnknown} is //. returned. The member function {\tt SubtypeStr()} may be used //. to get the value of any subtype, standard or non-standard, as //. a string. void SetSubtype(int aSubtype); //. Sets the subtype from the enumerated value {\tt aSubtype}. //. Enumerated values are defined for all standard subtypes in the //. file enum.h. The member function {\tt SetSubtypeStr()} may be //. used to set the value of any subtype, standard or non-standard, //. from a string. const DwString& SubtypeStr() const; //. Returns the subtype as a string. void SetSubtypeStr(const DwString& aStr); //. Sets the subtype from a string. const DwString& Boundary() const; //. For the multipart type only, returns the value of the boundary //. parameter. This member function is a convenience function //. that searches the list of {\tt DwParameter} objects. void SetBoundary(const DwString& aStr); //. For the multipart type only, sets the value of the boundary //. parameter. //. This member function is a convenience function that accesses the //. list of {\tt DwParameter} objects. virtual void CreateBoundary(unsigned aLevel=0); //. For the multipart type only, creates a boundary string. {\tt aLevel} //. indicates the level of a nested multipart body part; if it is //. positive, it is used to form part of the created boundary string. //. This member function is a convenience function that accesses the //. list of child {\tt DwParameter} objects. const DwString& Name() const; //. Returns the value of the "name" parameter, if such a parameter //. is present. The name parameter is often found in several media //. types, including the application/octet-stream media type; it //. suggests a file name for saving to a disk file. (The filename //. parameter in the Content-Disposition header field is an alternative //. way to indicate a file name.) This member function is a convenience //. function that searches the list of {\tt DwParameter} objects. void SetName(const DwString& aStr); //. Sets the value of the "name" parameter. If a name parameter is //. not already present, it is added. The name parameter is often //. found in several media types, including the application/octet-stream //. media type; it suggests a file name for saving to a disk file. //. (The filename parameter in the Content-Disposition header field //. is an alternative way to indicate a file name.) This member //. function is a convenience function that accesses the list of //. {\tt DwParameter} objects. DwParameter* FirstParameter() const; //. Returns the first {\tt DwParameter} object in the list managed by //. this {\tt DwMediaType} object. Use {\tt DwParameter::Next()} to //. iterate through the list. void AddParameter(DwParameter* aParam); //. Adds a {\tt DwParameter} object to the list managed by this //. {\tt DwMediaType} object. static DwMediaType* NewMediaType(const DwString& aStr, DwMessageComponent* aParent); //. Creates a new {\tt DwMediaType} object on the free store. //. If the static data member {\tt sNewMediaType} is {\tt NULL}, //. this member function will create a new {\tt DwMediaType} //. and return it. Otherwise, {\tt NewMediaType()} will call //. the user-supplied function pointed to by {\tt sNewMediaType}, //. which is assumed to return an object from a class derived from //. {\tt DwMediaType}, and return that object. //+ Var sNewMediaType static DwMediaType* (*sNewMediaType)(const DwString&, DwMessageComponent*); //. If {\tt sNewMediaType} is not {\tt NULL}, it is assumed to point to a //. user-supplied function that returns an object from a class derived //. from {\tt DwMediaType}. protected: void _AddParameter(DwParameter* aParam); //. Adds a parameter without setting the is-modified flag. virtual void TypeEnumToStr(); virtual void TypeStrToEnum(); virtual void SubtypeEnumToStr(); virtual void SubtypeStrToEnum(); void DeleteParameterList(); void CopyParameterList(DwParameter* aFirst); int mType; int mSubtype; DwString mTypeStr; DwString mSubtypeStr; DwString mBoundaryStr; DwString mNameStr; DwParameter* mFirstParameter; private: static const char* const sClassName; public: virtual void PrintDebugInfo(std::ostream& aStrm, int aDepth=0) const; //. This virtual function, inherited from {\tt DwMessageComponent}, //. prints debugging information about this object to {\tt aStrm}. //. It will also call {\tt PrintDebugInfo()} for any of its child //. components down to a level of {\tt aDepth}. //. //. This member function is available only in the debug version of //. the library. virtual void CheckInvariants() const; //. Aborts if one of the invariants of the object fails. Use this //. member function to track down bugs. //. //. This member function is available only in the debug version of //. the library. protected: void _PrintDebugInfo(std::ostream& aStrm) const; }; #endif mimelib1-1.1.4/mimelib/mimelib/mimepp.h0000644000175000017500000000546211175345261017324 0ustar resivoresivo//============================================================================= // File: mimepp.h // Contents: MIME++ library include file // Maintainer: Doug Sauder // WWW: http://www.fwb.gulf.net/~dwsauder/mimepp.html // // Copyright (c) 1996, 1997 Douglas W. Sauder // All rights reserved. // // IN NO EVENT SHALL DOUGLAS W. SAUDER BE LIABLE TO ANY PARTY FOR DIRECT, // INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF // THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF DOUGLAS W. SAUDER // HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // DOUGLAS W. SAUDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT // NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A // PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" // BASIS, AND DOUGLAS W. SAUDER HAS NO OBLIGATION TO PROVIDE MAINTENANCE, // SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. // //============================================================================= #ifndef DW_MIMEPP_H #define DW_MIMEPP_H #ifndef DW_CONFIG_H #include #endif #ifndef DW_ENUM_H #include #endif #ifndef DW_ADDRESS_H #include #endif #ifndef DW_ADDRLIST_H #include #endif #ifndef DW_BODY_H #include #endif #ifndef DW_BODYPART_H #include #endif #ifndef DW_BOYERMOR_H #include #endif #ifndef DW_DATETIME_H #include #endif #ifndef DW_DISPTYPE_H #include #endif #ifndef DW_DWSTRING_H #include #endif #ifndef DW_ENTITY_H #include #endif #ifndef DW_FIELD_H #include #endif #ifndef DW_FIELDBDY_H #include #endif #ifndef DW_GROUP_H #include #endif #ifndef DW_HEADER_H #include #endif #ifndef DW_MAILBOX_H #include #endif #ifndef DW_MBOXLIST_H #include #endif #ifndef DW_MECHANSM_H #include #endif #ifndef DW_MEDIATYP_H #include #endif #ifndef DW_MESSAGE_H #include #endif #ifndef DW_MSGCMP_H #include #endif #ifndef DW_MSGID_H #include #endif #ifndef DW_NNTP_H #include #endif #ifndef DW_PARAM_H #include #endif #ifndef DW_POP_H #include #endif #ifndef DW_PROTOCOL_H #include #endif //#ifndef DW_SMTP_H //#include //#endif #ifndef DW_TEXT_H #include #endif #ifndef DW_TOKEN_H #include #endif #ifndef DW_UUENCODE_H #include #endif #ifndef DW_UTILITY_H #include #endif #endif mimelib1-1.1.4/mimelib/mimelib/binhex.h0000644000175000017500000001470511175345261017312 0ustar resivoresivo//============================================================================= // File: binhex.h // Contents: Declarations for DwBinhex // Maintainer: Doug Sauder // WWW: http://www.fwb.gulf.net/~dwsauder/mimepp.html // // Copyright (c) 1996, 1997 Douglas W. Sauder // All rights reserved. // // IN NO EVENT SHALL DOUGLAS W. SAUDER BE LIABLE TO ANY PARTY FOR DIRECT, // INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF // THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF DOUGLAS W. SAUDER // HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // DOUGLAS W. SAUDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT // NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A // PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" // BASIS, AND DOUGLAS W. SAUDER HAS NO OBLIGATION TO PROVIDE MAINTENANCE, // SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. // //============================================================================= #ifndef DW_BINHEX_H #define DW_BINHEX_H #ifndef DW_CONFIG_H #include #endif #ifndef DW_STRING_H #include #endif //============================================================================= //+ Name DwBinhex -- Class for converting files to or from Binhex 4.0 format //+ Description //. {\tt DwBinhex} converts data to or from Binhex 4.0 format. Binhex is a //. format used almost exclusively on Macintosh computers for encoding //. files into text characters for transmission through the mail transport //. system or for archiving on non-Macintosh systems. The format includes //. the file name, file type, file creator, Macintosh Finder flags, data fork, //. resource fork, and checksums. In MIME, the use of Binhex is deprecated; //. applesingle and appledouble are the preferred format for encoding //. Macintosh files. The Binhex 4.0 format is described in RFC-1741. //. Binhex is a widely used, {\it de facto} standard, but it is not an //. official Internet standard. //. //. To use {\tt DwBinhex} for converting a Macintosh file to Binex format, //. call the member functions {\tt SetFileName()}, {\tt SetFileType()}, //. {\tt SetFileCreator()}, {\tt SetFlag1()}, {\tt SetFlag2()}, //. {\tt SetDataFork()}, and {\tt SetResourceFork()} to set the elements //. to be encoded. Any elements that are not set by calling one of the //. member functions are assigned reasonable defaults. Then call the //. {\tt Encode()} member function to actually perform the conversion to //. Binhex. Finally, call {\tt BinhexChars()} to retrieve the Binhex //. characters. //. //. To use {\tt DwBinhex} for converting a Macintosh file from Binhex format, //. call the member function {\tt SetBinhexChars()} to assign the Binhex //. characters to be converted. Then call {\tt Decode()} to actually //. perform the conversion. Finally, call {\tt FileName()}, {\tt FileType()}, //. {\tt FileCreator()}, {\tt Flag1()}, {\tt Flag2()}, {\tt DataFork()}, //. and {\tt ResourceFork()} to extract the decoded elements. //. //. Note: {\tt DwBinhex} does not change the file name in any way. When you //. you are dealing with file names, you should be aware of the fact that //. some filenames that are valid on a Macintosh may cause problems or //. unexpected results on a non-Macintosh system, and vice versa. Such //. problem characters include slash ('/'), colon (':'), space and possibly //. other characters. //============================================================================= // Last modified 1997-08-25 //+ Noentry ~DwBinhex class DW_EXPORT DwBinhex { public: DwBinhex(); //. This is the default constructor. virtual ~DwBinhex(); void Initialize(); //. Resets the object's internal state to its initial state. Call //. this member function to reuse the object for more than one encode //. or decode operation. const char* FileName() const; void SetFileName(const char* aName); //. Gets or sets the file name. The file name is restricted //. to a maximum length of 63 characters. void FileType(char* aBuf) const; void SetFileType(const char* aType); //. Gets or sets the file type. All Macintosh files have a file type, //. which is represented by four bytes. Some examples include "TEXT" //. for a text file, or "APPL" for an application. {\tt aBuf} should //. point to an array of at least four characters. void FileCreator(char* aBuf) const; void SetFileCreator(const char* aType); //. Gets or sets the file creator. Most Macintosh files have a creator, //. which is represented by a signature of four bytes. The creator //. specifies which application to launch when a file's icon is double //. clicked. {\tt aBuf} should point to an array of at least four //. characters. DwUint8 Flag1() const; void SetFlag1(DwUint8 aFlag); //. Gets or sets the first byte of the Macintosh Finder flags. For //. files that originate on non-Macintosh systems, this byte should //. be set to zero (the default). DwUint8 Flag2() const; void SetFlag2(DwUint8 aFlag); //. Gets or sets the second byte of the Macintosh Finder flags. For //. files that originate on non-Macintosh systems, this byte should //. be set to zero (the default). const DwString& DataFork() const; void SetDataFork(const DwString& aStr); //. Gets or sets the data fork for the file. For files that originate //. on non-Macintosh systems, such as a GIF or JPEG file, the file data //. should be set as the data fork. const DwString& ResourceFork() const; void SetResourceFork(const DwString& aStr); //. Gets or sets the resource fork for the file. For files that originate //. on non-Macintosh systems, such as a GIF or JPEG file, the resource //. should be normally be empty. const DwString& BinhexChars() const; void SetBinhexChars(const DwString& aStr); //. Gets or sets the characters of the Binhex encoded file. void Encode(); //. Converts the Macintosh file information to Binhex format. int Decode(); //. Converts the Macintosh file information from Binhex format. Returns //. zero if the decode operation completes successufully; otherwise, //. the function returns -1. private: char mFileName[64]; char mFileType[8]; char mFileCreator[8]; DwUint8 mFlag1; DwUint8 mFlag2; DwString mDataFork; DwString mResourceFork; DwString mBinhexChars; }; #endif mimelib1-1.1.4/mimelib/mimelib/headers.h0000644000175000017500000004233011175345261017443 0ustar resivoresivo//============================================================================= // File: headers.h // Contents: Declarations for DwHeaders // Maintainer: Doug Sauder // WWW: http://www.fwb.gulf.net/~dwsauder/mimepp.html // // Copyright (c) 1996, 1997 Douglas W. Sauder // All rights reserved. // // IN NO EVENT SHALL DOUGLAS W. SAUDER BE LIABLE TO ANY PARTY FOR DIRECT, // INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF // THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF DOUGLAS W. SAUDER // HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // DOUGLAS W. SAUDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT // NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A // PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" // BASIS, AND DOUGLAS W. SAUDER HAS NO OBLIGATION TO PROVIDE MAINTENANCE, // SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. // //============================================================================= #ifndef DW_HEADERS_H #define DW_HEADERS_H #include #include #ifndef DW_CONFIG_H #include #endif #ifndef DW_STRING_H #include #endif #ifndef DW_MSGCMP_H #include #endif #ifndef DW_ENTITY_H #include #endif #ifndef DW_MSGID_H #include #endif #ifndef DW_MAILBOX_H #include #endif #ifndef DW_MEDIATYP_H #include #endif #ifndef DW_DATETIME_H #include #endif #ifndef DW_MECHANSM_H #include #endif #ifndef DW_DISPTYPE_H #include #endif class DwMessage; class DwField; class DwFieldBody; class DwDateTime; class DwMailboxList; class DwAddressList; class DwMediaType; class DwMechanism; class DwText; //============================================================================= //+ Name DwHeaders -- Class representing the collection of header fields in a message or body part //+ Description //. {\tt DwHeaders} represents the collection of {\it header fields} (often //. called just {\it headers}) in an {\it entity} (either a message or body //. part), as described in RFC-822 and RFC-2045. A {\tt DwHeaders} object //. manages a list of {\tt DwField} objects, which represent the individual //. header fields. //. //. In the tree (broken-down) representation of a message, a {\tt DwHeaders} //. object is an intermediate node, having both a parent node and several //. child nodes. The parent node is the {\tt DwEntity} object that contains //. it. The child nodes are the {\tt DwField} objects in the list it manages. //. (See the man page for {\tt DwMessageComponent} for a discussion of //. the tree representation of a message.) //. //. Normally, you do not create a {\tt DwHeaders} object directly, but you //. access it through the {\tt Headers()} member function of {\tt DwEntity}, //. which creates the {\tt DwHeaders} object for you. //. //. While {\tt DwHeaders} has public member functions for managing the list //. of {\tt DwField} objects it contains, you will normally use convenience //. functions to access the field bodies of the header fields directly. //. You can access the field body for a specific well-known header field //. by using the member function {\tt ()}, where {\tt } is //. the field name of the header field with hyphens removed and the first //. word following a hyphen capitalized. For example, to access the field //. body for the "MIME-version" header field, use {\tt MimeVersion()}. //. The member function {\tt ()} will create a header field with //. field name {\tt } if such a header field does not already exist. //. You can check for the existence of a particular well-known header field //. by using the member function {\tt Has()}. For example, to check //. for the existence of the MIME-version header field, use //. {\tt HasMimeVersion()}. Well-known header fields are those documented in //. RFC-822 (standard email), RFC-1036 (USENET messages), RFC-2045 (MIME //. messages), and possibly other RFCs. //. //. In the case of an extension field or user-defined field, you can access //. the field body of the header field by calling the member function //. {\tt FieldBody()} with the field name as its argument. If the extension //. field or user-defined field does not exist, {\tt FieldBody()} will //. create it. You can check for the existence of an extension field or //. user-defined field by using the member function {\tt HasField()} with //. the field name as its argument. //. //. {\tt DwHeaders} has several other member functions provided for the //. sake of completeness that are not required for most applications. //. These functions are documented below. //============================================================================= // Last updated 1997-08-26 //+ Noentry ~DwHeaders sClassName CopyFields mFirstField _AddField class DW_EXPORT DwHeaders : public DwMessageComponent { public: DwHeaders(); DwHeaders(const DwHeaders& aHeaders); DwHeaders(const DwString& aStr, DwMessageComponent* aParent=0); //. The first constructor is the default constructor, which sets the //. {\tt DwHeaders} object's string representation to the empty string //. and sets its parent to {\tt NULL}. //. //. The second constructor is the copy constructor, which performs a //. deep copy of {\tt aHeaders}. //. The parent of the new {\tt DwHeaders} object is set to {\tt NULL}. //. //. The third constructor copies {\tt aStr} to the {\tt DwHeaders} //. object's string representation and sets {\tt aParent} as its parent. //. The virtual member function {\tt Parse()} should be called immediately //. after this constructor in order to parse the string representation. //. Unless it is {\tt NULL}, {\tt aParent} should point to an object of a class //. derived from {\tt DwEntity}. virtual ~DwHeaders(); const DwHeaders& operator = (const DwHeaders& aHeaders); //. This is the assignment operator, which performs a deep copy of //. {\tt aHeaders}. The parent node of the {\tt DwHeaders} object //. is not changed. virtual void Parse(); //. This virtual function, inherited from {\tt DwMessageComponent}, //. executes the parse method for {\tt DwHeaders} objects. The parse //. method creates or updates the broken-down representation from the //. string representation. For {\tt DwHeaders} objects, //. {\tt DwHeaders::Parse()} parses the string representation to create //. a list of {\tt DwField} objects. This member function also calls //. the {\tt Parse()} member function of each {\tt DwField} object in //. its list. //. //. You should call this member function after you set or modify the //. string representation, and before you access any of the header fields. //. //. This function clears the is-modified flag. virtual void Assemble(); //. This virtual function, inherited from {\tt DwMessageComponent}, //. executes the assemble method for {\tt DwHeaders} objects. The //. assemble method creates or updates the string representation from //. the broken-down representation. That is, the assemble method //. builds the string representation from its list of {\tt DwField} //. objects. Before it builds the string representation, this function //. first calls the {\tt Assemble()} member function of each {\tt DwField} //. object in its list. //. //. You should call this member function after you set or modify any //. of the header fields, and before you retrieve the string //. representation. //. //. This function clears the is-modified flag. virtual DwMessageComponent* Clone() const; //. This virtual function, inherited from {\tt DwMessageComponent}, //. creates a new {\tt DwHeaders} on the free store that has the same //. value as this {\tt DwHeaders} object. The basic idea is that of //. a virtual copy constructor. DwBool HasBcc() const; DwBool HasCc() const; DwBool HasComments() const; DwBool HasDate() const; DwBool HasEncrypted() const; DwBool HasFrom() const; DwBool HasInReplyTo() const; DwBool HasKeywords() const; DwBool HasMessageId() const; DwBool HasReceived() const; DwBool HasReferences() const; DwBool HasReplyTo() const; DwBool HasResentBcc() const; DwBool HasResentCc() const; DwBool HasResentDate() const; DwBool HasResentFrom() const; DwBool HasResentMessageId() const; DwBool HasResentReplyTo() const; DwBool HasResentSender() const; DwBool HasResentTo() const; DwBool HasReturnPath() const; DwBool HasSender() const; DwBool HasSubject() const; DwBool HasTo() const; // RFC-822 fields // DwBool HasApproved() const; DwBool HasControl() const; DwBool HasDistribution() const; DwBool HasExpires() const; DwBool HasFollowupTo() const; DwBool HasLines() const; DwBool HasNewsgroups() const; DwBool HasOrganization() const; DwBool HasPath() const; DwBool HasSummary() const; DwBool HasXref() const; // RFC-1036 fields // DwBool HasContentDescription() const; DwBool HasContentId() const; DwBool HasContentTransferEncoding() const; DwBool HasCte() const; DwBool HasContentType() const; DwBool HasMimeVersion() const; // RFC-2045 fields // DwBool HasContentDisposition() const; // RFC-1806 // //. Each member function in this group returns a boolean value indicating //. whether a particular well-known header field is present in this //. object's collection of header fields. DwBool HasField(const char* aFieldName) const; DwBool HasField(const DwString& aFieldName) const; //. Returns true if the header field specified by {\tt aFieldName} is //. present in this object's collection of header fields. These member //. functions are used for extension fields or user-defined fields. DwAddressList& Bcc(); DwAddressList& Cc(); DwText& Comments(); DwDateTime& Date(); DwText& Encrypted(); DwMailboxList& From(); DwText& InReplyTo(); DwText& Keywords(); DwMsgId& MessageId(); DwText& Received(); DwText& References(); DwAddressList& ReplyTo(); DwAddressList& ResentBcc(); DwAddressList& ResentCc(); DwDateTime& ResentDate(); DwMailboxList& ResentFrom(); DwMsgId& ResentMessageId(); DwAddressList& ResentReplyTo(); DwMailbox& ResentSender(); DwAddressList& ResentTo(); DwAddress& ReturnPath(); DwMailbox& Sender(); DwText& Subject(); DwAddressList& To(); // RFC-822 fields // DwText& Approved(); DwText& Control(); DwText& Distribution(); DwText& Expires(); DwText& FollowupTo(); DwText& Lines(); DwText& Newsgroups(); DwText& Organization(); DwText& Path(); DwText& Summary(); DwText& Xref(); // RFC-1036 fields (USENET messages) // DwText& ContentDescription(); DwMsgId& ContentId(); DwMechanism& ContentTransferEncoding(); DwMechanism& Cte(); DwMediaType& ContentType(); DwText& MimeVersion(); // RFC-2045 fields // DwDispositionType& ContentDisposition(); // RFC-1806 Content-Disposition field // //. Each member function in this group returns a reference to a //. {\tt DwFieldBody} object for a particular header field. If the //. header field does not already exist, it is created. Use the //. corresponding {\tt Has()} function to test if the header //. field already exists without creating it. DwFieldBody& FieldBody(const DwString& aFieldName); //. Returns a reference to the {\tt DwFieldBody} object for a particular //. header field with field name {\tt aFieldName}. If the header field //. does not already exist, it is created. Use {\tt HasField()} //. to test if the header field already exists without creating it. //. This member function allows access to extension fields or //. user-defined fields. std::vector AllFieldBodies(const DwString& aFieldName); //. Returns a vector of pointers to the {\tt DwFieldBody} objects for //. all header fields with field name {\tt aFieldName}. If the header //. field does not already exist, it is created. Use {\tt HasField()} //. to test if the header field already exists without creating it. //. This member function allows access to extension fields or //. user-defined fields. int NumFields() const; //. Returns the number of {\tt DwField} objects contained by this //. {\tt DwHeaders} object. DwField* FirstField() const; //. Returns a pointer to the first {\tt DwField} object contained by //. this {\tt DwHeaders} object. Use this member function to begin an //. iteration over the entire list of {\tt DwField} objects. //. Continue the iteration by calling {\tt DwField::Next()} on each //. {\tt DwField} object. DwField* FindField(const char* aFieldName) const; DwField* FindField(const DwString& aFieldName) const; //. Searches for a header field by its field name. Returns {\tt NULL} //. if the field is not found. This is an {\it advanced} function: //. most applications should use the {\tt ()} or //. {\tt Has()} family of functions. void AddOrReplaceField(DwField* aField); //. Adds a {\tt DwField} object to the list. If a header field with //. the same field name already exists, it is replaced by the new //. header field. //. //. {\tt DwHeaders} takes responsibility for deleting the added //. {\tt DwField} object. //. //. This is an advanced function. Consider using the member functions //. {\tt ()} (e.g. {\tt To()}, {\tt ContentType()}, and so on) //. and {\tt FieldBody()} to add header fields. void AddField(DwField* aField); //. Adds a {\tt DwField} object to the list. If a header field with //. the same field name already exists, it is {\it not} replaced; //. thus, duplicate header fields may occur when using this member //. function. (This is what you want for some header fields, such as //. the "Received" header field). //. //. {\tt DwHeaders} takes responsibility for deleting the added //. {\tt DwField} object. //. //. This is an advanced function. Consider using the member functions //. {\tt ()} (e.g. {\tt To()}, {\tt ContentType()}, and so on) //. and {\tt FieldBody()} for adding header fields. void AddFieldAt(int aPos, DwField* aField); //. This member functions follows the semantics of {\tt AddField()} //. except that {\tt aPos} specifies a position for adding the field. //. A position of 1 indicates the beginning of the list. A position of //. 0 indicates the end of the list. //. //. This is an advanced function. Consider using the member functions //. {\tt ()} (e.g. {\tt To()}, {\tt ContentType()}, and so on) //. and {\tt FieldBody()} for adding header fields. void RemoveField(DwField* aField); //. Removes the {\tt DwField} object from the list. The {\tt DwField} //. object is not deleted. void DeleteAllFields(); //. Removes all {\tt DwField} objects from the list and deletes them. static DwHeaders* NewHeaders(const DwString& aStr, DwMessageComponent* aParent); //. Creates a new {\tt DwHeaders} object on the free store. //. If the static data member {\tt sNewHeaders} is {\tt NULL}, //. this member function will create a new {\tt DwHeaders} //. and return it. Otherwise, {\tt NewHeaders()} will call //. the user-supplied function pointed to by {\tt sNewHeaders}, //. which is assumed to return an object from a class derived from //. {\tt DwHeaders}, and return that object. //+ Var sNewHeaders static DwHeaders* (*sNewHeaders)(const DwString&, DwMessageComponent*); //. If {\tt sNewHeaders} is not {\tt NULL}, it is assumed to point to a //. user-supplied function that returns an object from a class derived from //. {\tt DwHeaders}. protected: void _AddField(DwField* aField); //. Add field but don't set the is-modified flag DwField* mFirstField; DwField* mLastField; protected: static const char* const sClassName; void CopyFields(DwField* aFirst); public: virtual void PrintDebugInfo(std::ostream& aStrm, int aDepth=0) const; //. This virtual function, inherited from {\tt DwMessageComponent}, //. prints debugging information about this object to {\tt aStrm}. //. It will also call {\tt PrintDebugInfo()} for any of its child //. components down to a level of {\tt aDepth}. //. //. This member function is available only in the debug version of //. the library. virtual void CheckInvariants() const; //. Aborts if one of the invariants of the object fails. Use this //. member function to track down bugs. //. //. This member function is available only in the debug version of //. the library. private: void _PrintDebugInfo(std::ostream& aStrm) const; }; inline DwField* DwHeaders::FirstField() const { return mFirstField; } #endif mimelib1-1.1.4/mimelib/mimelib/datetime.h0000644000175000017500000002606511175345261017633 0ustar resivoresivo//============================================================================= // File: datetime.h // Contents: Declarations for DwDateTime // Maintainer: Doug Sauder // WWW: http://www.fwb.gulf.net/~dwsauder/mimepp.html // // Copyright (c) 1996, 1997 Douglas W. Sauder // All rights reserved. // // IN NO EVENT SHALL DOUGLAS W. SAUDER BE LIABLE TO ANY PARTY FOR DIRECT, // INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF // THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF DOUGLAS W. SAUDER // HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // DOUGLAS W. SAUDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT // NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A // PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" // BASIS, AND DOUGLAS W. SAUDER HAS NO OBLIGATION TO PROVIDE MAINTENANCE, // SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. // //============================================================================= #ifndef DW_DATETIME_H #define DW_DATETIME_H #include #ifndef DW_CONFIG_H #include #endif #ifndef DW_FIELDBDY_H #include #endif //============================================================================= //+ Name DwDateTime -- Class representing an RFC-822 date-time //+ Description //. {\tt DwDatetime} represents a {\it date-time} as described in RFC-822 //. and RFC-1123. The parse method for {\tt DwDateTime} parses the //. string representation to extract the year, month, day, hour, minute, //. second, and time zone. {\tt DwDateTime} provides member functions //. to set or get the individual components of the date-time. //============================================================================= // Last modified 1997-08-23 //+ Noentry ~DwDateTime mYear mMonth mDay mHour mMinute mSecond mZone //+ Noentry sDefaultZone sIsDefaultZoneSet _PrintDebugInfo class DW_EXPORT DwDateTime : public DwFieldBody { public: DwDateTime(); DwDateTime(const DwDateTime& aDateTime); DwDateTime(const DwString& aStr, DwMessageComponent* aParent=0); //. The first constructor is the default constructor, which assigns //. the current date and time as reported by the operating system. //. //. The second constructor is the copy constructor. The parent of //. the new {\tt DwDateTime} object is set to {\tt NULL}. //. //. The third constructor sets {\tt aStr} as the {\tt DwDateTime} //. object's string representation and sets {\tt aParent} as its parent. //. The virtual member function {\tt Parse()} should be called after //. this constructor to extract the date and time information from the //. string representation. Unless it is {\tt NULL}, {\tt aParent} should //. point to an object of a class derived from {\tt DwField}. virtual ~DwDateTime(); const DwDateTime& operator = (const DwDateTime& aDateTime); //. This is the assignment operator, which sets this {\tt DwDateTime} //. object to the same value as {\tt aDateTime}. virtual void Parse(); //. This virtual function, inherited from {\tt DwMessageComponent}, //. executes the parse method for {\tt DwDateTime} objects. The parse //. method creates or updates the broken-down representation from the //. string representation. For {\tt DwDateTime} objects, the parse //. method parses the string representation to extract the year, //. month, day, hour, minute, second, and time zone. //. //. This function clears the is-modified flag. virtual void Assemble(); //. This virtual function, inherited from {\tt DwMessageComponent}, //. executes the assemble method for {\tt DwDateTime} objects. //. It should be called whenever one of the object's attributes //. is changed in order to assemble the string representation from //. its broken-down representation. It will be called //. automatically for this object by the parent object's //. {\tt Assemble()} member function if the is-modified flag is set. //. //. This function clears the is-modified flag. virtual DwMessageComponent* Clone() const; //. This virtual function, inherited from {\tt DwMessageComponent}, //. creates a new {\tt DwDateTime} on the free store that has the same //. value as this {\tt DwDateTime} object. The basic idea is that of //. a virtual copy constructor. DwUint32 AsUnixTime() const; //. Returns the date and time as a UNIX (POSIX) time, defined as the //. number of seconds elapsed since 1 Jan 1970 00:00:00 UTC. void FromUnixTime(DwUint32 aTime); //. Sets the date and time from {\tt aTime}, interpreted as the number of //. of seconds elapsed since 1 Jan 1970 00:00:00 UTC. void FromCalendarTime(time_t aTime); //. Sets the date and time from {\tt aTime}, which is assumed to be in a //. format compatible with the native {\tt time()} ANSI C function. //. For most UNIX systems, this function is the same as the function //. {\tt FromUnixTime()}. (For efficiency, use {\tt FromUnixTime()} //. instead of {\tt FromCalendarTime()} if possible). DwInt32 DateAsJulianDayNum() const; //. Returns the Julian Day Number, defined as the number of days elapsed //. since 1 Jan 4713 BC. The JDN is calculated directly from the values //. of the year, month, and day; time zone information is ignored. void DateFromJulianDayNum(DwInt32 aJdn); //. Sets the year, month, and day from {\tt aJdn}, interpreted as a Julian //. Day Number. By definition, the JDN is the number of days elapsed //. since 1 Jan 4713 BC. This member function ignores time zone //. information. DwInt32 TimeAsSecsPastMidnight() const; //. Returns the number of seconds past midnight. The value is //. calculated directly from the values of the hour, minute, and //. second; time zone information is ignored. void TimeFromSecsPastMidnight(DwInt32 aSecs); //. Sets the hour, minute, and second from {\tt aSecs}, interpreted as the //. number of seconds elapsed since midnight. This member function //. ignores time zone information. The argument {\tt aSecs} should be in //. the range 0 to 86399, inclusive. int Year() const; //. Returns the four digit year, e.g. 1997. void SetYear(int aYear); //. Sets the year from {\tt aYear}, which should be a four digit year. int Month() const; //. Returns the month. Values range from 1 to 12. void SetMonth(int aMonth); //. Sets the month from {\tt aMonth}, which should be in the range 1 //. to 12. int Day() const; //. Returns the day of the month. Values range from 1 to 31. void SetDay(int aDay); //. Sets the day of the month from {\tt aDay}. int Hour() const; //. Returns the hour according to the 24 hour clock. //. Values range from 0 to 23. void SetHour(int aHour); //. Sets the hour from {\tt aHour} based on the 24-hour clock. {\tt aHour} //. should be in the range 0 to 23. int Minute() const; //. Returns the minute. Values range from 0 to 59. void SetMinute(int aMinute); //. Sets the minute from {\tt aMinute}, which should be in the range 0 //. to 59. int Second() const; //. Returns the second. Values range from 0 to 59. void SetSecond(int aSecond); //. Sets the second from {\tt aSecond}, which should be in the range 0 //. to 59. int Zone() const; //. Returns the time zone as the diffence in minutes between local time //. and Coordinated Universal Time (UTC or GMT). void SetZone(int aZone); //. Sets the time zone from {\tt aZone}, interpreted as the time difference //. in minutes between local time and Coordinated Universal Time //. (UTC, or GMT). static void SetDefaultZone(int aZone); //. Sets the default time zone. {\tt aZone} should be the time difference //. in minutes between local time and Coordinated Universal Time //. (UTC, or GMT). The value is used to set the time zone for any //. objects created using the default constructor. static DwDateTime* NewDateTime(const DwString&, DwMessageComponent*); //. Creates a new {\tt DwDateTime} object on the free store. //. If the static data member {\tt sNewDateTime} is {\tt NULL}, //. this member function will create a new {\tt DwDateTime} //. and return it. Otherwise, {\tt NewDateTime()} will call //. the user-supplied function pointed to by {\tt sNewDateTime}, //. which is assumed to return an object from a class derived from //. {\tt DwDateTime}, and return that object. //+ Var sNewDateTime static DwDateTime* (*sNewDateTime)(const DwString&, DwMessageComponent*); //. If {\tt sNewDateTime} is not {\tt NULL}, it is assumed to point to a //. user-supplied function that returns an object from a class derived //. from {\tt DwDateTime}. protected: void _FromUnixTime(DwUint32 aTime); //. Like {\tt FromUnixTime()}, but doesn't set the is-modified flag. void _FromCalendarTime(time_t aTime); //. Like {\tt FromCalendarTime()}, but doesn't set the is-modified flag. int mYear; int mMonth; int mDay; int mHour; int mMinute; int mSecond; int mZone; static int sDefaultZone; static int sIsDefaultZoneSet; private: static const char* const sClassName; void Init(); //. Initialization code common to all constructors. public: virtual void PrintDebugInfo(std::ostream& aStrm, int aDepth=0) const; //. This virtual function, inherited from {\tt DwMessageComponent}, //. prints debugging information about this object to {\tt aStrm}. //. //. This member function is available only in the debug version of //. the library. virtual void CheckInvariants() const; //. Aborts if one of the invariants of the object fails. Use this //. member function to track down bugs. //. //. This member function is available only in the debug version of //. the library. protected: void _PrintDebugInfo(std::ostream& aStrm) const; }; inline int DwDateTime::Year() const { return mYear; } inline int DwDateTime::Month() const { return mMonth; } inline int DwDateTime::Day() const { return mDay; } inline int DwDateTime::Hour() const { return mHour; } inline int DwDateTime::Minute() const { return mMinute; } inline int DwDateTime::Second() const { return mSecond; } inline int DwDateTime::Zone() const { return mZone; } inline void DwDateTime::SetYear(int aYear) { mYear = aYear; SetModified(); } inline void DwDateTime::SetMonth(int aMonth) { mMonth = aMonth; SetModified(); } inline void DwDateTime::SetDay(int aDay) { mDay = aDay; SetModified(); } inline void DwDateTime::SetHour(int aHour) { mHour = aHour; SetModified(); } inline void DwDateTime::SetMinute(int aMinute) { mMinute = aMinute; SetModified(); } inline void DwDateTime::SetSecond(int aSecond) { mSecond = aSecond; SetModified(); } inline void DwDateTime::SetZone(int aZone) { mZone = aZone; SetModified(); } #endif mimelib1-1.1.4/mimelib/mimelib/address.h0000644000175000017500000001305311175345261017455 0ustar resivoresivo//============================================================================= // File: address.h // Contents: Declarations for DwAddress // Maintainer: Doug Sauder // WWW: http://www.fwb.gulf.net/~dwsauder/mimepp.html // // Copyright (c) 1996, 1997 Douglas W. Sauder // All rights reserved. // // IN NO EVENT SHALL DOUGLAS W. SAUDER BE LIABLE TO ANY PARTY FOR DIRECT, // INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF // THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF DOUGLAS W. SAUDER // HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // DOUGLAS W. SAUDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT // NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A // PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" // BASIS, AND DOUGLAS W. SAUDER HAS NO OBLIGATION TO PROVIDE MAINTENANCE, // SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. // //============================================================================= #ifndef DW_ADDRESS_H #define DW_ADDRESS_H #ifndef DW_CONFIG_H #include #endif #ifndef DW_FIELDBDY_H #include #endif #ifndef DW_TOKEN_H #include #endif class DwAddressList; //============================================================================= //+ Name DwAddress -- Abstract class representing an RFC-822 address //+ Description //. {\tt DwAddress} represents an {\it address} as described in RFC-822. //. You may not instantiate objects of type {\tt DwAddress}, since //. {\tt DwAddress} is an abstract base class. Instead, you must instantiate //. objects of type {\tt DwMailbox} or {\tt DwGroup}, which are subclasses //. of {\tt DwAddress}. //. //. To determine the actual type of a {\tt DwAddress} object, you can use //. the member functions {\tt IsMailbox()} and {\tt IsGroup()}. //. //. If the string representation assigned to a {\tt DwAddress} is improperly //. formed, the parse method will fail. To determine if the parse method //. failed, call the member function {\tt IsValid()}. //. //. A {\tt DwAddress} object can be contained in list. To get the next //. {\tt DwAddress} object in the list, call the member function {\tt Next()}. //============================================================================= // Last modified 1997-08-23 //+ Noentry ~DwAddress mNext mIsValid sClassName _PrintDebugInfo class DW_EXPORT DwAddress : public DwFieldBody { friend class DwAddressList; public: virtual ~DwAddress(); DwBool IsMailbox() const; //. Returns true value if this object is a {\tt DwMailbox}. DwBool IsGroup() const; //. Returns true value if this object is a {\tt DwGroup}. inline DwBool IsValid() const; //. Returns true value if the last parse was successful. //. Returns false if the last parse failed (bad address) or //. the {\tt Parse()} member function was never called. DwAddress* Next() const; //. Returns the next {\tt DwAddress} object in the list when the object //. is included in a list of addresses. The function is used when //. iterating a list. void SetNext(DwAddress* aAddress); //. Sets the next {\tt DwAddress} object in the list. This member function //. generally should not be used, since {\tt DwAddressList} has member //. functions to manage its list of {\tt DwAddress} objects. protected: DwAddress(); DwAddress(const DwAddress& aAddr); DwAddress(const DwString& aStr, DwMessageComponent* aParent=0); //. The first constructor is the default constructor, which sets the //. {\tt DwAddress} object's string representation to the empty string //. and sets its parent to {\tt NULL}. //. //. The second constructor is the copy constructor, which copies the //. string representation and all attributes from {\tt aAddress}. //. The parent of the new {\tt DwAddress} object is set to {\tt NULL}. //. //. The third constructor copies {\tt aStr} to the {\tt DwAddress} //. object's string representation and sets {\tt aParent} as its parent. //. The virtual member function {\tt Parse()} should be called immediately //. after this constructor in order to parse the string representation. //. Unless it is {\tt NULL}, {\tt aParent} should point to an object of //. a class derived from {\tt DwField}. const DwAddress& operator = (const DwAddress& aAddr); //. This is the assignment operator, which performs a deep copy of //. {\tt aAddr}. The parent node of the {\tt DwAddress} object //. is not changed. int mIsValid; //. This data member is set to true if the parse method was successful. private: DwAddress* mNext; static const char* const sClassName; public: virtual void PrintDebugInfo(std::ostream& aStrm, int aDepth=0) const; //. This virtual function, inherited from {\tt DwMessageComponent}, //. prints debugging information about this object to {\tt aStrm}. //. It will also call {\tt PrintDebugInfo()} for any of its child //. components down to a level of {\tt aDepth}. //. //. This member function is available only in the debug version of //. the library. virtual void CheckInvariants() const; //. Aborts if one of the invariants of the object fails. Use this //. member function to track down bugs. //. //. This member function is available only in the debug version of //. the library. protected: void _PrintDebugInfo(std::ostream& aStrm) const; }; inline DwBool DwAddress::IsValid() const { return mIsValid != 0; } #endif mimelib1-1.1.4/mimelib/mimelib/config.h0000644000175000017500000001257711175345261017307 0ustar resivoresivo//============================================================================= // File: config.h // Contents: Declarations of macros for configuring the library // Maintainer: Doug Sauder // WWW: http://www.fwb.gulf.net/~dwsauder/mimepp.html // // Copyright (c) 1996, 1997 Douglas W. Sauder // All rights reserved. // // IN NO EVENT SHALL DOUGLAS W. SAUDER BE LIABLE TO ANY PARTY FOR DIRECT, // INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF // THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF DOUGLAS W. SAUDER // HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // DOUGLAS W. SAUDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT // NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A // PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" // BASIS, AND DOUGLAS W. SAUDER HAS NO OBLIGATION TO PROVIDE MAINTENANCE, // SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. // //============================================================================= #ifndef DW_CONFIG_H #define DW_CONFIG_H //----------------------------------------------------------------------------- // Platform // // Make sure that the following lines define either DW_UNIX or DW_WIN32. //----------------------------------------------------------------------------- #if defined(_WIN32) || defined(__WIN32__) # define DW_WIN32 #endif #if defined(__unix__) || defined(__unix) || defined(_AIX) || defined(__NetBSD__) || defined(__APPLE__) # define DW_UNIX #endif //----------------------------------------------------------------------------- // End of line characters // // Uncomment one of the following to indicate whether you want the library to // use LF or CR LF as the end of line characters. // // I strongly recommend using LF ('\n') alone as the end of line character, // since that is the normal end of line character for C and C++ libraries. // Then you can do the conversion to and from the CR LF end of line // characters at the interface to the transport system. //----------------------------------------------------------------------------- #define DW_EOL_LF //#define DW_EOL_CRLF #if defined(DW_EOL_CRLF) # define DW_EOL "\r\n" #elif defined(DW_EOL_LF) # define DW_EOL "\n" #else # error "Must define DW_EOL_CRLF, DW_EOL_LF" #endif //----------------------------------------------------------------------------- // C++ namespaces // // Uncomment the following line if you want the DwMime namespace to be defined. // If the namespace is not defined, then enums are specified as part of a // DwMime class. //----------------------------------------------------------------------------- //#define DW_USE_NAMESPACES //----------------------------------------------------------------------------- // C++ library string class // // Uncomment the following line if you want DwString typedef-ed to the // ANSI/ISO string class. // // *** Important: This option is not working or not fully tested yet *** //----------------------------------------------------------------------------- //#define DW_USE_ANSI_STRING //----------------------------------------------------------------------------- // bool type // // Uncomment the following line if you want DwBool typedef-ed to int instead // of bool. //----------------------------------------------------------------------------- //#define DW_NO_BOOL #if defined(DW_NO_BOOL) typedef int DwBool; #define DwFalse 0 #define DwTrue 1 #else typedef bool DwBool; #define DwFalse false #define DwTrue true #endif //----------------------------------------------------------------------------- // DLL vs static library // // Win32 users: Uncomment out the following line to create a static library // instead of a DLL. //----------------------------------------------------------------------------- // #define DW_NO_DLL #if defined(DW_WIN32) && !defined(DW_NO_DLL) # ifdef DW_IMPLEMENTATION # define DW_EXPORT __declspec(dllexport) # else # define DW_EXPORT __declspec(dllimport) # endif #else # define DW_EXPORT #endif //----------------------------------------------------------------------------- // Type definitions // // Make sure the following types are accurate for your machine. //----------------------------------------------------------------------------- #if defined(__BCPLUSPLUS__) && !defined(__WIN32__) # define DW_STD_16_BIT #endif #if defined(__alpha) || defined(__sgi) # define DW_STD_64_BIT #endif #if !defined(DW_STD_16_BIT) && !defined(DW_STD_64_BIT) # define DW_STD_32_BIT #endif typedef char DwChar7; // type for ASCII characters typedef unsigned char DwChar8; // type for 8-bit characters typedef signed char DwInt8; // type for 8-bit signed integers typedef unsigned char DwUint8; // type for 8-bit unsigned integers #if defined(DW_STD_16_BIT) typedef int DwInt16; // 16-bit signed integers typedef unsigned int DwUint16; // 16-bit unsigned integers typedef long DwInt32; // 32-bit signed integers typedef unsigned long DwUint32; // 32-bit unsigned integers #elif defined(DW_STD_32_BIT) typedef short DwInt16; typedef unsigned short DwUint16; typedef int DwInt32; typedef unsigned int DwUint32; #elif defined(DW_STD_64_BIT) typedef short DwInt16; typedef unsigned short DwUint16; typedef int DwInt32; typedef unsigned int DwUint32; #endif #endif mimelib1-1.1.4/mimelib/mimelib/bodypart.h0000644000175000017500000001411211175345261017651 0ustar resivoresivo//============================================================================= // File: bodypart.h // Contents: Declarations for DwBodyPart // Maintainer: Doug Sauder // WWW: http://www.fwb.gulf.net/~dwsauder/mimepp.html // // Copyright (c) 1996, 1997 Douglas W. Sauder // All rights reserved. // // IN NO EVENT SHALL DOUGLAS W. SAUDER BE LIABLE TO ANY PARTY FOR DIRECT, // INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF // THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF DOUGLAS W. SAUDER // HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // DOUGLAS W. SAUDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT // NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A // PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" // BASIS, AND DOUGLAS W. SAUDER HAS NO OBLIGATION TO PROVIDE MAINTENANCE, // SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. // //============================================================================= #ifndef DW_BODYPART_H #define DW_BODYPART_H #ifndef DW_CONFIG_H #include #endif #ifndef DW_STRING_H #include #endif #ifndef DW_ENTITY_H #include #endif class DwMessage; class DwEntity; class DwBody; //============================================================================= //+ Name DwBodyPart -- Class representing a MIME body-part //+ Description //. {\tt DwBodyPart} represents a {\it body part}, as described in RFC-2045 //. and RFC-2046. A body part is an {\it entity}, so it has a collection //. of headers and a {\it body}. A body part is different from a {\it message} //. in that a body part is part of a multipart body. //. //. In MIME++, a {\tt DwBodyPart} is a subclass of {\tt DwEntity}; therefore, //. it contains both a {\tt DwHeaders} object and a {\tt DwBody} object, //. and it is contained in a multipart {\tt DwBody} object. //. //. As with {\tt DwMessage}, most of the functionality of {\tt DwBodyPart} is //. implemented by the abstract class {\tt DwEntity}. //============================================================================= // Last modified 1997-08-23 //+ Noentry ~DwBodyPart _PrintDebugInfo mNext sClassName class DW_EXPORT DwBodyPart : public DwEntity { public: DwBodyPart(); DwBodyPart(const DwBodyPart& aPart); DwBodyPart(const DwEntity& aPart); DwBodyPart(const DwString& aStr, DwMessageComponent* aParent=0); //. The first constructor is the default constructor, which sets the //. {\tt DwBodyPart} object's string representation to the empty string //. and sets its parent to {\tt NULL}. //. //. The second constructor is the copy constructor, which performs //. a deep copy of {\tt aPart}. //. The parent of the new {\tt DwBodyPart} object is set to {\tt NULL}. //. //. The third constructor copies {\tt aStr} to the {\tt DwBodyPart} //. object's string representation and sets {\tt aParent} as its parent. //. The virtual member function {\tt Parse()} should be called immediately //. after this constructor in order to parse the string representation. //. Unless it is {\tt NULL}, {\tt aParent} should point to an object of //. a class derived from {\tt DwBody}. virtual ~DwBodyPart(); const DwBodyPart& operator = (const DwBodyPart& aPart); //. This is the assignment operator, which performs a deep copy of //. {\tt aPart}. The parent node of the {\tt DwBodyPart} object //. is not changed. virtual DwMessageComponent* Clone() const; //. This virtual function, inherited from {\tt DwMessageComponent}, //. creates a new {\tt DwBodyPart} on the free store that has the same //. value as this {\tt DwBodyPart} object. The basic idea is that of //. a virtual copy constructor. static DwBodyPart* NewBodyPart(const DwString& aStr, DwMessageComponent* aParent); //. Creates a new {\tt DwBodyPart} on the free store. //. If the static data member {\tt sNewBodyPart} is {\tt NULL}, //. this member function will create a new {\tt DwBodyPart} //. and return it. Otherwise, {\tt NewBodyPart()} will call //. the user-supplied function pointed to by {\tt sNewBodyPart}, //. which is assumed to return an object from a class derived from //. {\tt DwBodyPart}, and return that object. DwBodyPart* Next() const; //. This member function returns the next {\tt DwBodyPart} object //. following this {\tt DwBodyPart} in the list of {\tt DwBodyPart} //. objects contained in a multipart {\tt DwBody}. void SetNext(const DwBodyPart* aPart); //. This advanced function sets {\tt aPart} as the next {\tt DwBodyPart} //. object following this {\tt DwBodyPart} in the list of {\tt DwBodyPart} //. objects contained in a multipart {\tt DwBody}. Since {\tt DwBody} //. contains a member function for adding a {\tt DwBodyPart} object to //. its list, this function should be avoided for most applications. //+ Var sNewBodyPart static DwBodyPart* (*sNewBodyPart)(const DwString&, DwMessageComponent*); //. If {\tt sNewBodyPart} is not {\tt NULL}, it is assumed to point to a //. user-supplied function that returns an object from a class //. derived from {\tt DwBodyPart}. public: virtual void PrintDebugInfo(std::ostream& aStrm, int aDepth=0) const; //. This virtual function, inherited from {\tt DwMessageComponent}, //. prints debugging information about this object to {\tt aStrm}. //. It will also call {\tt PrintDebugInfo()} for any of its child //. components down to a level of {\tt aDepth}. //. //. This member function is available only in the debug version of //. the library. virtual void CheckInvariants() const; //. Aborts if one of the invariants of the object fails. Use this //. member function to track down bugs. //. //. This member function is available only in the debug version of //. the library. protected: void _PrintDebugInfo(std::ostream& aStrm) const; private: const DwBodyPart* mNext; static const char* const sClassName; }; #endif mimelib1-1.1.4/mimelib/mimelib/body.h0000644000175000017500000002727411175345261016777 0ustar resivoresivo//============================================================================= // File: body.h // Contents: Declarations for DwBody // Maintainer: Doug Sauder // WWW: http://www.fwb.gulf.net/~dwsauder/mimepp.html // // Copyright (c) 1996, 1997 Douglas W. Sauder // All rights reserved. // // IN NO EVENT SHALL DOUGLAS W. SAUDER BE LIABLE TO ANY PARTY FOR DIRECT, // INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF // THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF DOUGLAS W. SAUDER // HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // DOUGLAS W. SAUDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT // NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A // PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" // BASIS, AND DOUGLAS W. SAUDER HAS NO OBLIGATION TO PROVIDE MAINTENANCE, // SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. // //============================================================================= #ifndef DW_BODY_H #define DW_BODY_H #ifndef DW_CONFIG_H #include #endif #ifndef DW_STRING_H #include #endif #ifndef DW_ENTITY_H #include #endif class DwMessage; class DwEntity; class DwBodyPart; //============================================================================= //+ Name DwBody -- Class representing a MIME message body //+ Description //. {\tt DwBody} represents a {\it body}, as described in RFC-2045. A body //. is always part of an {\it entity}, which could be either a {\it message} //. or a {\it body part}. An entity has a collection of {\it header fields} //. and a body. If the content type of a body is ``multipart,'' then the //. body contains one or more body parts. If the content type is ``message,'' //. then the body contains an encapsulated message. In all content types, //. the body contains a string of characters. //. //. In MIME++, a {\tt DwBody} object is contained in a {\tt DwEntity} object. //. The {\tt DwBody} object may contain a discrete body consisting only of a //. string of characters, or it may be a composite body, consisting of several //. contained {\tt DwBodyPart} objects or a single contained {\tt DwMessage} //. object. The only reliable way to determine the type of {\tt DwBody} is //. to access the Content-Type header field from the {\tt DwHeaders} object //. of the {\tt DwEntity} that contains it. For this reason, a {\tt DwBody} //. should always be part of a {\tt DwEntity}. //. //. In the tree (broken-down) representation of a message, a {\tt DwBody} //. object can be an intermediate node, having both a parent node and //. one or more child nodes, or a leaf node, having a parent but no child //. nodes. In either case, the parent node is the {\tt DwEntity} object //. that contains it. If it is an intermediate node, it must be of type //. multipart with {\tt DwBodyPart} objects as child nodes, or of type //. message with a single {\tt DwMessage} object as its child node. //. //. Normally, you do not create a {\tt DwBody} object directly, but you //. access it through the {\tt Body()} member function of {\tt DwEntity}, //. which creates the {\tt DwBody} object for you. //. //. To add a {\tt DwBodyPart} to a multipart {\tt DwBody}, use the member //. function {\tt AddBodyPart()}. To iterate over the {\tt DwBodyParts} //. contained in multipart {\tt DwBody}, get the first {\tt DwBodyPart} //. by calling {\tt FirstBodyPart()}. Then get the following {\tt DwBodyParts} //. by calling {\tt DwBodyPart::Next()} on the current {\tt DwBodyPart}. //. To get the {\tt DwMessage} contained in a {\tt Body} with message //. content type, call {\tt Message()}. //============================================================================= // Last modified 1997-08-23 //+ Noentry ~DwBody sClassName DeleteBodyParts CopyBodyParts _PrintDebugInfo class DW_EXPORT DwBody : public DwMessageComponent { friend class DwHeaders; friend class DwEntity; friend class DwBodyPart; public: DwBody(); DwBody(const DwBody& aBody); DwBody(const DwString& aStr, DwMessageComponent* aParent=0); //. The first constructor is the default constructor, which sets the //. {\tt DwBody} object's string representation to the empty string //. and sets its parent to {\tt NULL}. //. //. The second constructor is the copy constructor, which performs //. a deep copy of {\tt aBody}. //. The parent of the new {\tt DwBody} object is set to {\tt NULL}. //. //. The third constructor copies {\tt aStr} to the {\tt DwBody} //. object's string representation and sets {\tt aParent} as its parent. //. The virtual member function {\tt Parse()} should be called immediately //. after this constructor in order to parse the string representation. //. Unless it is {\tt NULL}, {\tt aParent} should point to an object of //. a class derived from {\tt DwEntity}. virtual ~DwBody(); const DwBody& operator = (const DwBody& aBody); //. This is the assignment operator, which performs a deep copy of //. {\tt aBody}. The parent node of the {\tt DwBody} object //. is not changed. virtual void Parse(); //. This virtual function, inherited from {\tt DwMessageComponent}, //. executes the parse method for {\tt DwBody} objects. The parse //. method creates or updates the broken-down representation from the //. string representation. For a multipart {\tt DwBody} object, the //. parse method creates a collection of {\tt DwBodyPart} objects. //. For a message {\tt DwBody}, the parse method creates a single //. {\tt DwMessage} object. For any other type of {\tt DwBody}, //. the parse method does nothing. This member function calls the //. {\tt Parse()} member function of any objects it creates. //. //. Note: If the {\tt DwBody} object has no parent node -- that is, //. it is not contained by a {\tt DwEntity} object -- then the parse //. method does nothing, since it is unable to determine the type of //. body. //. //. You should call this member function after you set or modify the //. string representation, and before you access a contained //. {\tt DwBodyPart} or {\tt DwMessage}. //. //. This function clears the is-modified flag. virtual void Assemble(); //. This virtual function, inherited from {\tt DwMessageComponent}, //. executes the assemble method for {\tt DwBody} objects. The //. assemble method creates or updates the string representation //. from the broken-down representation. Only {\tt DwBody} objects //. with content type of multipart or message require assembling. //. In either case, the {\tt DwBody} object must be able to find the //. headers of the message or body part that contains it. Therefore, //. if the {\tt DwBody} object is not the child of a {\tt DwEntity} //. ({\it i.e.}, {\tt DwMessage} or {\tt DwBodyPart}) object, the //. {\tt DwBody} cannot be assembled because the content type cannot //. be determined. //. //. This function calls the {\tt Parse()} member function of any //. {\tt DwBodyPart} or {\tt DwMessage} object it contains. //. //. You should call this member function after you add a {\tt DwBodyPart} //. object to a multipart body, or add a {\tt DwMessage} object to a //. message body, and before you access the object's string representation. //. //. This function clears the is-modified flag. virtual DwMessageComponent* Clone() const; //. This virtual function, inherited from {\tt DwMessageComponent}, //. creates a new {\tt DwBody} on the free store that has the same //. value as this {\tt DwBody} object. The basic idea is that of //. a virtual copy constructor. DwBodyPart* FirstBodyPart() const; //. For a multipart {\tt DwBody}, this member function returns the //. first contained {\tt DwBodyPart} object. //. Use {\tt DwBodyPart::Next()} to iterate through the list of //. {\tt DwBodyPart}s. void AddBodyPart(DwBodyPart* aPart); //. For a multipart {\tt DwBody}, this member function appends a //. {\tt DwBodyPart} object to the list. Any {\tt DwBodyPart} objects //. added to a {\tt DwBody} object's list will be deleted by the //. {\tt DwBody} object's destructor. void RemoveBodyPart(DwBodyPart* aPart); //. For a multipart {\tt DwBody}, this member function removes a //. {\tt DwBodyPart} object from the list. The caller is responsible //. for deleting the bodypart afterwards! DwMessage* Message() const; //. For a {\tt DwBody} with content type of message, this member function //. returns the {\tt DwMessage} encapsulated in it. void SetMessage(DwMessage* aMessage); //. For a {\tt DwBody} with content type of message, this member function //. sets the {\tt DwMessage} object it contains. static DwBody* NewBody(const DwString& aStr, DwMessageComponent* aParent); //. Creates a new {\tt DwBody} object on the free store. //. If the static data member {\tt sNewBody} is {\tt NULL}, //. this member function will create a new {\tt DwBody} //. and return it. Otherwise, {\tt NewBody()} will call //. the user-supplied function pointed to by {\tt sNewBody}, //. which is assumed to return an object from a class derived from //. {\tt DwBody}, and return that object. //+ Var sNewBody static DwBody* (*sNewBody)(const DwString&, DwMessageComponent*); //. If {\tt sNewBody} is not {\tt NULL}, it is assumed to point to a //. user-supplied function that returns an object from a class //. derived from {\tt DwBody}. protected: DwString mBoundaryStr; //. A cache for the boundary string, which is obtained from the //. headers associated with this body. DwString mPreamble; //. Contains the preamble -- the text preceding the first boundary -- //. in a ``multipart/*'' media type. DwString mEpilogue; //. Contains the epilogue -- the text following the last boundary -- //. in a ``multipart/*'' media type. DwBodyPart* mFirstBodyPart; //. Points to the first body part in a ``multipart/*'' media type. //. Is {\tt NULL} if there are no body parts. DwMessage* mMessage; //. Points to the contained message, in a ``message/*'' media type. static const char* const sClassName; void _AddBodyPart(DwBodyPart*); //. Adds a body part to a multipart body. This function differs //. from {\tt AddBodyPart} in that it does not set the is-modified //. flag. void _RemoveBodyPart(DwBodyPart*); //. Removes a body part from a multipart body. This function differs //. from {\tt RemoveBodyPart} in that it does not set the is-modified //. flag. void _SetMessage(DwMessage*); //. Sets a message to a body. This function differs from //. {\tt SetMessage()} in that it does not set the is-modified //. flag. void CopyBodyParts(const DwBodyPart* aFirst); public: void DeleteBodyParts(); virtual void PrintDebugInfo(std::ostream& aStrm, int aDepth=0) const; //. This virtual function, inherited from {\tt DwMessageComponent}, //. prints debugging information about this object to {\tt aStrm}. //. It will also call {\tt PrintDebugInfo()} for any of its child //. components down to a level of {\tt aDepth}. //. //. This member function is available only in the debug version of //. the library. virtual void CheckInvariants() const; //. Aborts if one of the invariants of the object fails. Use this //. member function to track down bugs. //. //. This member function is available only in the debug version of //. the library. protected: void _PrintDebugInfo(std::ostream& aStrm) const; }; #endif mimelib1-1.1.4/mimelib/mimelib/message.h0000644000175000017500000001255311175345261017460 0ustar resivoresivo//============================================================================= // File: message.h // Contents: Declarations for DwMessage // Maintainer: Doug Sauder // WWW: http://www.fwb.gulf.net/~dwsauder/mimepp.html // // Copyright (c) 1996, 1997 Douglas W. Sauder // All rights reserved. // // IN NO EVENT SHALL DOUGLAS W. SAUDER BE LIABLE TO ANY PARTY FOR DIRECT, // INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF // THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF DOUGLAS W. SAUDER // HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // DOUGLAS W. SAUDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT // NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A // PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" // BASIS, AND DOUGLAS W. SAUDER HAS NO OBLIGATION TO PROVIDE MAINTENANCE, // SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. // //============================================================================= #ifndef DW_MESSAGE_H #define DW_MESSAGE_H #ifndef DW_CONFIG_H #include #endif #ifndef DW_ENTITY_H #include #endif //============================================================================= //+ Name DwMessage -- Class representing an RFC-822/MIME message //+ Description //. {\tt DwMessage} represents an RFC-822/MIME {\it message}. //. //. A {\it message} contains both a collection of {\it header fields} and //. a {\it body}. In the terminology of RFC-2045, the general term for the //. headers-body combination is {\it entity}. In MIME++, {\tt DwMessage} //. is a direct subclass of {\tt DwEntity}, and therefore contains both //. a {\tt DwHeaders} object and a {\tt DwBody} object. //. //. In the tree (broken-down) representation of message, a {\tt DwMessage} //. object is almost always a root node, having child nodes but no parent node. //. The child nodes are the {\tt DwHeaders} object and the {\tt DwBody} object //. it contains. A {\tt DwMessage} may sometimes be an intermediate node. In //. this special case, the parent node is a {\tt DwBody} object of type //. "message/*" and the {\tt DwMessage} object represents an encapsulated //. message. //. //. To access the contained {\tt DwHeaders} object, use the inherited member //. function {\tt DwEntity::Headers()}. To access the contained {\tt DwBody} //. object, use the inherited member function {\tt DwEntity::Body()}. //============================================================================= // Last modified 1997-08-30 //+ Noentry ~DwMessage _PrintDebugInfo class DW_EXPORT DwMessage : public DwEntity { public: DwMessage(); DwMessage(const DwMessage& aMessage); DwMessage(const DwString& aStr, DwMessageComponent* aParent=0); //. The first constructor is the default constructor, which sets the //. {\tt DwMessage} object's string representation to the empty string //. and sets its parent to {\tt NULL}. //. //. The second constructor is the copy constructor, which performs //. a deep copy of {\tt aMessage}. //. The parent of the new {\tt DwMessage} object is set to {\tt NULL}. //. //. The third constructor copies {\tt aStr} to the {\tt DwMessage} //. object's string representation and sets {\tt aParent} as its parent. //. The virtual member function {\tt Parse()} should be called immediately //. after this constructor in order to parse the string representation. virtual ~DwMessage(); const DwMessage& operator = (const DwMessage& aMessage); //. This is the assignment operator, which performs a deep copy of //. {\tt aMessage}. The parent node of the {\tt DwMessage} object //. is not changed. virtual DwMessageComponent* Clone() const; //. This virtual function, inherited from {\tt DwMessageComponent}, //. creates a new {\tt DwMessage} on the free store that has the same //. value as this {\tt DwMessage} object. The basic idea is that of //. a ``virtual copy constructor.'' static DwMessage* NewMessage(const DwString& aStr, DwMessageComponent* aParent); //. Creates a new {\tt DwMessage} object on the free store. //. If the static data member {\tt sNewMessage} is {\tt NULL}, //. this member function will create a new {\tt DwMessage} //. and return it. Otherwise, {\tt NewMessage()} will call //. the user-supplied function pointed to by {\tt sNewMessage}, //. which is assumed to return an object from a class derived from //. {\tt DwMessage}, and return that object. //+ Var sNewMessage static DwMessage* (*sNewMessage)(const DwString&, DwMessageComponent*); //. If {\tt sNewMessage} is not {\tt NULL}, it is assumed to point //. to a user supplied function that returns an object from a class //. derived from {\tt DwMessage}. private: static const char* const sClassName; public: virtual void PrintDebugInfo(std::ostream& aStrm, int aDepth=0) const; //. This virtual function, inherited from {\tt DwMessageComponent}, //. prints debugging information about this object to {\tt aStrm}. //. It will also call {\tt PrintDebugInfo()} for any of its child //. components down to a level of {\tt aDepth}. //. //. This member function is available only in the debug version of //. the library. protected: void _PrintDebugInfo(std::ostream& aStrm) const; }; #endif mimelib1-1.1.4/mimelib/LICENSE0000644000175000017500000004312211175345261015246 0ustar resivoresivo GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. mimelib1-1.1.4/mimelib/basicmsg.h0000644000175000017500000001213411175345261016201 0ustar resivoresivo//============================================================================= // File: basicmsg.h // Contents: Declarations for BasicMessage // Maintainer: Doug Sauder // WWW: http://www.fwb.gulf.net/~dwsauder/mimepp.html // // Copyright (c) 1996, 1997 Douglas W. Sauder // All rights reserved. // // IN NO EVENT SHALL DOUGLAS W. SAUDER BE LIABLE TO ANY PARTY FOR DIRECT, // INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF // THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF DOUGLAS W. SAUDER // HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // DOUGLAS W. SAUDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT // NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A // PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" // BASIS, AND DOUGLAS W. SAUDER HAS NO OBLIGATION TO PROVIDE MAINTENANCE, // SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. // //============================================================================= // BasicMessage is a wrapper class that serves two purposes. First, it // hides many of the underlying details of the class library, making the // library easier to use. Second, it provides good example code to show // you how to create your own customized wrapper classes. // BasicMessage contains a DwMessage by reference. The reason BasicMessage // "has-a" DwMessage and not "is-a" DwMessage is because we can assign // the DwMessage to an appropriately specialized subclass of BasicMessage // *after* the DwMessage is parsed. For example, after we parse a DwMessage, // we can determine that it is a multipart and assign it to a // MultipartMessage instead of a BasicMessage. #ifndef BASICMSG_H #define BASICMSG_H #ifndef MIMEPP_H #include #endif class BasicMessage { public: // Use this constructor to create a new message BasicMessage(); // Use this constructor to create a wrapper for a DwMessage that has // been parsed. BasicMessage takes responsibility for deleting the // DwMessage object passed to the constructor, therefore, make sure // it is allocated on the free store. BasicMessage(DwMessage* aMsg); virtual ~BasicMessage(); // Replace the contained DwMessage with a new DwMessage. Note: // + The previous DwMessage will be deleted. // + The BasicMessage destructor will delete the DwMessage passed as an // argument. // Use this function to set a parsed DwMessage for a BasicMessage that // was created using the default constructor. void TakeMessage(DwMessage* aMsg); // Return the BasicMessage contents as a string const DwString& AsString(); // Set fields that are either automatically set (Message-id) // or that do not change from one message to another (MIME-Version). // We make it a virtual function so it can be easily overridden in // a subclass. In your own subclass, or your customized version of // this class, you may want to set the date field automatically to // the current date and time in this member function. virtual void SetAutomaticFields(); // Get or set the 'Date' header field const DwString& DateStr() const; DwUint32 Date() const; void SetDate(DwUint32 aUnixTime); // Get or set the 'To' header field const DwString& To() const; void SetTo(const DwString& aStr); // Get or set the 'Cc' header field const DwString& Cc() const; void SetCc(const DwString& aStr); // Get or set the 'Bcc' header field const DwString& Bcc() const; void SetBcc(const DwString& aStr); // Get or set the 'From' header field const DwString& From() const; void SetFrom(const DwString& aStr); // Get or set the 'Subject' header field const DwString& Subject() const; void SetSubject(const DwString& aStr); // Get or set the 'Content-Type' header field // + The member functions that involve enumerated types (ints) // will work only for well-known types or subtypes. // Type const DwString& TypeStr() const; int Type() const; void SetTypeStr(const DwString& aStr); void SetType(int aType); // Subtype const DwString& SubtypeStr() const; int Subtype() const; void SetSubtypeStr(const DwString& aStr); void SetSubtype(int aSubtype); // Get or set the 'Content-Transfer-Encoding' header field // + The member functions that involve enumerated types (ints) // will work only for well-known encodings const DwString& ContentTransferEncodingStr() const; int ContentTransferEncoding() const; void SetContentTransferEncodingStr(const DwString& aStr); void SetContentTransferEncoding(int aCte); // Cte is short for ContentTransferEncoding. // These functions are an alternative to the ones with longer names. const DwString& CteStr() const; int Cte() const; void SetCteStr(const DwString& aStr); void SetCte(int aCte); // Get or set the message body const DwString& Body() const; void SetBody(const DwString& aStr); protected: DwMessage* mMessage; DwString mEmptyString; }; #endif mimelib1-1.1.4/mimelib/attach.cpp0000644000175000017500000001337111175345261016214 0ustar resivoresivo//============================================================================= // File: attach.cpp // Contents: Definitions for MessageWithAttachments // Maintainer: Doug Sauder // WWW: http://www.fwb.gulf.net/~dwsauder/mimepp.html // // Copyright (c) 1996, 1997 Douglas W. Sauder // All rights reserved. // // IN NO EVENT SHALL DOUGLAS W. SAUDER BE LIABLE TO ANY PARTY FOR DIRECT, // INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF // THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF DOUGLAS W. SAUDER // HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // DOUGLAS W. SAUDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT // NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A // PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" // BASIS, AND DOUGLAS W. SAUDER HAS NO OBLIGATION TO PROVIDE MAINTENANCE, // SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. // //============================================================================= #include #include #include #include #include #include "attach.h" MessageWithAttachments::MessageWithAttachments() { } MessageWithAttachments::~MessageWithAttachments() { } void MessageWithAttachments::SetText(const DwString& aStr) { // Create a body part and set the necessary fields MultipartBodyPart part; part.SetType(DwMime::kTypeText); part.SetSubtype(DwMime::kSubtypePlain); part.SetCte(DwMime::kCte7bit); // Set the string as the body of the body part part.SetBody(aStr); // Set this body part as the first one SetBodyPart(0, part); } int MessageWithAttachments::NumberOfAttachments() const { int n = NumberOfParts() - 1; return (n >= 0) ? n : 0; } void MessageWithAttachments::Attach7bitFile(const char* aFilename, int aType, int aSubtype) { // Get the file contents DwString str; PutFileInString(aFilename, str); // Create a body part and set the necessary fields MultipartBodyPart part; part.SetType(aType); part.SetSubtype(aSubtype); part.SetCte(DwMime::kCte7bit); // Set content-disposition to attachment, with filename parameter // (see RFC-1806 for information on this *experimental* header field) DwString contDisp = "attachment; filename="; contDisp += '\"'; contDisp += aFilename; contDisp += '\"'; part.SetContentDisposition(contDisp); // Set the file contents as the body of the body part part.SetBody(str); // Make sure this is not the first part, since that is reserved for // the text if (NumberOfParts() == 0) { SetBodyPart(1, part); } else { AddBodyPart(part); } } void MessageWithAttachments::Attach8bitFile(const char* aFilename, int aType, int aSubtype) { // Get the file contents DwString str; PutFileInString(aFilename, str); // Encode using quoted-printable encoding DwString encStr; DwEncodeQuotedPrintable(str, encStr); // Create a body part and set the necessary fields MultipartBodyPart part; part.SetType(aType); part.SetSubtype(aSubtype); part.SetCte(DwMime::kCteQuotedPrintable); // Set content-disposition to attachment, with filename parameter // (see RFC-1806 for information on this *experimental* header field) DwString contDisp = "attachment; filename="; contDisp += '\"'; contDisp += aFilename; contDisp += '\"'; part.SetContentDisposition(contDisp); // Set the encoded file contents as the body of the body part part.SetBody(encStr); // Make sure this is not the first part, since that is reserved for // the text if (NumberOfParts() == 0) { SetBodyPart(1, part); } else { AddBodyPart(part); } } void MessageWithAttachments::AttachBinaryFile(const char* aFilename, int aType, int aSubtype) { // Get the file contents DwString str; PutFileInString(aFilename, str); // Encode using base64 encoding DwString encStr; DwEncodeBase64(str, encStr); // Create a body part and set the necessary fields MultipartBodyPart part; part.SetType(aType); part.SetSubtype(aSubtype); part.SetCte(DwMime::kCteBase64); // Set content-disposition to attachment, with filename parameter // (see RFC-1806 for information on this *experimental* header field) DwString contDisp = "attachment; filename="; contDisp += '\"'; contDisp += aFilename; contDisp += '\"'; part.SetContentDisposition(contDisp); // Set the encoded file contents as the body of the body part part.SetBody(encStr); // Make sure this is not the first part, since that is reserved for // the text if (NumberOfParts() == 0) { SetBodyPart(1, part); } else { AddBodyPart(part); } } int MessageWithAttachments::PutFileInString(const char* aFilename, DwString& str) { // Get the file size struct stat statBuf; int k = stat(aFilename, &statBuf); if (k < 0) { str = ""; return -1; } int fileSize = (int) statBuf.st_size; // Allocate a buffer int bufSize = fileSize + 8; // a little elbow room added char* buf = new char[bufSize]; // Read the file into the buffer FILE* fp = fopen(aFilename, "rb"); if (fp == 0) { delete[] buf; str = ""; return -1; } int len = 0; while (1) { int ch = getc(fp); if (feof(fp) || len == fileSize) { break; } buf[len++] = ch; } buf[len] = 0; fclose(fp); // Place the buffer in the string str.TakeBuffer(buf, bufSize, 0, len); return 0; } mimelib1-1.1.4/mimelib/COPYRIGHT0000644000175000017500000000124211175345261015531 0ustar resivoresivoCopyright (c) 1996, 1997 Douglas W. Sauder All rights reserved. IN NO EVENT SHALL DOUGLAS W. SAUDER BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF DOUGLAS W. SAUDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. DOUGLAS W. SAUDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND DOUGLAS W. SAUDER HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. mimelib1-1.1.4/mimelib/group.cpp0000644000175000017500000001377311175345261016112 0ustar resivoresivo//============================================================================= // File: group.cpp // Contents: Definitions for DwGroup // Maintainer: Doug Sauder // WWW: http://www.fwb.gulf.net/~dwsauder/mimepp.html // // Copyright (c) 1996, 1997 Douglas W. Sauder // All rights reserved. // // IN NO EVENT SHALL DOUGLAS W. SAUDER BE LIABLE TO ANY PARTY FOR DIRECT, // INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF // THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF DOUGLAS W. SAUDER // HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // DOUGLAS W. SAUDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT // NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A // PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" // BASIS, AND DOUGLAS W. SAUDER HAS NO OBLIGATION TO PROVIDE MAINTENANCE, // SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. // //============================================================================= #define DW_IMPLEMENTATION #include #include #include #include #include #include #include const char* const DwGroup::sClassName = "DwGroup"; DwGroup* (*DwGroup::sNewGroup)(const DwString&, DwMessageComponent*) = 0; DwGroup* DwGroup::NewGroup(const DwString& aStr, DwMessageComponent* aParent) { if (sNewGroup) { return sNewGroup(aStr, aParent); } else { return new DwGroup(aStr, aParent); } } DwGroup::DwGroup() { mMailboxList = DwMailboxList::NewMailboxList("", this); mClassId = kCidGroup; mClassName = sClassName; } DwGroup::DwGroup(const DwGroup& aGroup) : DwAddress(aGroup), mGroupName(aGroup.mGroupName) { mMailboxList = (DwMailboxList*) aGroup.mMailboxList->Clone(); mMailboxList->SetParent(this); mClassId = kCidGroup; mClassName = sClassName; } DwGroup::DwGroup(const DwString& aStr, DwMessageComponent* aParent) : DwAddress(aStr, aParent) { mMailboxList = DwMailboxList::NewMailboxList("", this); mClassId = kCidGroup; mClassName = sClassName; } DwGroup::~DwGroup() { delete mMailboxList; } const DwGroup& DwGroup::operator = (const DwGroup& aGroup) { if (this == &aGroup) return *this; DwAddress::operator = (aGroup); mGroupName = aGroup.mGroupName; delete mMailboxList; mMailboxList = (DwMailboxList*) aGroup.mMailboxList->Clone(); // *mMailboxList = *aGroup.mMailboxList; return *this; } const DwString& DwGroup::GroupName() const { return mGroupName; } const DwString& DwGroup::Phrase() const { return mGroupName; } void DwGroup::SetGroupName(const DwString& aName) { mGroupName = aName; } void DwGroup::SetPhrase(const DwString& aPhrase) { mGroupName = aPhrase; } DwMailboxList& DwGroup::MailboxList() const { return *mMailboxList; } void DwGroup::Parse() { mIsModified = 0; mGroupName = ""; int isGroupNameNull = 1; if (mMailboxList) { delete mMailboxList; } mMailboxList = DwMailboxList::NewMailboxList("", this); mIsValid = 0; DwRfc822Tokenizer tokenizer(mString); int type = tokenizer.Type(); int ch; // Everything up to the first ':' is the group name int done = 0; while (!done && type != eTkNull) { switch (type) { case eTkSpecial: ch = tokenizer.Token()[0]; switch (ch) { case ':': done = 1; } break; case eTkQuotedString: case eTkAtom: if (isGroupNameNull) { isGroupNameNull = 0; } else { mGroupName += " "; } mGroupName += tokenizer.Token(); break; } ++tokenizer; type = tokenizer.Type(); } // Find mailbox list, which ends with ';' DwTokenString tokenString(mString); tokenString.SetFirst(tokenizer); done = 0; while (!done && type != eTkNull) { if (type == eTkSpecial && tokenizer.Token()[0] == ';') { tokenString.ExtendTo(tokenizer); break; } ++tokenizer; type = tokenizer.Type(); } if (mMailboxList) { delete mMailboxList; } mMailboxList = DwMailboxList::NewMailboxList(tokenString.Tokens(), this); mMailboxList->Parse(); if (mGroupName.length() > 0) { mIsValid = 1; } else { mIsValid = 0; } } void DwGroup::Assemble() { if (!mIsModified) return; if (mGroupName.length() == 0) { mIsValid = 0; mString = ""; return; } mMailboxList->Assemble(); mString = ""; mString += mGroupName; mString += ":"; mString += mMailboxList->AsString(); mString += ";"; mIsModified = 0; } DwMessageComponent* DwGroup::Clone() const { return new DwGroup(*this); } #if defined (DW_DEBUG_VERSION) void DwGroup::PrintDebugInfo(std::ostream& aStrm, int aDepth) const { aStrm << "------------ Debug info for DwGroup class ------------\n"; _PrintDebugInfo(aStrm); int depth = aDepth - 1; depth = (depth >= 0) ? depth : 0; if (aDepth == 0 || depth > 0) { mMailboxList->PrintDebugInfo(aStrm, depth); } } #else void DwGroup::PrintDebugInfo(std::ostream&, int) const {} #endif // defined (DW_DEBUG_VERSION) #if defined (DW_DEBUG_VERSION) void DwGroup::_PrintDebugInfo(std::ostream& aStrm) const { DwAddress::_PrintDebugInfo(aStrm); aStrm << "Group name: " << mGroupName << '\n'; aStrm << "Mailbox list: " << mMailboxList->ObjectId() << '\n'; } #else void DwGroup::_PrintDebugInfo(std::ostream& ) const {} #endif // defined (DW_DEBUG_VERSION) void DwGroup::CheckInvariants() const { #if defined (DW_DEBUG_VERSION) DwAddress::CheckInvariants(); mGroupName.CheckInvariants(); mMailboxList->CheckInvariants(); assert((DwMessageComponent*) this == mMailboxList->Parent()); #endif // defined (DW_DEBUG_VERSION) } mimelib1-1.1.4/mimelib/dw_date.cpp0000644000175000017500000004702411175345261016361 0ustar resivoresivo//============================================================================= // File: dw_date.cpp // Contents: Date parsing function // Maintainer: Doug Sauder // WWW: http://www.fwb.gulf.net/~dwsauder/mimepp.html // // Copyright (c) 1996, 1997 Douglas W. Sauder // All rights reserved. // // IN NO EVENT SHALL DOUGLAS W. SAUDER BE LIABLE TO ANY PARTY FOR DIRECT, // INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF // THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF DOUGLAS W. SAUDER // HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // DOUGLAS W. SAUDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT // NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A // PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" // BASIS, AND DOUGLAS W. SAUDER HAS NO OBLIGATION TO PROVIDE MAINTENANCE, // SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. // //============================================================================= /* * For maximum code reuse, the functions in this file are written in C. */ #include #include #include #include static int CommentLength(const char *str) { int ch, pos, level, quoteNext, done, len; level = 0; quoteNext = 0; pos = 0; len = 0; ch = str[pos]; done = 0; while (1) { switch (ch) { case 0: len = pos; done = 1; break; case '\\': quoteNext = 1; break; case '(': if (!quoteNext) { ++level; } quoteNext = 0; break; case ')': if (!quoteNext) { --level; if (level == 0) { len = pos + 1; done = 1; } } quoteNext = 0; break; default: quoteNext = 0; } if (done) { break; } ++pos; ch = str[pos]; } return len; } /* * ParseRfc822Date() -- Parse a date in RFC-822 (RFC-1123) format * * If the parsing succeeds: * - tms is set to contain the year, month, day, hour, minute, and second * - z is set to contain the time zone in minutes offset from UTC * - 0 is returned * If the parsing fails: * - (-1) is returned * - the information in tms and z is undefined */ #ifdef __cplusplus extern "C" #endif int ParseRfc822Date(const char *str, struct tm *tms, int *z) { int pos, ch, n, sgn, numZoneDigits; int day=1, month=0, year=1970, hour=0, minute=0, second=0, zone=0; int isValid = 1; if (!str) { return -1; } /* * Ignore optional day of the week. */ /* * Day -- one or two digits */ /* -- skip over non-digits */ pos = 0; ch = str[pos]; while (ch && !('0' <= ch && ch <= '9')) { if (ch == '(') { pos += CommentLength(&str[pos]); } else { ++pos; } ch = str[pos]; } /* -- convert next one or two digits */ n = -1; if ('0' <= ch && ch <= '9') { n = ch - '0'; ++pos; ch = str[pos]; } if ('0' <= ch && ch <= '9') { n *= 10; n += ch - '0'; ++pos; ch = str[pos]; } if (1 <= n && n <= 31) { day = n; } else { isValid = 0; } /* * Month. Use case-insensitive string compare for added robustness */ /* -- skip over chars to first possible month char */ while (ch && !('A' <= ch && ch <= 'S') && !('a' <= ch && ch <= 's')) { if (ch == '(') { pos += CommentLength(&str[pos]); } else { ++pos; } ch = str[pos]; } /* -- convert the month name */ n = -1; switch (ch) { case 'A': case 'a': /* Apr */ if ((str[pos+1] == 'p' || str[pos+1] == 'P') && (str[pos+2] == 'r' || str[pos+2] == 'R')) { n = 3; pos += 3; ch = str[pos]; } /* Aug */ else if ((str[pos+1] == 'u' || str[pos+1] == 'U') && (str[pos+2] == 'g' || str[pos+2] == 'G')) { n = 7; pos += 3; ch = str[pos]; } break; case 'D': case 'd': /* Dec */ if ((str[pos+1] == 'e' || str[pos+1] == 'E') && (str[pos+2] == 'c' || str[pos+2] == 'C')) { n = 11; pos += 3; ch = str[pos]; } break; case 'F': case 'f': /* Feb */ if ((str[pos+1] == 'e' || str[pos+1] == 'E') && (str[pos+2] == 'b' || str[pos+2] == 'B')) { n = 1; pos += 3; ch = str[pos]; } break; case 'J': case 'j': /* Jan */ if ((str[pos+1] == 'a' || str[pos+1] == 'A') && (str[pos+2] == 'n' || str[pos+2] == 'N')) { n = 0; pos += 3; ch = str[pos]; } /* Jul */ else if ((str[pos+1] == 'u' || str[pos+1] == 'U') && (str[pos+2] == 'l' || str[pos+2] == 'L')) { n = 6; pos += 3; ch = str[pos]; } /* Jun */ else if ((str[pos+1] == 'u' || str[pos+1] == 'U') && (str[pos+2] == 'n' || str[pos+2] == 'N')) { n = 5; pos += 3; ch = str[pos]; } break; case 'M': case 'm': /* Mar */ if ((str[pos+1] == 'a' || str[pos+1] == 'A') && (str[pos+2] == 'r' || str[pos+2] == 'R')) { n = 2; pos += 3; ch = str[pos]; } /* May */ else if ((str[pos+1] == 'a' || str[pos+1] == 'A') && (str[pos+2] == 'y' || str[pos+2] == 'Y')) { n = 4; pos += 3; ch = str[pos]; } break; case 'N': case 'n': /* Nov */ if ((str[pos+1] == 'o' || str[pos+1] == 'O') && (str[pos+2] == 'v' || str[pos+2] == 'V')) { n = 10; pos += 3; ch = str[pos]; } break; case 'O': case 'o': /* Oct */ if ((str[pos+1] == 'c' || str[pos+1] == 'c') && (str[pos+2] == 't' || str[pos+2] == 'T')) { n = 9; pos += 3; ch = str[pos]; } break; case 'S': case 's': /* Sep */ if ((str[pos+1] == 'e' || str[pos+1] == 'E') && (str[pos+2] == 'p' || str[pos+2] == 'P')) { n = 8; pos += 3; ch = str[pos]; } break; } if (0 <= n && n <= 11) { month = n; } else { isValid = 0; } /* * Year -- two or four digits (four preferred) */ /* -- skip over non-digits */ while (ch && !('0' <= ch && ch <= '9')) { if (ch == '(') { pos += CommentLength(&str[pos]); } else { ++pos; } ch = str[pos]; } /* -- convert up to four digits */ n = -1; if ('0' <= ch && ch <= '9') { n = ch - '0'; ++pos; ch = str[pos]; } if ('0' <= ch && ch <= '9') { n *= 10; n += ch - '0'; ++pos; ch = str[pos]; } if ('0' <= ch && ch <= '9') { n *= 10; n += ch - '0'; ++pos; ch = str[pos]; } if ('0' <= ch && ch <= '9') { n *= 10; n += ch - '0'; ++pos; ch = str[pos]; } if (n != -1) { /* Fixed year 2000 problem (fix by tony@lasernet.globalnet.co.uk) */ if (n < 70) n += 2000; /* When less than 70 assume after year 2000 */ else if (n <= 99) n += 1900; /* When >69 and <100 assume 1970 to 1999 */ /* Additional check to limit valid range to 1970 to 2037 */ if ((n >= 1970) && (n < 2038)) year = n; else isValid = 0; } else { isValid = 0; } /* * Hour -- two digits */ /* -- skip over non-digits */ while (ch && !('0' <= ch && ch <= '9')) { if (ch == '(') { pos += CommentLength(&str[pos]); } else { ++pos; } ch = str[pos]; } /* -- convert next one or two digits */ n = -1; if ('0' <= ch && ch <= '9') { n = ch - '0'; ++pos; ch = str[pos]; } if ('0' <= ch && ch <= '9') { n *= 10; n += ch - '0'; ++pos; ch = str[pos]; } if (0 <= n && n <= 23) { hour = n; } else { isValid = 0; } /* * Minute -- two digits */ /* -- scan for ':' */ while (ch && ch != ':') { if (ch == '(') { pos += CommentLength(&str[pos]); } else { ++pos; } ch = str[pos]; } /* -- skip over non-digits */ while (ch && !('0' <= ch && ch <= '9')) { if (ch == '(') { pos += CommentLength(&str[pos]); } else { ++pos; } ch = str[pos]; } /* -- convert next one or two digits */ n = -1; if ('0' <= ch && ch <= '9') { n = ch - '0'; ++pos; ch = str[pos]; } if ('0' <= ch && ch <= '9') { n *= 10; n += ch - '0'; ++pos; ch = str[pos]; } if (0 <= n && n <= 59) { minute = n; } else { isValid = 0; } /* * Second (optional) -- two digits */ /* -- scan for ':' or start of time zone */ while (ch && !(ch == ':' || ch == '+' || ch == '-' || isalpha(ch))) { if (ch == '(') { pos += CommentLength(&str[pos]); } else { ++pos; } ch = str[pos]; } /* -- get the seconds, if it's there */ if (ch == ':') { ++pos; /* -- skip non-digits */ ch = str[pos]; while (ch && !('0' <= ch && ch <= '9')) { if (ch == '(') { pos += CommentLength(&str[pos]); } else { ++pos; } ch = str[pos]; } /* -- convert next one or two digits */ n = -1; if ('0' <= ch && ch <= '9') { n = ch - '0'; ++pos; ch = str[pos]; } if ('0' <= ch && ch <= '9') { n *= 10; n += ch - '0'; ++pos; ch = str[pos]; } if (0 <= n && n <= 59) { second = n; } else { isValid = 0; } /* -- scan for start of time zone */ while (ch && !(ch == '+' || ch == '-' || isalpha(ch))) { if (ch == '(') { pos += CommentLength(&str[pos]); } else { ++pos; } ch = str[pos]; } } else /* if (ch != ':') */ { second = 0; } /* * Time zone * * Note: According to RFC-1123, the military time zones are specified * incorrectly in RFC-822. RFC-1123 then states that "military time * zones in RFC-822 headers carry no information." * Here, we follow the specification in RFC-822. What else could we * do? Military time zones should *never* be used! */ sgn = 1; numZoneDigits = 0; switch (ch) { case '-': sgn = -1; /* fall through */ case '+': ++pos; /* -- skip non-digits */ ch = str[pos]; while (ch && !('0' <= ch && ch <= '9')) { ++pos; ch = str[pos]; } while( str[pos + numZoneDigits] && isdigit(str[pos + numZoneDigits] ) ) ++numZoneDigits; /* -- convert next four digits */ n = 0; while ( numZoneDigits ) { switch(numZoneDigits) { case 4: if ('0' <= ch && ch <= '9') { n = (ch - '0')*600; ++pos; ch = str[pos]; } break; case 3: if ('0' <= ch && ch <= '9') { n += (ch - '0')*60; ++pos; ch = str[pos]; } break; case 2: if ('0' <= ch && ch <= '9') { n += (ch - '0')*10; ++pos; ch = str[pos]; } break; case 1: if ('0' <= ch && ch <= '9') { n += ch - '0'; } break; default: break; } --numZoneDigits; } zone = sgn*n; break; case 'U': case 'u': if (str[pos+1] == 'T' || str[pos+1] == 't') { zone = 0; } break; case 'G': case 'g': if ((str[pos+1] == 'M' || str[pos+1] == 'm') && (str[pos+2] == 'T' || str[pos+2] == 't')) { zone = 0; } break; case 'E': case 'e': if ((str[pos+1] == 'S' || str[pos+1] == 's') && (str[pos+2] == 'T' || str[pos+2] == 't')) { zone = -300; } else if ((str[pos+1] == 'D' || str[pos+1] == 'd') && (str[pos+2] == 'T' || str[pos+2] == 't')) { zone = -240; } break; case 'C': case 'c': if ((str[pos+1] == 'S' || str[pos+1] == 's') && (str[pos+2] == 'T' || str[pos+2] == 't')) { zone = -360; } else if ((str[pos+1] == 'D' || str[pos+1] == 'd') && (str[pos+2] == 'T' || str[pos+2] == 't')) { zone = -300; } else if ((str[pos+1] == 'E' || str[pos+1] == 'e') // allow non-RFC822 "CET" && (str[pos+2] == 'T' || str[pos+2] == 't')) { zone = 60; } else if ((str[pos+1] == 'E' || str[pos+1] == 'e') // allow non-RFC822 "CEST" && (str[pos+2] == 'S' || str[pos+2] == 's') && (str[pos+3] == 'T' || str[pos+3] == 't')) { zone = 120; } break; case 'M': case 'm': if ((str[pos+1] == 'S' || str[pos+1] == 's') && (str[pos+2] == 'T' || str[pos+2] == 't')) { zone = -420; } else if ((str[pos+1] == 'D' || str[pos+1] == 'd') && (str[pos+2] == 'T' || str[pos+2] == 't')) { zone = -360; } break; case 'P': case 'p': if ((str[pos+1] == 'S' || str[pos+1] == 's') && (str[pos+2] == 'T' || str[pos+2] == 't')) { zone = -480; } else if ((str[pos+1] == 'D' || str[pos+1] == 'd') && (str[pos+2] == 'T' || str[pos+2] == 't')) { zone = -420; } break; case 'Z': /* Military time zone */ zone = 0; break; default: /* Military time zone */ if ('A' <= ch && ch <= 'I') { zone = 'A' - 1 - ch; } else if ('K' <= ch && ch <= 'M') { zone = 'A' - ch; } else if ('N' <= ch && ch <= 'Y') { zone = ch - 'N' + 1; } /* Some software doesn't set the timezone, so we default to +/-0 so KMail isn't too strict. --dnaber@mini.gt.owl.de, 2000-06-11 else { isValid = 0; } */ break; } if (isValid) { if (tms) { tms->tm_year = year - 1900; tms->tm_mon = month; tms->tm_mday = day; tms->tm_hour = hour; tms->tm_min = minute; tms->tm_sec = second; } if (z) { *z = zone; } } else { if (tms) { tms->tm_year = 70; tms->tm_mon = 0; tms->tm_mday = 1; tms->tm_hour = 0; tms->tm_min = 0; tms->tm_sec = 0; } if (z) { *z = 0; } } return isValid ? 0 : -1; } const char* wdays[] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" }; const char* months[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; #ifdef DW_TESTING_DATEPARSER #include #include #include const char* testStr[] = { "" }; int main() { struct tm *ptms, tms1, tms2; time_t tt; int i, zone1, zone2; char buf[100], sgn; /* try a bunch of random dates */ srand(100); for (i=0; i < 1000; ++i) { tt = rand()*((double)0x7fffffff/RAND_MAX); zone1 = (rand()%49 - 24)*30; gmtime(&tt, &ptms); tms1 = *ptms; sgn = (zone1 >= 0) ? '+' : '-'; snprintf(buf, sizeof(buf), "%s, %2d %s %d %d%d:%d%d:%d%d %c%d%d%d%d", wdays[tms1.tm_wday], tms1.tm_mday, months[tms1.tm_mon], tms1.tm_year+1900, tms1.tm_hour/10, tms1.tm_hour%10, tms1.tm_min/10, tms1.tm_min%10, tms1.tm_sec/10, tms1.tm_sec%10, sgn, abs(zone1)/60/10, abs(zone1)/60%10, abs(zone1)%60/10, abs(zone1)%60%10); ParseRfc822Date(buf, &tms2, &zone2); if (tms1.tm_year != tms2.tm_year) { fprintf(stderr, "Bad year\n"); } if (tms1.tm_mon != tms2.tm_mon) { fprintf(stderr, "Bad month\n"); } if (tms1.tm_mday != tms2.tm_mday) { fprintf(stderr, "Bad day\n"); } if (tms1.tm_hour != tms2.tm_hour) { fprintf(stderr, "Bad hour\n"); } if (tms1.tm_min != tms2.tm_min) { fprintf(stderr, "Bad minute\n"); } if (tms1.tm_sec != tms2.tm_sec) { fprintf(stderr, "Bad second\n"); } if (zone1 != zone2) { fprintf(stderr, "Bad zone\n"); } } return 0; } #endif // try to parse a date/time string given in a format not // correctly specified in RFC822 format // Here we detect the following format: // "WWW MMM dd HH:MM:SS [Z] YYYY" zone is optional // e.g.: Fri Oct 14 09:21:49 CEST 2005 // or: Tue Mar 23 18:00:02 2004 #include #include #ifdef __cplusplus extern "C" #endif int ParseDate(const char *str, struct tm *tms, int *z) { if ( !str ) return -1; size_t len = strlen(str); if ( len < 24 ) // at least "WWW MMM dd HH:MM:SS YYYY" return -1; int day=1, month=0, year=1970, hour=0, minute=0, second=0, zone=0; int i; for (i = 0; i < 7; i++) if ( strncmp(str, wdays[i], 3) == 0 ) break; if ( i == 7 ) return -1; for (i = 0; i < 12; i++) if ( strncmp(str+4, months[i], 3) == 0 ) break; if ( i == 12 ) return -1; month = i; if ( sscanf(str+8, "%d %d:%d:%d", &day, &hour, &minute, &second) != 4 ) return -1; if ( isdigit(str[20]) ) { // year without zone info, as in ctime() if ( sscanf(str+20, "%d", &year) != 1 ) return -1; } else { if ( sscanf(str+20, "%*s %d", &year) != 1 ) return -1; if ( strncmp(str+20, "EST" , 3) == 0 ) zone = -5 * 60; else if ( strncmp(str+20, "EDT" , 3) == 0 ) zone = -4 * 60; else if ( strncmp(str+20, "CST" , 3) == 0 ) zone = -6 * 60; else if ( strncmp(str+20, "CDT" , 3) == 0 ) zone = -5 * 60; else if ( strncmp(str+20, "MST" , 3) == 0 ) zone = -7 * 60; else if ( strncmp(str+20, "MDT" , 3) == 0 ) zone = -6 * 60; else if ( strncmp(str+20, "PST" , 3) == 0 ) zone = -8 * 60; else if ( strncmp(str+20, "PDT" , 3) == 0 ) zone = -7 * 60; else if ( strncmp(str+20, "CET" , 3) == 0 ) zone = 60; else if ( strncmp(str+20, "CEST", 4) == 0 ) zone = 120; } if ( (day < 1) || (day > 31) || (hour < 0) || (hour > 23) || (minute < 0) || (minute > 59) || (second < 0) || (second > 59) || (year < 1900) ) return -1; if ( tms ) { tms->tm_year = year - 1900; tms->tm_mon = month; tms->tm_mday = day; tms->tm_hour = hour; tms->tm_min = minute; tms->tm_sec = second; } if ( z ) *z = zone; return 0; } mimelib1-1.1.4/mimelib/mboxlist.cpp0000644000175000017500000002171511175345261016612 0ustar resivoresivo//============================================================================= // File: mboxlist.cpp // Contents: Definitions for DwMailboxList // Maintainer: Doug Sauder // WWW: http://www.fwb.gulf.net/~dwsauder/mimepp.html // // Copyright (c) 1996, 1997 Douglas W. Sauder // All rights reserved. // // IN NO EVENT SHALL DOUGLAS W. SAUDER BE LIABLE TO ANY PARTY FOR DIRECT, // INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF // THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF DOUGLAS W. SAUDER // HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // DOUGLAS W. SAUDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT // NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A // PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" // BASIS, AND DOUGLAS W. SAUDER HAS NO OBLIGATION TO PROVIDE MAINTENANCE, // SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. // //============================================================================= #define DW_IMPLEMENTATION #include #include #include #include #include #include #include #include #include #include const char* const DwMailboxList::sClassName = "DwMailboxList"; DwMailboxList* (*DwMailboxList::sNewMailboxList)(const DwString&, DwMessageComponent*) = 0; DwMailboxList* DwMailboxList::NewMailboxList(const DwString& aStr, DwMessageComponent* aParent) { if (sNewMailboxList) { return sNewMailboxList(aStr, aParent); } else { return new DwMailboxList(aStr, aParent); } } DwMailboxList::DwMailboxList() { mFirstMailbox = 0; mClassId = kCidMailboxList; mClassName = sClassName; } DwMailboxList::DwMailboxList(const DwMailboxList& aList) : DwFieldBody(aList) { mFirstMailbox = 0; const DwMailbox* firstMailbox = aList.mFirstMailbox; if (firstMailbox) { CopyList(firstMailbox); } mClassId = kCidMailboxList; mClassName = sClassName; } DwMailboxList::DwMailboxList(const DwString& aStr, DwMessageComponent* aParent) : DwFieldBody(aStr, aParent) { mFirstMailbox = 0; mClassId = kCidMailboxList; mClassName = sClassName; } DwMailboxList::~DwMailboxList() { if (mFirstMailbox) { _DeleteAll(); } } const DwMailboxList& DwMailboxList::operator = (const DwMailboxList& aList) { if (this == &aList) return *this; DwFieldBody::operator = (aList); if (mFirstMailbox) { _DeleteAll(); } const DwMailbox* firstMailbox = aList.mFirstMailbox; if (firstMailbox) { CopyList(firstMailbox); } if (mParent && mIsModified) { mParent->SetModified(); } return *this; } DwMailbox* DwMailboxList::FirstMailbox() const { return mFirstMailbox; } void DwMailboxList::Add(DwMailbox* aMailbox) { assert(aMailbox != 0); if (aMailbox == 0) return; _AddMailbox(aMailbox); SetModified(); } void DwMailboxList::_AddMailbox(DwMailbox* aMailbox) { assert(aMailbox != 0); if (aMailbox == 0) return; if (!mFirstMailbox) { mFirstMailbox = aMailbox; } else { DwMailbox* mb = mFirstMailbox; while (mb->Next()) { mb = (DwMailbox*) mb->Next(); } mb->SetNext(aMailbox); } aMailbox->SetParent(this); } void DwMailboxList::Remove(DwMailbox* mailbox) { DwMailbox* mb = mFirstMailbox; if (mb == mailbox) { mFirstMailbox = (DwMailbox*) mb->Next(); return; } while (mb) { if (mb->Next() == mailbox) { mb->SetNext(mailbox->Next()); break; } } SetModified(); } void DwMailboxList::DeleteAll() { _DeleteAll(); SetModified(); } void DwMailboxList::_DeleteAll() { DwMailbox* mb = mFirstMailbox; while (mb) { DwMailbox* toDel = mb; mb = (DwMailbox*) mb->Next(); delete toDel; } mFirstMailbox = 0; } void DwMailboxList::Parse() { mIsModified = 0; // Mailboxes are separated by commas. Commas may also occur in a route. // (See RFC822 p. 27) if (mFirstMailbox) _DeleteAll(); DwMailboxListParser parser(mString); DwMailbox* mailbox; while (1) { switch (parser.MbType()) { case DwMailboxListParser::eMbError: case DwMailboxListParser::eMbEnd: goto LOOP_EXIT; case DwMailboxListParser::eMbMailbox: mailbox = DwMailbox::NewMailbox(parser.MbString(), this); mailbox->Parse(); if (mailbox->IsValid()) { _AddMailbox(mailbox); } else { delete mailbox; } break; case DwMailboxListParser::eMbNull: break; } ++parser; } LOOP_EXIT: return; } void DwMailboxList::Assemble() { if (!mIsModified) return; mString = ""; int count = 0; DwMailbox* mb = mFirstMailbox; while (mb) { mb->Assemble(); if (mb->IsValid()) { if (count > 0){ if (IsFolding()) { mString += "," DW_EOL " "; } else { mString += ", "; } } mString += mb->AsString(); ++count; } mb = (DwMailbox*) mb->Next(); } mIsModified = 0; } DwMessageComponent* DwMailboxList::Clone() const { return new DwMailboxList(*this); } void DwMailboxList::CopyList(const DwMailbox* aFirst) { const DwMailbox* mailbox = aFirst; while (mailbox) { DwMailbox* newMailbox = (DwMailbox*) mailbox->Clone(); Add(newMailbox); mailbox = (DwMailbox*) mailbox->Next(); } } #if defined (DW_DEBUG_VERSION) void DwMailboxList::PrintDebugInfo(std::ostream& aStrm, int aDepth) const { aStrm << "-------------- Debug info for DwMailboxList class --------------\n"; _PrintDebugInfo(aStrm); int depth = aDepth - 1; depth = (depth >= 0) ? depth : 0; if (aDepth == 0 || depth > 0) { DwMailbox* mbox = mFirstMailbox; while (mbox) { mbox->PrintDebugInfo(aStrm, depth); mbox = (DwMailbox*) mbox->Next(); } } } #else void DwMailboxList::PrintDebugInfo(std::ostream& , int ) const {} #endif // defined (DW_DEBUG_VERSION) #if defined (DW_DEBUG_VERSION) void DwMailboxList::_PrintDebugInfo(std::ostream& aStrm) const { DwFieldBody::_PrintDebugInfo(aStrm); aStrm << "Mailbox objects: "; DwMailbox* mbox = mFirstMailbox; if (mbox) { int count = 0; while (mbox) { if (count) aStrm << ' '; aStrm << mbox->ObjectId(); mbox = (DwMailbox*) mbox->Next(); ++count; } aStrm << '\n'; } else { aStrm << "(none)\n"; } } #else void DwMailboxList::_PrintDebugInfo(std::ostream& ) const {} #endif // defined (DW_DEBUG_VERSION) void DwMailboxList::CheckInvariants() const { #if defined (DW_DEBUG_VERSION) DwMailbox* mbox = mFirstMailbox; while (mbox) { mbox->CheckInvariants(); assert((DwMessageComponent*) this == mbox->Parent()); mbox = (DwMailbox*) mbox->Next(); } #endif // defined (DW_DEBUG_VERSION) } //------------------------------------------------------------------------- DwMailboxListParser::DwMailboxListParser(const DwString& aStr) : mTokenizer(aStr), mMbString(aStr) { mMbType = eMbError; ParseNextMailbox(); } DwMailboxListParser::~DwMailboxListParser() { } int DwMailboxListParser::Restart() { mTokenizer.Restart(); ParseNextMailbox(); return mMbType; } int DwMailboxListParser::operator ++ () { ParseNextMailbox(); return mMbType; } void DwMailboxListParser::ParseNextMailbox() { mMbString.SetFirst(mTokenizer); mMbType = eMbEnd; int type = mTokenizer.Type(); if (type == eTkNull) { return; } enum { eTopLevel, eInRouteAddr } state; state = eTopLevel; mMbType = eMbMailbox; int done = 0; while (!done) { if (type == eTkNull) { mMbString.ExtendTo(mTokenizer); break; } if (type == eTkSpecial) { int ch = mTokenizer.Token()[0]; switch (state) { case eTopLevel: switch (ch) { case ',': mMbString.ExtendTo(mTokenizer); done = 1; break; case '<': state = eInRouteAddr; break; } break; case eInRouteAddr: switch (ch) { case '>': state = eTopLevel; break; } break; } } ++mTokenizer; type = mTokenizer.Type(); } if (mMbString.Tokens().length() == 0) { mMbType = eMbNull; } } mimelib1-1.1.4/mimelib/dw_cte.cpp0000644000175000017500000006522711175345261016224 0ustar resivoresivo//============================================================================= // File: dw_cte.cpp // Contents: Function definitions for content transfer encodings // Maintainer: Doug Sauder // WWW: http://www.fwb.gulf.net/~dwsauder/mimepp.html // // Copyright (c) 1996, 1997 Douglas W. Sauder // All rights reserved. // // IN NO EVENT SHALL DOUGLAS W. SAUDER BE LIABLE TO ANY PARTY FOR DIRECT, // INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF // THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF DOUGLAS W. SAUDER // HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // DOUGLAS W. SAUDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT // NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A // PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" // BASIS, AND DOUGLAS W. SAUDER HAS NO OBLIGATION TO PROVIDE MAINTENANCE, // SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. // //============================================================================= #define DW_IMPLEMENTATION #include #include #include #include #include #define MAXLINE 76 static size_t calc_crlf_buff_size(const char* srcBuf, size_t srcLen); static int to_crlf(const char* srcBuf, size_t srcLen, char* destBuf, size_t destSize, size_t* destLen); static int to_lf(const char* srcBuf, size_t srcLen, char* destBuf, size_t destSize, size_t* destLen); static int to_cr(const char* srcBuf, size_t srcLen, char* destBuf, size_t destSize, size_t* destLen); static int encode_base64(const char* aIn, size_t aInLen, char* aOut, size_t aOutSize, size_t* aOutLen); static int decode_base64(const char* aIn, size_t aInLen, char* aOut, size_t aOutSize, size_t* aOutLen); static int encode_qp(const char* aIn, size_t aInLen, char* aOut, size_t aOutSize, size_t* aOutLen); static int decode_qp(const char* aIn, size_t aInLen, char* aOut, size_t aOutSize, size_t* aOutLen); static size_t calc_qp_buff_size(const char* aIn, size_t aInLen); int DwToCrLfEol(const DwString& aSrcStr, DwString& aDestStr) { // Estimate required destination buffer size size_t srcLen = aSrcStr.length(); const char* srcBuf = aSrcStr.data(); size_t destSize = calc_crlf_buff_size(srcBuf, srcLen); // Allocate destination buffer DwString destStr(destSize, (char)0); char* destBuf = (char*) destStr.data(); // Encode source to destination size_t destLen = 0; to_crlf(srcBuf, srcLen, destBuf, destSize, &destLen); aDestStr.assign(destStr, 0, destLen); return 0; } int DwToLfEol(const DwString& aSrcStr, DwString& aDestStr) { size_t srcLen = aSrcStr.length(); const char* srcBuf = aSrcStr.data(); size_t destSize = srcLen; // Allocate destination buffer DwString destStr(destSize, (char)0); char* destBuf = (char*) destStr.data(); // Encode source to destination size_t destLen = 0; to_lf(srcBuf, srcLen, destBuf, destSize, &destLen); aDestStr.assign(destStr, 0, destLen); return 0; } int DwToCrEol(const DwString& aSrcStr, DwString& aDestStr) { size_t srcLen = aSrcStr.length(); const char* srcBuf = aSrcStr.data(); size_t destSize = srcLen; // Allocate destination buffer DwString destStr(destSize, (char)0); char* destBuf = (char*) destStr.data(); // Encode source to destination size_t destLen = 0; to_cr(srcBuf, srcLen, destBuf, destSize, &destLen); aDestStr.assign(destStr, 0, destLen); return 0; } int DwToLocalEol(const DwString& aSrcStr, DwString& aDestStr) { #if defined(DW_EOL_CRLF) return DwToCrLfEol(aSrcStr, aDestStr); #elif defined(DW_EOL_LF) return DwToLfEol(aSrcStr, aDestStr); #else # error "Must define DW_EOL_CRLF, DW_EOL_LF" #endif } int DwEncodeBase64(const DwString& aSrcStr, DwString& aDestStr) { // Estimate required destination buffer size size_t srcLen = aSrcStr.length(); const char* srcBuf = aSrcStr.data(); size_t destSize = (srcLen+2)/3*4; destSize += strlen(DW_EOL)*destSize/72 + 2; destSize += 64; // a little extra room // Allocate destination buffer DwString destStr(destSize, (char)0); char* destBuf = (char*) destStr.data(); // Encode source to destination size_t destLen = 0; int result = encode_base64(srcBuf, srcLen, destBuf, destSize, &destLen); aDestStr.assign(destStr, 0, destLen); return result; } int DwDecodeBase64(const DwString& aSrcStr, DwString& aDestStr) { // Set destination buffer size same as source buffer size size_t srcLen = aSrcStr.length(); const char* srcBuf = aSrcStr.data(); size_t destSize = srcLen; // Allocate destination buffer DwString destStr(destSize, (char)0); char* destBuf = (char*) destStr.data(); // Encode source to destination size_t destLen = 0; int result = decode_base64(srcBuf, srcLen, destBuf, destSize, &destLen); aDestStr.assign(destStr, 0, destLen); return result; } int DwEncodeQuotedPrintable(const DwString& aSrcStr, DwString& aDestStr) { // Estimate required destination buffer size size_t srcLen = aSrcStr.length(); const char* srcBuf = aSrcStr.data(); size_t destSize = calc_qp_buff_size(srcBuf, srcLen); destSize += 64; // a little extra room // Allocate destination buffer DwString destStr(destSize, (char)0); char* destBuf = (char*) destStr.data(); // Encode source to destination size_t destLen = 0; int result = encode_qp(srcBuf, srcLen, destBuf, destSize, &destLen); aDestStr.assign(destStr, 0, destLen); return result; } int DwDecodeQuotedPrintable(const DwString& aSrcStr, DwString& aDestStr) { // Set destination buffer size same as source buffer size size_t srcLen = aSrcStr.length(); const char* srcBuf = aSrcStr.data(); size_t destSize = srcLen; // Allocate destination buffer DwString destStr(destSize, (char)0); char* destBuf = (char*) destStr.data(); // Encode source to destination size_t destLen = 0; int result = decode_qp(srcBuf, srcLen, destBuf, destSize, &destLen); aDestStr.assign(destStr, 0, destLen); return result; } //============================================================================ // Everything below this line is private to this file (static) //============================================================================ static size_t calc_crlf_buff_size(const char* srcBuf, size_t srcLen) { size_t i, extra; if (!srcBuf) return 0; extra = 0; for (i=0; i < srcLen; ) { switch (srcBuf[i]) { /* Bare LF (UNIX or C text) */ case '\n': ++extra; ++i; break; case '\r': /* CR LF (DOS, Windows, or MIME text) */ if (i+1 < srcLen && srcBuf[i+1] == '\n') { i += 2; } /* Bare CR (Macintosh text) */ else { ++extra; ++i; } break; default: ++i; } } return srcLen + extra; } static int to_crlf(const char* srcBuf, size_t srcLen, char* destBuf, size_t destSize, size_t* destLen) { size_t iSrc, iDest; if (!srcBuf || !destBuf || !destLen) return -1; iSrc = iDest = 0; while (iSrc < srcLen && iDest < destSize) { switch (srcBuf[iSrc]) { /* Bare LF (UNIX or C text) */ case '\n': destBuf[iDest++] = '\r'; if (iDest < destSize) { destBuf[iDest++] = srcBuf[iSrc++]; } break; case '\r': /* CR LF (DOS, Windows, or MIME text) */ if (iSrc+1 < srcLen && srcBuf[iSrc+1] == '\n') { destBuf[iDest++] = srcBuf[iSrc++]; if (iDest < destSize) { destBuf[iDest++] = srcBuf[iSrc++]; } } /* Bare CR (Macintosh text) */ else { destBuf[iDest++] = srcBuf[iSrc++]; if (iDest < destSize) { destBuf[iDest++] = '\n'; } } break; default: destBuf[iDest++] = srcBuf[iSrc++]; } } *destLen = iDest; if (iDest < destSize) { destBuf[iDest] = 0; } return 0; } static int to_lf(const char* srcBuf, size_t srcLen, char* destBuf, size_t destSize, size_t* destLen) { size_t iSrc, iDest; if (!srcBuf || !destBuf || !destLen) return -1; iSrc = iDest = 0; while (iSrc < srcLen && iDest < destSize) { switch (srcBuf[iSrc]) { /* Bare LF (UNIX or C text) */ case '\n': destBuf[iDest++] = srcBuf[iSrc++]; break; case '\r': /* CR LF (DOS, Windows, or MIME text) */ if (iSrc+1 < srcLen && srcBuf[iSrc+1] == '\n') { ++iSrc; destBuf[iDest++] = srcBuf[iSrc++]; } /* Bare CR (Macintosh text) */ else { destBuf[iDest++] = '\n'; ++iSrc; } break; default: destBuf[iDest++] = srcBuf[iSrc++]; } } *destLen = iDest; if (iDest < destSize) { destBuf[iDest] = 0; } return 0; } static int to_cr(const char* srcBuf, size_t srcLen, char* destBuf, size_t destSize, size_t* destLen) { size_t iSrc, iDest; if (!srcBuf || !destBuf || !destLen) return -1; iSrc = iDest = 0; while (iSrc < srcLen && iDest < destSize) { switch (srcBuf[iSrc]) { /* Bare LF (UNIX or C text) */ case '\n': destBuf[iDest++] = '\r'; ++iSrc; break; case '\r': /* CR LF (DOS, Windows, or MIME text) */ if (iSrc+1 < srcLen && srcBuf[iSrc+1] == '\n') { destBuf[iDest++] = srcBuf[iSrc++]; ++iSrc; } /* Bare CR (Macintosh text) */ else { destBuf[iDest++] = srcBuf[iSrc++]; } break; default: destBuf[iDest++] = srcBuf[iSrc++]; } } *destLen = iDest; if (iDest < destSize) { destBuf[iDest] = 0; } return 0; } static char base64tab[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "abcdefghijklmnopqrstuvwxyz0123456789+/"; static char base64idx[128] = { '\377','\377','\377','\377','\377','\377','\377','\377', '\377','\377','\377','\377','\377','\377','\377','\377', '\377','\377','\377','\377','\377','\377','\377','\377', '\377','\377','\377','\377','\377','\377','\377','\377', '\377','\377','\377','\377','\377','\377','\377','\377', '\377','\377','\377', 62,'\377','\377','\377', 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61,'\377','\377','\377','\377','\377','\377', '\377', 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,'\377','\377','\377','\377','\377', '\377', 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,'\377','\377','\377','\377','\377' }; static char hextab[] = "0123456789ABCDEF"; #ifdef __cplusplus inline int isbase64(int a) { return ('A' <= a && a <= 'Z') || ('a' <= a && a <= 'z') || ('0' <= a && a <= '9') || a == '+' || a == '/'; } #else #define isbase64(a) ( ('A' <= (a) && (a) <= 'Z') \ || ('a' <= (a) && (a) <= 'z') \ || ('0' <= (a) && (a) <= '9') \ || (a) == '+' || (a) == '/' ) #endif static int encode_base64(const char* aIn, size_t aInLen, char* aOut, size_t aOutSize, size_t* aOutLen) { if (!aIn || !aOut || !aOutLen) return -1; size_t inLen = aInLen; char* out = aOut; size_t outSize = (inLen+2)/3*4; /* 3:4 conversion ratio */ outSize += strlen(DW_EOL)*outSize/MAXLINE + 2; /* Space for newlines and NUL */ if (aOutSize < outSize) return -1; size_t inPos = 0; size_t outPos = 0; int c1, c2, c3; int lineLen = 0; /* Get three characters at a time and encode them. */ for (size_t i=0; i < inLen/3; ++i) { c1 = aIn[inPos++] & 0xFF; c2 = aIn[inPos++] & 0xFF; c3 = aIn[inPos++] & 0xFF; out[outPos++] = base64tab[(c1 & 0xFC) >> 2]; out[outPos++] = base64tab[((c1 & 0x03) << 4) | ((c2 & 0xF0) >> 4)]; out[outPos++] = base64tab[((c2 & 0x0F) << 2) | ((c3 & 0xC0) >> 6)]; out[outPos++] = base64tab[c3 & 0x3F]; lineLen += 4; if (lineLen >= MAXLINE-3) { const char* cp = DW_EOL; out[outPos++] = *cp++; if (*cp) { out[outPos++] = *cp; } lineLen = 0; } } /* Encode the remaining one or two characters. */ const char* cp; switch (inLen % 3) { case 0: cp = DW_EOL; out[outPos++] = *cp++; if (*cp) { out[outPos++] = *cp; } break; case 1: c1 = aIn[inPos] & 0xFF; out[outPos++] = base64tab[(c1 & 0xFC) >> 2]; out[outPos++] = base64tab[((c1 & 0x03) << 4)]; out[outPos++] = '='; out[outPos++] = '='; cp = DW_EOL; out[outPos++] = *cp++; if (*cp) { out[outPos++] = *cp; } break; case 2: c1 = aIn[inPos++] & 0xFF; c2 = aIn[inPos] & 0xFF; out[outPos++] = base64tab[(c1 & 0xFC) >> 2]; out[outPos++] = base64tab[((c1 & 0x03) << 4) | ((c2 & 0xF0) >> 4)]; out[outPos++] = base64tab[((c2 & 0x0F) << 2)]; out[outPos++] = '='; cp = DW_EOL; out[outPos++] = *cp++; if (*cp) { out[outPos++] = *cp; } break; } out[outPos] = 0; *aOutLen = outPos; return 0; } static int decode_base64(const char* aIn, size_t aInLen, char* aOut, size_t aOutSize, size_t* aOutLen) { if (!aIn || !aOut || !aOutLen) return -1; size_t inLen = aInLen; char* out = aOut; size_t outSize = ( ( inLen + 3 ) / 4 ) * 3; if (aOutSize < outSize) return -1; /* Get four input chars at a time and decode them. Ignore white space * chars (CR, LF, SP, HT). If '=' is encountered, terminate input. If * a char other than white space, base64 char, or '=' is encountered, * flag an input error, but otherwise ignore the char. */ int isErr = 0; int isEndSeen = 0; int b1, b2, b3; int a1, a2, a3, a4; size_t inPos = 0; size_t outPos = 0; while (inPos < inLen) { a1 = a2 = a3 = a4 = 0; while (inPos < inLen) { a1 = aIn[inPos++] & 0xFF; if (isbase64(a1)) { break; } else if (a1 == '=') { isEndSeen = 1; break; } else if (a1 != '\r' && a1 != '\n' && a1 != ' ' && a1 != '\t') { isErr = 1; } } while (inPos < inLen) { a2 = aIn[inPos++] & 0xFF; if (isbase64(a2)) { break; } else if (a2 == '=') { isEndSeen = 1; break; } else if (a2 != '\r' && a2 != '\n' && a2 != ' ' && a2 != '\t') { isErr = 1; } } while (inPos < inLen) { a3 = aIn[inPos++] & 0xFF; if (isbase64(a3)) { break; } else if (a3 == '=') { isEndSeen = 1; break; } else if (a3 != '\r' && a3 != '\n' && a3 != ' ' && a3 != '\t') { isErr = 1; } } while (inPos < inLen) { a4 = aIn[inPos++] & 0xFF; if (isbase64(a4)) { break; } else if (a4 == '=') { isEndSeen = 1; break; } else if (a4 != '\r' && a4 != '\n' && a4 != ' ' && a4 != '\t') { isErr = 1; } } if (isbase64(a1) && isbase64(a2) && isbase64(a3) && isbase64(a4)) { a1 = base64idx[a1] & 0xFF; a2 = base64idx[a2] & 0xFF; a3 = base64idx[a3] & 0xFF; a4 = base64idx[a4] & 0xFF; b1 = ((a1 << 2) & 0xFC) | ((a2 >> 4) & 0x03); b2 = ((a2 << 4) & 0xF0) | ((a3 >> 2) & 0x0F); b3 = ((a3 << 6) & 0xC0) | ( a4 & 0x3F); out[outPos++] = char(b1); out[outPos++] = char(b2); out[outPos++] = char(b3); } else if (isbase64(a1) && isbase64(a2) && isbase64(a3) && a4 == '=') { a1 = base64idx[a1] & 0xFF; a2 = base64idx[a2] & 0xFF; a3 = base64idx[a3] & 0xFF; b1 = ((a1 << 2) & 0xFC) | ((a2 >> 4) & 0x03); b2 = ((a2 << 4) & 0xF0) | ((a3 >> 2) & 0x0F); out[outPos++] = char(b1); out[outPos++] = char(b2); break; } else if (isbase64(a1) && isbase64(a2) && a3 == '=' && a4 == '=') { a1 = base64idx[a1] & 0xFF; a2 = base64idx[a2] & 0xFF; b1 = ((a1 << 2) & 0xFC) | ((a2 >> 4) & 0x03); out[outPos++] = char(b1); break; } else { break; } if (isEndSeen) { break; } } /* end while loop */ *aOutLen = outPos; return (isErr) ? -1 : 0; } /***** Warning: calc_qp_buff_size must stay in sync with encode_qp ******/ static int encode_qp(const char* aIn, size_t aInLen, char* aOut, size_t /*aOutSize */, size_t* aOutLen) { size_t inPos, outPos, lineLen; int ch; if (!aIn || !aOut || !aOutLen) { return -1; } inPos = 0; outPos = 0; lineLen = 0; while (inPos < aInLen) { ch = aIn[inPos++] & 0xFF; /* '.' at beginning of line (confuses some SMTPs) */ if (lineLen == 0 && ch == '.') { aOut[outPos++] = '='; aOut[outPos++] = hextab[(ch >> 4) & 0x0F]; aOut[outPos++] = hextab[ch & 0x0F]; lineLen += 3; } /* "From " at beginning of line (gets mangled in mbox folders) */ else if (lineLen == 0 && inPos+3 < aInLen && ch == 'F' && aIn[inPos ] == 'r' && aIn[inPos+1] == 'o' && aIn[inPos+2] == 'm' && aIn[inPos+3] == ' ') { aOut[outPos++] = '='; aOut[outPos++] = hextab[(ch >> 4) & 0x0F]; aOut[outPos++] = hextab[ch & 0x0F]; lineLen += 3; } /* Normal printable char */ else if ((62 <= ch && ch <= 126) || (33 <= ch && ch <= 60)) { aOut[outPos++] = (char) ch; ++lineLen; } /* Space */ else if (ch == ' ') { /* Space at end of line or end of input must be encoded */ #if defined(DW_EOL_LF) if (inPos >= aInLen /* End of input? */ || aIn[inPos] == '\n') { /* End of line? */ aOut[outPos++] = '='; aOut[outPos++] = '2'; aOut[outPos++] = '0'; lineLen += 3; } #elif defined(DW_EOL_CRLF) if (inPos >= aInLen /* End of input? */ || (inPos < aInLen-1 /* End of line? */ && aIn[inPos ] == '\r' && aIn[inPos+1] == '\n') ) { aOut[outPos++] = '='; aOut[outPos++] = '2'; aOut[outPos++] = '0'; lineLen += 3; } #else # error Must define DW_EOL_LF or DW_EOL_CRLF #endif else { aOut[outPos++] = ' '; ++lineLen; } } /* Hard line break */ #if defined(DW_EOL_LF) else if (ch == '\n') { aOut[outPos++] = '\n'; lineLen = 0; } #elif defined(DW_EOL_CRLF) else if (inPos < aInLen && ch == '\r' && aIn[inPos] == '\n') { ++inPos; aOut[outPos++] = '\r'; aOut[outPos++] = '\n'; lineLen = 0; } #endif /* Non-printable char */ else if (ch & 0x80 /* 8-bit char */ || !(ch & 0xE0) /* control char */ || ch == 0x7F /* DEL */ || ch == '=') { /* special case */ aOut[outPos++] = '='; aOut[outPos++] = hextab[(ch >> 4) & 0x0F]; aOut[outPos++] = hextab[ch & 0x0F]; lineLen += 3; } /* Soft line break */ #if defined(DW_EOL_LF) if (lineLen >= MAXLINE-3 && inPos < aInLen && aIn[inPos] != '\n') { aOut[outPos++] = '='; aOut[outPos++] = '\n'; lineLen = 0; } #elif defined(DW_EOL_CRLF) if (lineLen >= MAXLINE-3 && !(inPos < aInLen-1 && aIn[inPos] == '\r' && aIn[inPos+1] == '\n')) { aOut[outPos++] = '='; aOut[outPos++] = '\r'; aOut[outPos++] = '\n'; lineLen = 0; } #endif } aOut[outPos] = 0; *aOutLen = outPos; return 0; } static int decode_qp(const char* aIn, size_t aInLen, char* aOut, size_t /* aOutSize */, size_t* aOutLen) { size_t i, inPos, outPos, lineLen, nextLineStart, numChars, charsEnd; int isEolFound, softLineBrk, isError; int ch, c1, c2; if (!aIn || !aOut || !aOutLen) return -1; isError = 0; inPos = 0; outPos = 0; for (i=0; i < aInLen; ++i) { if (aIn[i] == 0) { aInLen = i; break; } } if (aInLen == 0) { aOut[0] = 0; *aOutLen = 0; return 0; } while (inPos < aInLen) { /* Get line */ lineLen = 0; isEolFound = 0; while (!isEolFound && lineLen < aInLen - inPos) { ch = aIn[inPos+lineLen]; ++lineLen; if (ch == '\n') { isEolFound = 1; } } nextLineStart = inPos + lineLen; numChars = lineLen; /* Remove white space from end of line */ while (numChars > 0) { ch = aIn[inPos+numChars-1] & 0x7F; if (ch != '\n' && ch != '\r' && ch != ' ' && ch != '\t') { break; } --numChars; } charsEnd = inPos + numChars; /* Decode line */ softLineBrk = 0; while (inPos < charsEnd) { ch = aIn[inPos++] & 0x7F; if (ch != '=') { /* Normal printable char */ aOut[outPos++] = (char) ch; } else /* if (ch == '=') */ { /* Soft line break */ if (inPos >= charsEnd) { softLineBrk = 1; break; } /* Non-printable char */ else if (inPos < charsEnd-1) { c1 = aIn[inPos++] & 0x7F; if ('0' <= c1 && c1 <= '9') c1 -= '0'; else if ('A' <= c1 && c1 <= 'F') c1 = c1 - 'A' + 10; else if ('a' <= c1 && c1 <= 'f') c1 = c1 - 'a' + 10; else isError = 1; c2 = aIn[inPos++] & 0x7F; if ('0' <= c2 && c2 <= '9') c2 -= '0'; else if ('A' <= c2 && c2 <= 'F') c2 = c2 - 'A' + 10; else if ('a' <= c2 && c2 <= 'f') c2 = c2 - 'a' + 10; else isError = 1; aOut[outPos++] = (char) ((c1 << 4) + c2); } else /* if (inPos == charsEnd-1) */ { isError = 1; } } } if (isEolFound && !softLineBrk) { const char* cp = DW_EOL; aOut[outPos++] = *cp++; if (*cp) { aOut[outPos++] = *cp; } } inPos = nextLineStart; } aOut[outPos] = 0; *aOutLen = outPos; return (isError) ? -1 : 0; } /***** Warning: calc_qp_buff_size must stay in sync with encode_qp ******/ static size_t calc_qp_buff_size(const char* aIn, size_t aInLen) { size_t inPos, outLen, lineLen; int ch; if (!aIn || aInLen == 0) { return 0; } inPos = 0; outLen = 0; lineLen = 0; while (inPos < aInLen) { ch = aIn[inPos++] & 0xFF; /* '.' at beginning of line (confuses some SMTPs) */ if (lineLen == 0 && ch == '.') { outLen += 3; lineLen += 3; } /* "From " at beginning of line (gets mangled in mbox folders) */ else if (lineLen == 0 && inPos+3 < aInLen && ch == 'F' && aIn[inPos ] == 'r' && aIn[inPos+1] == 'o' && aIn[inPos+2] == 'm' && aIn[inPos+3] == ' ') { outLen += 3; lineLen += 3; } /* Normal printable char */ else if ((62 <= ch && ch <= 126) || (33 <= ch && ch <= 60)) { ++outLen; ++lineLen; } /* Space */ else if (ch == ' ') { /* Space at end of line or end of input must be encoded */ #if defined(DW_EOL_LF) if (inPos >= aInLen /* End of input? */ || aIn[inPos] == '\n') { /* End of line? */ outLen += 3; lineLen += 3; } #elif defined(DW_EOL_CRLF) if (inPos >= aInLen /* End of input? */ || (inPos < aInLen-1 /* End of line? */ && aIn[inPos ] == '\r' && aIn[inPos+1] == '\n') ) { outLen += 3; lineLen += 3; } #else # error Must define DW_EOL_LF or DW_EOL_CRLF #endif else { ++outLen; ++lineLen; } } /* Hard line break */ #if defined(DW_EOL_LF) else if (ch == '\n') { ++outLen; lineLen = 0; } #elif defined(DW_EOL_CRLF) else if (inPos < aInLen && ch == '\r' && aIn[inPos] == '\n') { ++inPos; outLen += 2; lineLen = 0; } #endif /* Non-printable char */ else if (ch & 0x80 /* 8-bit char */ || !(ch & 0xE0) /* control char */ || ch == 0x7F /* DEL */ || ch == '=') { /* special case */ outLen += 3; lineLen += 3; } /* Soft line break */ #if defined(DW_EOL_LF) if (lineLen >= MAXLINE-3 && inPos < aInLen && aIn[inPos] != '\n') { outLen += 2; lineLen = 0; } #elif defined(DW_EOL_CRLF) if (lineLen >= MAXLINE-3 && !(inPos < aInLen-1 && aIn[inPos] == '\r' && aIn[inPos+1] == '\n')) { outLen += 3; lineLen = 0; } #endif } return outLen; }