diff options
Diffstat (limited to 'src/utility')
-rw-r--r-- | src/utility/file.hpp | 218 | ||||
-rw-r--r-- | src/utility/md5.cpp | 331 | ||||
-rw-r--r-- | src/utility/md5.hpp | 68 | ||||
-rw-r--r-- | src/utility/path.cpp | 196 | ||||
-rw-r--r-- | src/utility/path.hpp | 124 | ||||
-rw-r--r-- | src/utility/random.cpp | 59 | ||||
-rw-r--r-- | src/utility/random.hpp | 62 | ||||
-rw-r--r-- | src/utility/singleton.cpp | 53 | ||||
-rw-r--r-- | src/utility/singleton.hpp | 92 | ||||
-rw-r--r-- | src/utility/smartPtr.hpp | 166 | ||||
-rw-r--r-- | src/utility/stream.cpp | 257 | ||||
-rw-r--r-- | src/utility/stream.hpp | 263 | ||||
-rw-r--r-- | src/utility/stringProxy.cpp | 131 | ||||
-rw-r--r-- | src/utility/stringProxy.hpp | 90 |
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 |