aboutsummaryrefslogtreecommitdiffstats
path: root/src/utility
diff options
context:
space:
mode:
Diffstat (limited to 'src/utility')
-rw-r--r--src/utility/file.hpp218
-rw-r--r--src/utility/md5.cpp331
-rw-r--r--src/utility/md5.hpp68
-rw-r--r--src/utility/path.cpp196
-rw-r--r--src/utility/path.hpp124
-rw-r--r--src/utility/random.cpp59
-rw-r--r--src/utility/random.hpp62
-rw-r--r--src/utility/singleton.cpp53
-rw-r--r--src/utility/singleton.hpp92
-rw-r--r--src/utility/smartPtr.hpp166
-rw-r--r--src/utility/stream.cpp257
-rw-r--r--src/utility/stream.hpp263
-rw-r--r--src/utility/stringProxy.cpp131
-rw-r--r--src/utility/stringProxy.hpp90
14 files changed, 2110 insertions, 0 deletions
diff --git a/src/utility/file.hpp b/src/utility/file.hpp
new file mode 100644
index 00000000..f4d63bc2
--- /dev/null
+++ b/src/utility/file.hpp
@@ -0,0 +1,218 @@
+//
+// VMime library (http://vmime.sourceforge.net)
+// Copyright (C) 2002-2004 Vincent Richard <[email protected]>
+//
+// 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+//
+
+#ifndef VMIME_UTILITY_FILE_HPP_INCLUDED
+#define VMIME_UTILITY_FILE_HPP_INCLUDED
+
+
+#include "path.hpp"
+#include "../config.hpp"
+
+
+#if VMIME_HAVE_FILESYSTEM_FEATURES
+
+
+namespace vmime {
+namespace utility {
+
+
+class file;
+
+
+/** File list iterator (see file::getFiles).
+ */
+
+class fileIterator
+{
+public:
+
+ virtual ~fileIterator() { }
+
+ /** Check whether the cursor has reach the end of the list.
+ *
+ * @return true if you can call nextElement(), or false
+ * if no more file is available
+ */
+ virtual const bool hasMoreElements() const = 0;
+
+ /** Return the next file in the list.
+ *
+ * @return next file or NULL
+ */
+ virtual file* nextElement() = 0;
+};
+
+
+// TODO: fileWriter
+
+class fileWriter
+{
+public:
+
+ virtual ~fileWriter() { }
+
+ virtual utility::outputStream* getOutputStream() = 0;
+};
+
+
+// TODO: fileReader
+
+class fileReader
+{
+public:
+
+ virtual ~fileReader() { }
+
+ virtual utility::inputStream* getInputStream() = 0;
+};
+
+
+/** Abstract representation of a file or directory.
+ */
+
+class file
+{
+public:
+
+ typedef utility::path path;
+ typedef long length_type;
+
+
+ virtual ~file() { }
+
+
+ /** Create the file pointed by this file object.
+ */
+ virtual void createFile() = 0;
+
+ /** Create the directory pointed by this file object.
+ *
+ * @param createAll if set to true, recursively create all
+ * parent directories if they do not exist
+ */
+ virtual void createDirectory(const bool createAll = false) = 0;
+
+ /** Test whether this is a file.
+ *
+ * @return true if this is a file, false otherwise
+ */
+ virtual const bool isFile() const = 0;
+
+ /** Test whether this is a directory.
+ *
+ * @return true if this is a directory, false otherwise
+ */
+ virtual const bool isDirectory() const = 0;
+
+ /** Test whether this file is readible.
+ *
+ * @return true if we can read this file, false otherwise
+ */
+ virtual const bool canRead() const = 0;
+
+ /** Test whether this file is writeable.
+ *
+ * @return true if we can write to this file, false otherwise
+ */
+ virtual const bool canWrite() const = 0;
+
+ /** Return the length of this file.
+ *
+ * @return file size (in bytes)
+ */
+ virtual const length_type length() = 0;
+
+ /** Return the full path of this file/directory.
+ *
+ * @return full path of the file
+ */
+ virtual const path& fullPath() const = 0;
+
+ /** Test whether this file/directory exists.
+ *
+ * @return true if the file exists, false otherwise
+ */
+ virtual const bool exists() const = 0;
+
+ /** Return the parent directory of this file/directory.
+ *
+ * @return parent directory (or NULL if root)
+ */
+ virtual const file* getParent() const = 0;
+
+ /** Rename the file/directory.
+ *
+ * @param newName full path of the new file
+ */
+ virtual void rename(const path& newName) = 0;
+
+ /** Deletes this file/directory.
+ */
+ virtual void remove() = 0;
+
+
+ // TODO virtual fileWriter* getFileWriter() = 0;
+ // TODO virtual fileReader* getFileReader() = 0;
+
+ /** Enumerate files contained in this directory.
+ *
+ * @return file iterator to enumerate files
+ * @throw exceptions::not_a_directory if this is not a directory
+ */
+ virtual fileIterator* getFiles() const;
+};
+
+
+class fileSystemFactory
+{
+public:
+
+ virtual ~fileSystemFactory() { }
+
+ /** Create a new file object from the specified path.
+ *
+ * @param path full path (absolute) of the file
+ * @return new file object for the path
+ */
+ virtual file* create(const file::path& path) = 0;
+
+ /** Parse a path contained in a string.
+ *
+ * @param str string containing a path in a system-dependant representation
+ * @return path object (abstract representation)
+ */
+ virtual file::path stringToPath(const string& str) = 0;
+
+ /** Return the system-dependant string representation for the specified path.
+ *
+ * @param path abstract representation of the path
+ * @return string representation of the path
+ */
+ virtual string pathToString(const file::path& path) = 0;
+};
+
+
+} // utility
+} // vmime
+
+
+#endif // VMIME_HAVE_FILESYSTEM_FEATURES
+
+
+#endif // VMIME_UTILITY_FILE_HPP_INCLUDED
diff --git a/src/utility/md5.cpp b/src/utility/md5.cpp
new file mode 100644
index 00000000..e181a5d0
--- /dev/null
+++ b/src/utility/md5.cpp
@@ -0,0 +1,331 @@
+//
+// VMime library (http://vmime.sourceforge.net)
+// Copyright (C) 2002-2004 Vincent Richard <[email protected]>
+//
+// 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+//
+//
+// Derived from cryptoapi implementation, originally based on the
+// public domain implementation written by Colin Plumb in 1993.
+//
+// Copyright (C) Cryptoapi developers.
+//
+// Algorithm Copyright:
+//
+// Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
+// rights reserved.
+//
+// License to copy and use this software is granted provided that it
+// is identified as the "RSA Data Security, Inc. MD5 Message-Digest
+// Algorithm" in all material mentioning or referencing this software
+// or this function.
+//
+// License is also granted to make and use derivative works provided
+// that such works are identified as "derived from the RSA Data
+// Security, Inc. MD5 Message-Digest Algorithm" in all material
+// mentioning or referencing the derived work.
+//
+// RSA Data Security, Inc. makes no representations concerning either
+// the merchantability of this software or the suitability of this
+// software forany particular purpose. It is provided "as is"
+// without express or implied warranty of any kind.
+// These notices must be retained in any copies of any part of this
+// documentation and/or software.
+
+#include "md5.hpp"
+
+
+namespace vmime {
+namespace utility {
+
+
+md5::md5()
+ : m_finalized(false)
+{
+ init();
+}
+
+
+md5::md5(const vmime_uint8* const in, const unsigned long length)
+ : m_finalized(false)
+{
+ init();
+ update(in, length);
+}
+
+
+md5::md5(const string& in)
+ : m_finalized(false)
+{
+ init();
+ update((vmime_uint8*) in.c_str(), in.length());
+}
+
+
+void md5::init()
+{
+ m_hash[0] = 0x67452301;
+ m_hash[1] = 0xefcdab89;
+ m_hash[2] = 0x98badcfe;
+ m_hash[3] = 0x10325476;
+
+ m_byteCount = 0;
+}
+
+
+static void copyUint8Array(vmime_uint8* dest, const vmime_uint8* src, unsigned long count)
+{
+ for ( ; count >= 4 ; count -= 4, dest += 4, src += 4)
+ {
+ dest[0] = src[0];
+ dest[1] = src[1];
+ dest[2] = src[2];
+ dest[3] = src[3];
+ }
+
+ for ( ; count ; --count, ++dest, ++src)
+ dest[0] = src[0];
+}
+
+
+void md5::update(const string& in)
+{
+ update((vmime_uint8*) in.c_str(), in.length());
+}
+
+
+void md5::update(const vmime_uint8* data, unsigned long len)
+{
+ if (m_finalized)
+ return;
+
+ const unsigned long avail = 64 - (m_byteCount & 0x3f);
+
+ m_byteCount += len;
+
+ if (avail > len)
+ {
+ copyUint8Array(m_block + (64 - avail), data, len);
+ return;
+ }
+
+ copyUint8Array(m_block + (64 - avail), data, avail);
+ transformHelper();
+
+ data += avail;
+ len -= avail;
+
+ while (len >= 64)
+ {
+ copyUint8Array(m_block, data, 64);
+ transformHelper();
+
+ data += 64;
+ len -= 64;
+ }
+
+ copyUint8Array(m_block, data, len);
+}
+
+
+void md5::finalize()
+{
+ const long offset = m_byteCount & 0x3f;
+
+ vmime_uint8* p = m_block + offset;
+ long padding = 56 - (offset + 1);
+
+ *p++ = 0x80;
+
+ if (padding < 0)
+ {
+ memset(p, 0x00, padding + 8);
+ transformHelper();
+ p = m_block;
+ padding = 56;
+ }
+
+ memset(p, 0, padding);
+
+ ((vmime_uint32*) m_block)[14] = (m_byteCount << 3);
+ ((vmime_uint32*) m_block)[15] = (m_byteCount >> 29);
+
+#if VMIME_BYTE_ORDER_BIG_ENDIAN
+ swapUint32Array((vmime_uint32*) m_block, (64 - 8) / 4);
+#endif
+
+ transform();
+
+#if VMIME_BYTE_ORDER_BIG_ENDIAN
+ swapUint32Array((vmime_uint32*) m_hash, 4);
+#endif
+
+ m_finalized = true;
+}
+
+
+static inline vmime_uint32 swapUint32(const vmime_uint32 D)
+{
+ return ((D << 24) | ((D << 8) & 0x00FF0000) | ((D >> 8) & 0x0000FF00) | (D >> 24));
+}
+
+
+static inline void swapUint32Array(vmime_uint32* buf, unsigned long words)
+{
+ for ( ; words >= 4 ; words -= 4, buf += 4)
+ {
+ buf[0] = swapUint32(buf[0]);
+ buf[1] = swapUint32(buf[1]);
+ buf[2] = swapUint32(buf[2]);
+ buf[3] = swapUint32(buf[3]);
+ }
+
+ for ( ; words ; --words, ++buf)
+ buf[0] = swapUint32(buf[0]);
+}
+
+
+void md5::transformHelper()
+{
+#if VMIME_BYTE_ORDER_BIG_ENDIAN
+ swapUint32Array((vmime_uint32*) m_block, 64 / 4);
+#endif
+ transform();
+}
+
+
+void md5::transform()
+{
+ const vmime_uint32* const in = (vmime_uint32*) m_block;
+
+ vmime_uint32 a = m_hash[0];
+ vmime_uint32 b = m_hash[1];
+ vmime_uint32 c = m_hash[2];
+ vmime_uint32 d = m_hash[3];
+
+#define F1(x, y, z) (z ^ (x & (y ^ z)))
+#define F2(x, y, z) F1(z, x, y)
+#define F3(x, y, z) (x ^ y ^ z)
+#define F4(x, y, z) (y ^ (x | ~z))
+
+#define MD5STEP(f, w, x, y, z, in, s) \
+ (w += f(x, y, z) + in, w = (w<<s | w>>(32-s)) + x)
+
+ MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7);
+ MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12);
+ MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17);
+ MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22);
+ MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7);
+ MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12);
+ MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17);
+ MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22);
+ MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7);
+ MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12);
+ MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17);
+ MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22);
+ MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7);
+ MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12);
+ MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17);
+ MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22);
+
+ MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5);
+ MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9);
+ MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14);
+ MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20);
+ MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5);
+ MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9);
+ MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14);
+ MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20);
+ MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5);
+ MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9);
+ MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14);
+ MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20);
+ MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5);
+ MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9);
+ MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14);
+ MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20);
+
+ MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4);
+ MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11);
+ MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16);
+ MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23);
+ MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4);
+ MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11);
+ MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16);
+ MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23);
+ MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4);
+ MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11);
+ MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16);
+ MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23);
+ MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4);
+ MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11);
+ MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16);
+ MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23);
+
+ MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6);
+ MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10);
+ MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15);
+ MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21);
+ MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6);
+ MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10);
+ MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15);
+ MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21);
+ MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6);
+ MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10);
+ MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15);
+ MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21);
+ MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6);
+ MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10);
+ MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15);
+ MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21);
+
+ m_hash[0] += a;
+ m_hash[1] += b;
+ m_hash[2] += c;
+ m_hash[3] += d;
+}
+
+
+const string md5::hex()
+{
+ if (!m_finalized)
+ finalize();
+
+ static const unsigned char hex[] = "0123456789abcdef";
+
+ std::ostringstream oss;
+ const vmime_uint8* const digest = (vmime_uint8*) m_hash;
+
+ for (int i = 0 ; i < 16 ; ++i)
+ {
+ oss << hex[(digest[i] & 0xf0) >> 4];
+ oss << hex[(digest[i] & 0x0f)];
+ }
+
+ return (oss.str());
+}
+
+
+const vmime_uint8* md5::hash()
+{
+ if (!m_finalized)
+ finalize();
+
+ return ((vmime_uint8*) m_hash);
+}
+
+
+} // utility
+} // vmime
diff --git a/src/utility/md5.hpp b/src/utility/md5.hpp
new file mode 100644
index 00000000..dc9bb384
--- /dev/null
+++ b/src/utility/md5.hpp
@@ -0,0 +1,68 @@
+//
+// VMime library (http://vmime.sourceforge.net)
+// Copyright (C) 2002-2004 Vincent Richard <[email protected]>
+//
+// 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+//
+
+#ifndef VMIME_UTILITY_MD5_HPP_INCLUDED
+#define VMIME_UTILITY_MD5_HPP_INCLUDED
+
+
+#include "base.hpp"
+#include "config.hpp"
+
+
+namespace vmime {
+namespace utility {
+
+
+class md5
+{
+public:
+
+ md5();
+ md5(const vmime_uint8* const in, const unsigned long length);
+ md5(const string& in);
+
+public:
+
+ const string hex();
+ const vmime_uint8* hash();
+
+ void update(const vmime_uint8* data, unsigned long len);
+ void update(const string& in);
+
+protected:
+
+ void init();
+ void transformHelper();
+ void transform();
+ void finalize();
+
+ vmime_uint32 m_hash[4];
+
+ unsigned long m_byteCount;
+ vmime_uint8 m_block[64];
+
+ bool m_finalized;
+};
+
+
+} // utility
+} // vmime
+
+
+#endif // VMIME_UTILITY_MD5_HPP_INCLUDED
diff --git a/src/utility/path.cpp b/src/utility/path.cpp
new file mode 100644
index 00000000..477f29dd
--- /dev/null
+++ b/src/utility/path.cpp
@@ -0,0 +1,196 @@
+//
+// VMime library (http://vmime.sourceforge.net)
+// Copyright (C) 2002-2004 Vincent Richard <[email protected]>
+//
+// 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+//
+
+#include "path.hpp"
+
+#include <algorithm>
+
+
+namespace vmime {
+namespace utility {
+
+
+path::path()
+{
+}
+
+
+path::path(const component& c)
+{
+ m_list.push_back(c);
+}
+
+
+path::path(const path& p)
+{
+ m_list.resize(p.m_list.size());
+ std::copy(p.m_list.begin(), p.m_list.end(), m_list.begin());
+}
+
+
+path::path(const string& s)
+{
+ m_list.push_back(component(s));
+}
+
+
+path path::operator/(const path& p) const
+{
+ path pr(*this);
+ pr /= p;
+
+ return (pr);
+}
+
+
+path path::operator/(const component& c) const
+{
+ path pr(*this);
+ pr /= c;
+
+ return (pr);
+}
+
+
+path& path::operator/=(const path& p)
+{
+ const list::size_type size = m_list.size();
+
+ m_list.resize(size + p.m_list.size());
+ std::copy(p.m_list.begin(), p.m_list.end(), m_list.begin() + size);
+
+ return (*this);
+}
+
+
+path& path::operator/=(const component& c)
+{
+ m_list.push_back(c);
+ return (*this);
+}
+
+
+path path::parent() const
+{
+ path p;
+
+ if (!empty())
+ {
+ p.m_list.resize(m_list.size() - 1);
+ std::copy(m_list.begin(), m_list.end() - 1, p.m_list.begin());
+ }
+
+ return (p);
+}
+
+
+path& path::operator=(const path& p)
+{
+ m_list.resize(p.m_list.size());
+ std::copy(p.m_list.begin(), p.m_list.end(), m_list.begin());
+
+ return (*this);
+}
+
+
+path& path::operator=(const component& c)
+{
+ m_list.resize(1);
+ m_list[0] = c;
+
+ return (*this);
+}
+
+
+const bool path::operator==(const path& p) const
+{
+ if (m_list.size() != p.m_list.size())
+ return (false);
+
+ list::const_iterator i = m_list.begin();
+ list::const_iterator j = p.m_list.begin();
+
+ bool equal = true;
+
+ for ( ; equal && i != m_list.end() ; ++i, ++j)
+ //equal = (*i == *j);
+ equal = ((*i).buffer() == (*j).buffer());
+
+ return (equal);
+}
+
+
+const bool path::operator!=(const path& p) const
+{
+ return (!(*this == p));
+}
+
+
+const bool path::empty() const
+{
+ return (m_list.empty());
+}
+
+
+const path::component path::last() const
+{
+ return (empty() ? component("") : m_list[m_list.size() - 1]);
+}
+
+
+path::component& path::last()
+{
+ return (m_list[m_list.size() - 1]);
+}
+
+
+const int path::size() const
+{
+ return (m_list.size());
+}
+
+
+const path::component& path::operator[](const int x) const
+{
+ return (m_list[x]);
+}
+
+
+path::component& path::operator[](const int x)
+{
+ return (m_list[x]);
+}
+
+
+const bool path::isDirectParentOf(const path& p) const
+{
+ if (p.size() != size() + 1)
+ return (false);
+
+ bool equal = true;
+
+ for (int i = 0 ; equal && i < size() ; ++i)
+ equal = (m_list[i] == p.m_list[i]);
+
+ return (equal);
+}
+
+
+} // utility
+} // vmime
diff --git a/src/utility/path.hpp b/src/utility/path.hpp
new file mode 100644
index 00000000..bc980889
--- /dev/null
+++ b/src/utility/path.hpp
@@ -0,0 +1,124 @@
+//
+// VMime library (http://vmime.sourceforge.net)
+// Copyright (C) 2002-2004 Vincent Richard <[email protected]>
+//
+// 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+//
+
+#ifndef VMIME_UTILITY_PATH_HPP_INCLUDED
+#define VMIME_UTILITY_PATH_HPP_INCLUDED
+
+
+#include <vector>
+
+#include "../types.hpp"
+#include "../word.hpp"
+
+
+namespace vmime {
+namespace utility {
+
+
+/** Abstract representation of a path (filesystem, mailbox, etc).
+ */
+
+class path
+{
+public:
+
+ typedef vmime::word component;
+ typedef std::vector <component> list;
+
+ // Construct a path
+ path();
+ path(const component& c);
+ path(const path& p);
+ path(const string& s);
+
+ // Append a component to a path
+ path operator/(const path& p) const;
+ path operator/(const component& c) const;
+
+ path& operator/=(const path& p);
+ path& operator/=(const component& c);
+
+ // Return the parent path
+ path parent() const;
+
+ // Assignment
+ path& operator=(const path& p);
+ path& operator=(const component& c);
+
+ // Path comparison
+ const bool operator==(const path& p) const;
+ const bool operator!=(const path& p) const;
+
+ /** Test whether this path is empty (root).
+ *
+ * @return true if the path is empty (no components = root)
+ */
+ const bool empty() const;
+
+ /** Return the last component of this path (const version).
+ *
+ * @return last component
+ */
+ const component last() const;
+
+ /** Return the last component of this path (non-const version).
+ *
+ * @return last component
+ */
+ component& last();
+
+ /** Return the number of components in this path.
+ *
+ * @return number of components
+ */
+ const int size() const;
+
+ /** Return the specified component of the path (const version).
+ *
+ * @param x index of the component
+ * @return component at the specified index
+ */
+ const component& operator[](const int x) const;
+
+ /** Return the specified component of the path (non-const version).
+ *
+ * @param x index of the component
+ * @return component at the specified index
+ */
+ component& operator[](const int x);
+
+ /** Test whether this path is a direct parent of another one.
+ *
+ * @param p other path
+ * @return true if the specified path is a child (direct or
+ * indirect) of this path, false otherwise
+ */
+ const bool isDirectParentOf(const path& p) const;
+
+private:
+
+ list m_list;
+};
+
+
+} // utility
+} // vmime
+
+
+#endif // VMIME_UTILITY_PATH_HPP_INCLUDED
diff --git a/src/utility/random.cpp b/src/utility/random.cpp
new file mode 100644
index 00000000..6896d83c
--- /dev/null
+++ b/src/utility/random.cpp
@@ -0,0 +1,59 @@
+//
+// VMime library (http://vmime.sourceforge.net)
+// Copyright (C) 2002-2004 Vincent Richard <[email protected]>
+//
+// 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+//
+
+#include "random.hpp"
+#include "platformDependant.hpp"
+
+#include <ctime>
+
+
+namespace vmime {
+namespace utility {
+
+
+unsigned int random::m_next(static_cast<unsigned int>(::std::time(NULL)));
+
+
+const unsigned int random::next()
+{
+ // Park and Miller's minimal standard generator:
+ // xn+1 = (a * xn + b) mod c
+ // xn+1 = (16807 * xn) mod (2^31 - 1)
+ static const unsigned long a = 16807;
+ static const unsigned long c = (1 << ((sizeof(int) << 3) - 1));
+
+ m_next = static_cast<unsigned int>((a * m_next) % c);
+ return (m_next);
+}
+
+
+const unsigned int random::time()
+{
+ return (platformDependant::getHandler()->getUnixTime());
+}
+
+
+const unsigned int random::process()
+{
+ return (platformDependant::getHandler()->getProcessId());
+}
+
+
+} // utility
+} // vmime
diff --git a/src/utility/random.hpp b/src/utility/random.hpp
new file mode 100644
index 00000000..0d9dd92a
--- /dev/null
+++ b/src/utility/random.hpp
@@ -0,0 +1,62 @@
+//
+// VMime library (http://vmime.sourceforge.net)
+// Copyright (C) 2002-2004 Vincent Richard <[email protected]>
+//
+// 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+//
+
+#ifndef VMIME_UTILITY_RANDOM_HPP_INCLUDED
+#define VMIME_UTILITY_RANDOM_HPP_INCLUDED
+
+
+namespace vmime {
+namespace utility {
+
+
+class random
+{
+public:
+
+ /** Return a new random number.
+ *
+ * @return random number
+ */
+ static const unsigned int next();
+
+ /** Return the current time as a number (may be used to
+ * build "random" strings).
+ *
+ * @return time as a number
+ */
+ static const unsigned int time();
+
+ /** Return the current process number (may be user to
+ * build "random" strings).
+ *
+ * @return process number
+ */
+ static const unsigned int process();
+
+protected:
+
+ static unsigned int m_next;
+};
+
+
+} // utility
+} // vmime
+
+
+#endif // VMIME_UTILITY_RANDOM_HPP_INCLUDED
diff --git a/src/utility/singleton.cpp b/src/utility/singleton.cpp
new file mode 100644
index 00000000..c960a64a
--- /dev/null
+++ b/src/utility/singleton.cpp
@@ -0,0 +1,53 @@
+//
+// VMime library (http://vmime.sourceforge.net)
+// Copyright (C) 2002-2004 Vincent Richard <[email protected]>
+//
+// 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+//
+
+#include "singleton.hpp"
+
+
+namespace vmime {
+namespace utility {
+
+
+singletonManager::singletonManager()
+{
+}
+
+
+singletonManager::~singletonManager()
+{
+ for (std::list <abstractSingleton*>::iterator it = m_list.begin() ; it != m_list.end() ; ++it)
+ delete (*it);
+}
+
+
+singletonManager* singletonManager::getInstance()
+{
+ static singletonManager inst;
+ return (&inst);
+}
+
+
+void singletonManager::manage(abstractSingleton* s)
+{
+ m_list.push_back(s);
+}
+
+
+} // utility
+} // vmime
diff --git a/src/utility/singleton.hpp b/src/utility/singleton.hpp
new file mode 100644
index 00000000..33def75b
--- /dev/null
+++ b/src/utility/singleton.hpp
@@ -0,0 +1,92 @@
+//
+// VMime library (http://vmime.sourceforge.net)
+// Copyright (C) 2002-2004 Vincent Richard <[email protected]>
+//
+// 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+//
+
+#ifndef VMIME_UTILITY_SINGLETON_HPP_INCLUDED
+#define VMIME_UTILITY_SINGLETON_HPP_INCLUDED
+
+
+#include <list>
+
+
+namespace vmime {
+namespace utility {
+
+
+// Singleton abstract base class.
+
+class abstractSingleton
+{
+ friend class singletonManager;
+
+protected:
+
+ abstractSingleton() { }
+ virtual ~abstractSingleton() { }
+};
+
+
+// Singleton manager
+// (for automatic clean-up of all instanciated singletons).
+
+class singletonManager
+{
+public:
+
+ static singletonManager* getInstance();
+
+ void manage(abstractSingleton* s);
+
+private:
+
+ singletonManager();
+ ~singletonManager();
+
+ std::list <abstractSingleton*> m_list;
+};
+
+
+// A singleton template.
+
+template <class TYPE>
+class singleton : public abstractSingleton
+{
+protected:
+
+ singleton() { }
+ ~singleton() { }
+
+public:
+
+ static TYPE* getInstance()
+ {
+ static TYPE* inst = NULL;
+
+ if (!inst)
+ singletonManager::getInstance()->manage(inst = new TYPE());
+
+ return (inst);
+ }
+};
+
+
+} // utility
+} // vmime
+
+
+#endif // VMIME_UTILITY_SINGLETON_HPP_INCLUDED
diff --git a/src/utility/smartPtr.hpp b/src/utility/smartPtr.hpp
new file mode 100644
index 00000000..9905ae2f
--- /dev/null
+++ b/src/utility/smartPtr.hpp
@@ -0,0 +1,166 @@
+//
+// VMime library (http://vmime.sourceforge.net)
+// Copyright (C) 2002-2004 Vincent Richard <[email protected]>
+//
+// 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+//
+
+#ifndef VMIME_UTILITY_SMARTPTR_HPP_INCLUDED
+#define VMIME_UTILITY_SMARTPTR_HPP_INCLUDED
+
+
+namespace vmime {
+namespace utility {
+
+
+/** Simple auto-delete pointer.
+ */
+
+template <class T>
+class auto_ptr
+{
+private:
+
+ T* const m_ptr;
+
+public:
+
+ auto_ptr(T* const ptr) : m_ptr(ptr) { }
+ ~auto_ptr() { delete (m_ptr); }
+
+ operator T*() { return (m_ptr); }
+
+ T* const operator ->() { return (m_ptr); }
+ T& operator *() { return (*m_ptr); }
+};
+
+
+/** Smart auto-delete, referencable and copiable pointer.
+ */
+
+template <class T>
+class smart_ptr
+{
+private:
+
+ struct data
+ {
+ int refCount;
+ T* ptr;
+ };
+
+ data* m_data;
+
+
+ typedef std::map <T*, data*> MapType;
+ static MapType sm_map;
+
+public:
+
+ smart_ptr() : m_data(NULL) { }
+ smart_ptr(T* const ptr) : m_data(NULL) { if (ptr) { attach(ptr); } }
+ smart_ptr(smart_ptr& ptr) : m_data(NULL) { if (ptr.m_data) { attach(ptr); } }
+
+ ~smart_ptr() { detach(); }
+
+ smart_ptr& operator=(smart_ptr& ptr)
+ {
+ attach(ptr);
+ return (*this);
+ }
+
+ smart_ptr& operator=(T* const ptr)
+ {
+ if (!ptr)
+ detach();
+ else
+ attach(ptr);
+
+ return (*this);
+ }
+
+ operator T*() { return (m_data ? m_data->ptr : NULL); }
+ operator const T*() { return (m_data ? m_data->ptr : NULL); }
+
+ T& operator *() { return (*(m_data->ptr)); }
+ T* operator ->() { return (m_data->ptr); }
+
+ const T* const ptr() const { return (m_data ? m_data->ptr : NULL); }
+ T* const ptr() { return (m_data ? m_data->ptr : NULL); }
+
+private:
+
+ void detach()
+ {
+ if (m_data)
+ {
+ if (m_data->refCount == 1)
+ {
+ typename MapType::iterator it = sm_map.find(m_data->ptr);
+ if (it != sm_map.end()) sm_map.erase(it);
+
+ delete (m_data->ptr);
+ delete (m_data);
+ }
+ else
+ {
+ m_data->refCount--;
+ }
+
+ m_data = NULL;
+ }
+ }
+
+ void attach(T* const ptr)
+ {
+ detach();
+
+ typename MapType::iterator it = sm_map.find(ptr);
+
+ if (it != sm_map.end())
+ {
+ (*it).second->refCount++;
+ }
+ else
+ {
+ m_data = new data;
+ m_data->refCount = 1;
+ m_data->ptr = ptr;
+
+ sm_map.insert(typename MapType::value_type(ptr, m_data));
+ }
+ }
+
+ void attach(smart_ptr <T>& ptr)
+ {
+ data* newData = ptr.m_data;
+ if (newData) newData->refCount++;
+
+ detach();
+
+ m_data = newData;
+ }
+};
+
+
+template <class T>
+typename smart_ptr <T>::MapType smart_ptr <T>::sm_map;
+
+
+} // utility
+} // vmime
+
+
+#endif // VMIME_UTILITY_SMARTPTR_HPP_INCLUDED
diff --git a/src/utility/stream.cpp b/src/utility/stream.cpp
new file mode 100644
index 00000000..06d4ba27
--- /dev/null
+++ b/src/utility/stream.cpp
@@ -0,0 +1,257 @@
+//
+// VMime library (http://vmime.sourceforge.net)
+// Copyright (C) 2002-2004 Vincent Richard <[email protected]>
+//
+// 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+//
+
+#include "stream.hpp"
+#include "stringProxy.hpp"
+
+#include <algorithm> // for std::copy
+#include <iterator> // for std::back_inserter
+
+
+namespace vmime {
+namespace utility {
+
+
+// Helpers
+
+outputStream& operator<<(outputStream& os, const stream::value_type c)
+{
+ os.write(&c, 1);
+ return (os);
+}
+
+
+outputStream& operator<<(outputStream& os, const string& str)
+{
+ os.write(str.data(), str.length());
+ return (os);
+}
+
+
+const stream::size_type bufferedStreamCopy(inputStream& is, outputStream& os)
+{
+ stream::value_type buffer[65536];
+ stream::size_type total = 0;
+
+ while (!is.eof())
+ {
+ const stream::size_type read = is.read(buffer, sizeof(buffer));
+
+ if (read != 0)
+ {
+ os.write(buffer, read);
+ total += read;
+ }
+ }
+
+ return (total);
+}
+
+
+
+// outputStreamAdapter
+
+outputStreamAdapter::outputStreamAdapter(std::ostream& os)
+ : m_stream(os)
+{
+}
+
+
+void outputStreamAdapter::write
+ (const value_type* const data, const size_type count)
+{
+ m_stream.write(data, count);
+}
+
+
+
+// outputStreamStringAdapter
+
+outputStreamStringAdapter::outputStreamStringAdapter(string& buffer)
+ : m_buffer(buffer)
+{
+ m_buffer.clear();
+}
+
+
+void outputStreamStringAdapter::write(const value_type* const data, const size_type count)
+{
+ // TODO: better way?
+ std::copy(data, data + count, std::back_inserter(m_buffer));
+}
+
+
+
+// inputStreamAdapter
+
+inputStreamAdapter::inputStreamAdapter(std::istream& is)
+ : m_stream(is)
+{
+}
+
+
+const bool inputStreamAdapter::eof() const
+{
+ return (m_stream.eof());
+}
+
+
+void inputStreamAdapter::reset()
+{
+ m_stream.seekg(0, std::ios::beg);
+ m_stream.clear();
+}
+
+
+const stream::size_type inputStreamAdapter::read
+ (value_type* const data, const size_type count)
+{
+ m_stream.read(data, count);
+ return (m_stream.gcount());
+}
+
+
+
+// inputStreamStringAdapter
+
+inputStreamStringAdapter::inputStreamStringAdapter(const string& buffer)
+ : m_buffer(buffer), m_begin(0), m_end(buffer.length()), m_pos(0)
+{
+}
+
+
+inputStreamStringAdapter::inputStreamStringAdapter(const string& buffer,
+ const string::size_type begin, const string::size_type end)
+ : m_buffer(buffer), m_begin(begin), m_end(end), m_pos(begin)
+{
+}
+
+
+const bool inputStreamStringAdapter::eof() const
+{
+ return (m_pos >= m_end);
+}
+
+
+void inputStreamStringAdapter::reset()
+{
+ m_pos = m_begin;
+}
+
+
+const stream::size_type inputStreamStringAdapter::read
+ (value_type* const data, const size_type count)
+{
+ if (m_pos + count >= m_end)
+ {
+ const size_type remaining = m_end - m_pos;
+
+ std::copy(m_buffer.begin() + m_pos, m_buffer.end(), data);
+ m_pos = m_end;
+ return (remaining);
+ }
+ else
+ {
+ std::copy(m_buffer.begin() + m_pos, m_buffer.begin() + m_pos + count, data);
+ m_pos += count;
+ return (count);
+ }
+}
+
+
+
+// inputStreamStringProxyAdapter
+
+inputStreamStringProxyAdapter::inputStreamStringProxyAdapter(const stringProxy& buffer)
+ : m_buffer(buffer), m_pos(0)
+{
+}
+
+
+const bool inputStreamStringProxyAdapter::eof() const
+{
+ return (m_pos >= m_buffer.length());
+}
+
+
+void inputStreamStringProxyAdapter::reset()
+{
+ m_pos = 0;
+}
+
+
+const stream::size_type inputStreamStringProxyAdapter::read
+ (value_type* const data, const size_type count)
+{
+ const size_type remaining = m_buffer.length() - m_pos;
+
+ if (count > remaining)
+ {
+ std::copy(m_buffer.it_begin() + m_pos, m_buffer.it_end(), data);
+ m_pos = m_buffer.length();
+ return (remaining);
+ }
+ else
+ {
+ std::copy(m_buffer.it_begin() + m_pos, m_buffer.it_begin() + m_pos + count, data);
+ m_pos += count;
+ return (count);
+ }
+}
+
+
+
+// inputStreamPointerAdapter
+
+inputStreamPointerAdapter::inputStreamPointerAdapter(std::istream* is, const bool own)
+ : m_stream(is), m_own(own)
+{
+}
+
+
+inputStreamPointerAdapter::~inputStreamPointerAdapter()
+{
+ if (m_own)
+ delete (m_stream);
+}
+
+
+const bool inputStreamPointerAdapter::eof() const
+{
+ return (m_stream->eof());
+}
+
+
+void inputStreamPointerAdapter::reset()
+{
+ m_stream->seekg(0, std::ios::beg);
+ m_stream->clear();
+}
+
+
+const stream::size_type inputStreamPointerAdapter::read
+ (value_type* const data, const size_type count)
+{
+ m_stream->read(data, count);
+ return (m_stream->gcount());
+}
+
+
+} // utility
+} // vmime
diff --git a/src/utility/stream.hpp b/src/utility/stream.hpp
new file mode 100644
index 00000000..8f8de54c
--- /dev/null
+++ b/src/utility/stream.hpp
@@ -0,0 +1,263 @@
+//
+// VMime library (http://vmime.sourceforge.net)
+// Copyright (C) 2002-2004 Vincent Richard <[email protected]>
+//
+// 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+//
+
+#ifndef VMIME_UTILITY_STREAM_HPP_INCLUDED
+#define VMIME_UTILITY_STREAM_HPP_INCLUDED
+
+
+#include <istream>
+#include <ostream>
+
+#include "../types.hpp"
+
+
+namespace vmime {
+namespace utility {
+
+
+class stringProxy;
+
+
+/** Base class for input/output stream.
+ */
+
+class stream
+{
+public:
+
+ virtual ~stream() { }
+
+ /** Type used to read/write one byte in the stream.
+ */
+ typedef string::value_type value_type;
+
+ /** Type used for lengths in streams.
+ */
+ typedef string::size_type size_type;
+};
+
+
+
+/** Simple output stream.
+ */
+
+class outputStream : public stream
+{
+public:
+
+ /** Write data to the stream.
+ *
+ * @param data buffer containing data to write
+ * @param count number of bytes to write
+ */
+ virtual void write(const value_type* const data, const size_type count) = 0;
+};
+
+
+
+/** Simple input stream.
+ */
+
+class inputStream : public stream
+{
+public:
+
+ /** Test for end of stream (no more data to read).
+ *
+ * @return true if we have reached the end of stream, false otherwise
+ */
+ virtual const bool eof() const = 0;
+
+ /** Set the read pointer to the beginning of the stream.
+ *
+ * @warning WARNING: this may not work for all stream types.
+ */
+ virtual void reset() = 0;
+
+ /** Read data from the stream.
+ *
+ * @param data will receive the data read
+ * @param count maximum number of bytes to read
+ * @return number of bytes read
+ */
+ virtual const size_type read(value_type* const data, const size_type count) = 0;
+};
+
+
+
+// Helpers functions
+
+outputStream& operator<<(outputStream& os, const string& str);
+outputStream& operator<<(outputStream& os, const stream::value_type c);
+
+
+template <int N>
+outputStream& operator<<(outputStream& os, const char (&str)[N])
+{
+ os.write(str, N - 1);
+ return (os);
+}
+
+
+/** Copy data from one stream into another stream using a buffered method.
+ *
+ * @param is input stream (source data)
+ * @param os output stream (destination for data)
+ * @return number of bytes copied
+ */
+
+const stream::size_type bufferedStreamCopy(inputStream& is, outputStream& os);
+
+
+
+// Adapters
+
+
+/** An adapter class for C++ standard output streams.
+ */
+
+class outputStreamAdapter : public outputStream
+{
+public:
+
+ /** @param os output stream to wrap
+ */
+ outputStreamAdapter(std::ostream& os);
+
+ void write(const value_type* const data, const size_type count);
+
+private:
+
+ std::ostream& m_stream;
+};
+
+
+/** An adapter class for string output.
+ */
+
+class outputStreamStringAdapter : public outputStream
+{
+public:
+
+ outputStreamStringAdapter(string& buffer);
+
+ void write(const value_type* const data, const size_type count);
+
+private:
+
+ string& m_buffer;
+};
+
+
+/** An adapter class for C++ standard input streams.
+ */
+
+class inputStreamAdapter : public inputStream
+{
+public:
+
+ /** @param is input stream to wrap
+ */
+ inputStreamAdapter(std::istream& is);
+
+ const bool eof() const;
+ void reset();
+ const size_type read(value_type* const data, const size_type count);
+
+private:
+
+ std::istream& m_stream;
+};
+
+
+/** An adapter class for string input.
+ */
+
+class inputStreamStringAdapter : public inputStream
+{
+public:
+
+ inputStreamStringAdapter(const string& buffer);
+ inputStreamStringAdapter(const string& buffer, const string::size_type begin, const string::size_type end);
+
+ const bool eof() const;
+ void reset();
+ const size_type read(value_type* const data, const size_type count);
+
+private:
+
+ const string m_buffer; // do _NOT_ keep a reference...
+ const string::size_type m_begin;
+ const string::size_type m_end;
+ string::size_type m_pos;
+};
+
+
+/** An adapter class for stringProxy input.
+ */
+
+class inputStreamStringProxyAdapter : public inputStream
+{
+public:
+
+ /** @param buffer stringProxy object to wrap
+ */
+ inputStreamStringProxyAdapter(const stringProxy& buffer);
+
+ const bool eof() const;
+ void reset();
+ const size_type read(value_type* const data, const size_type count);
+
+private:
+
+ const stringProxy& m_buffer;
+ string::size_type m_pos;
+};
+
+
+/** An adapter class for pointer to C++ standard input stream.
+ */
+
+class inputStreamPointerAdapter : public inputStream
+{
+public:
+
+ /** @param is input stream to wrap
+ * @param own if set to 'true', the pointer will be deleted when
+ * this object is destroyed
+ */
+ inputStreamPointerAdapter(std::istream* is, const bool own = true);
+ ~inputStreamPointerAdapter();
+
+ const bool eof() const;
+ void reset();
+ const size_type read(value_type* const data, const size_type count);
+
+private:
+
+ std::istream* m_stream;
+ const bool m_own;
+};
+
+
+} // utility
+} // vmime
+
+
+#endif // VMIME_UTILITY_STREAM_HPP_INCLUDED
diff --git a/src/utility/stringProxy.cpp b/src/utility/stringProxy.cpp
new file mode 100644
index 00000000..f79e8a58
--- /dev/null
+++ b/src/utility/stringProxy.cpp
@@ -0,0 +1,131 @@
+//
+// VMime library (http://vmime.sourceforge.net)
+// Copyright (C) 2002-2004 Vincent Richard <[email protected]>
+//
+// 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+//
+
+#include "stringProxy.hpp"
+
+#include <iterator>
+#include <algorithm>
+
+
+namespace vmime {
+namespace utility {
+
+
+stringProxy::stringProxy()
+ : m_start(0), m_end(0)
+{
+}
+
+
+stringProxy::stringProxy(const stringProxy& s)
+ : m_buffer(s.m_buffer), m_start(s.m_start), m_end(s.m_end)
+{
+}
+
+
+stringProxy::stringProxy(const string_type& s, const size_type start, const size_type end)
+ : m_buffer(s), m_start(start),
+ m_end(end == std::numeric_limits <size_type>::max() ? s.length() : end)
+{
+}
+
+
+void stringProxy::set(const string_type& s, const size_type start, const size_type end)
+{
+ m_buffer = s;
+ m_start = start;
+
+ if (end == std::numeric_limits <size_type>::max())
+ m_end = s.length();
+ else
+ m_end = end;
+}
+
+
+void stringProxy::detach()
+{
+ m_buffer.clear();
+ m_start = m_end = 0;
+}
+
+
+stringProxy& stringProxy::operator=(const stringProxy& s)
+{
+ m_buffer = s.m_buffer;
+ m_start = s.m_start;
+ m_end = s.m_end;
+
+ return (*this);
+}
+
+
+stringProxy& stringProxy::operator=(const string_type& s)
+{
+ m_buffer = s;
+ m_start = 0;
+ m_end = s.length();
+
+ return (*this);
+}
+
+
+void stringProxy::extract(outputStream& os, const size_type start, const size_type end) const
+{
+ if (end == std::numeric_limits <size_type>::max())
+ os.write(m_buffer.data() + m_start + start, m_end - start - m_start);
+ else
+ os.write(m_buffer.data() + m_start + start, end - start - m_start);
+}
+
+
+const stringProxy::size_type stringProxy::length() const
+{
+ return (m_end - m_start);
+}
+
+
+const stringProxy::size_type stringProxy::start() const
+{
+ return (m_start);
+}
+
+
+const stringProxy::size_type stringProxy::end() const
+{
+ return (m_end);
+}
+
+
+std::ostream& operator<<(std::ostream& os, const stringProxy& s)
+{
+ outputStreamAdapter adapter(os);
+ s.extract(adapter);
+ return (os);
+}
+
+
+outputStream& operator<<(outputStream& os, const stringProxy& s)
+{
+ s.extract(os);
+ return (os);
+}
+
+
+} // utility
+} // vmime
diff --git a/src/utility/stringProxy.hpp b/src/utility/stringProxy.hpp
new file mode 100644
index 00000000..e8001aed
--- /dev/null
+++ b/src/utility/stringProxy.hpp
@@ -0,0 +1,90 @@
+//
+// VMime library (http://vmime.sourceforge.net)
+// Copyright (C) 2002-2004 Vincent Richard <[email protected]>
+//
+// 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+//
+
+#ifndef VMIME_UTILITY_STRINGPROXY_HPP_INCLUDED
+#define VMIME_UTILITY_STRINGPROXY_HPP_INCLUDED
+
+
+#include <limits>
+
+#include "../types.hpp"
+#include "stream.hpp"
+
+
+namespace vmime {
+namespace utility {
+
+
+/** This class is a proxy for the string class. This takes
+ * advantage of the COW (copy-on-write) system that might
+ * be used in "std::string" implementation.
+ */
+
+class stringProxy
+{
+public:
+
+ typedef string::size_type size_type;
+ typedef string string_type;
+
+
+ // Consruction
+ stringProxy();
+ stringProxy(const stringProxy& s);
+ stringProxy(const string_type& s, const size_type start = 0, const size_type end = std::numeric_limits <size_type>::max());
+
+ // Assignment
+ void set(const string_type& s, const size_type start = 0, const size_type end = std::numeric_limits <size_type>::max());
+ void detach();
+
+ stringProxy& operator=(const stringProxy& s);
+ stringProxy& operator=(const string_type& s);
+
+ // Extract some portion (or whole) of the string
+ // and output it into a stream.
+ void extract(outputStream& os, const size_type start = 0, const size_type end = std::numeric_limits <size_type>::max()) const;
+
+ // Return the "virtual" length of the string
+ const size_type length() const;
+
+ // Return the boundaries of the "virtual" string
+ const size_type start() const;
+ const size_type end() const;
+
+ string::const_iterator it_begin() const { return (m_buffer.begin() + m_start); }
+ string::const_iterator it_end() const { return (m_buffer.begin() + m_end); }
+
+private:
+
+ string_type m_buffer;
+
+ size_type m_start;
+ size_type m_end;
+};
+
+
+std::ostream& operator<<(std::ostream& os, const stringProxy& s);
+outputStream& operator<<(outputStream& os, const stringProxy& s);
+
+
+} // utility
+} // vmime
+
+
+#endif // VMIME_UTILITY_STRINGPROXY_HPP_INCLUDED