aboutsummaryrefslogtreecommitdiffstats
path: root/src/platforms/windows/windowsFile.cpp
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/platforms/windows/windowsFile.cpp460
1 files changed, 460 insertions, 0 deletions
diff --git a/src/platforms/windows/windowsFile.cpp b/src/platforms/windows/windowsFile.cpp
new file mode 100644
index 00000000..04298120
--- /dev/null
+++ b/src/platforms/windows/windowsFile.cpp
@@ -0,0 +1,460 @@
+//
+// VMime library (http://vmime.sourceforge.net)
+// Copyright (C) 2002-2005 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 "vmime/platforms/windows/windowsFile.hpp"
+
+#include <windows.h>
+#include <string.h>
+
+#include "vmime/exception.hpp"
+
+
+#if VMIME_HAVE_FILESYSTEM_FEATURES
+
+
+namespace vmime {
+namespace platforms {
+namespace windows {
+
+
+vmime::utility::file* windowsFileSystemFactory::create(const vmime::utility::file::path& path) const
+{
+ return new windowsFile(path);
+}
+
+
+const vmime::utility::file::path windowsFileSystemFactory::stringToPath(const vmime::string& str) const
+{
+ return (stringToPathImpl(str));
+}
+
+
+const vmime::string windowsFileSystemFactory::pathToString(const vmime::utility::file::path& path) const
+{
+ return (pathToStringImpl(path));
+}
+
+
+const vmime::utility::file::path windowsFileSystemFactory::stringToPathImpl(const vmime::string& str)
+{
+ vmime::string::size_type offset = 0;
+ vmime::string::size_type prev = 0;
+
+ vmime::utility::file::path path;
+
+ while ((offset = str.find_first_of("\\", offset)) != vmime::string::npos)
+ {
+ if (offset != prev)
+ path.appendComponent(vmime::string(str.begin() + prev, str.begin() + offset));
+
+ prev = offset + 1;
+ offset++;
+ }
+
+ if (prev < str.length())
+ path.appendComponent(vmime::string(str.begin() + prev, str.end()));
+
+ return (path);
+}
+
+
+const vmime::string windowsFileSystemFactory::pathToStringImpl(const vmime::utility::file::path& path)
+{
+ vmime::string native = "";
+
+ for (int i = 0 ; i < path.getSize() ; ++i)
+ {
+ if (i > 0)
+ native += "\\";
+
+ native += path[i].getBuffer();
+ }
+
+ return (native);
+}
+
+
+const bool windowsFileSystemFactory::isValidPathComponent(const vmime::utility::file::path::component& comp) const
+{
+ return (comp.getBuffer().find_first_of("\\*") == vmime::string::npos);
+}
+
+
+const bool windowsFileSystemFactory::isValidPath(const vmime::utility::file::path& path) const
+{
+ for (int i = 0 ; i < path.getSize() ; ++i)
+ {
+ if (!isValidPathComponent(path[i]))
+ return false;
+ }
+
+ return true;
+}
+
+
+void windowsFileSystemFactory::reportError(const vmime::utility::path& path, const int err)
+{
+ vmime::string desc;
+
+ LPVOID lpMsgBuf;
+ if (FormatMessage(
+ FORMAT_MESSAGE_ALLOCATE_BUFFER |
+ FORMAT_MESSAGE_FROM_SYSTEM |
+ FORMAT_MESSAGE_IGNORE_INSERTS,
+ NULL,
+ err,
+ MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+ (LPTSTR) &lpMsgBuf,
+ 0,
+ NULL ))
+ {
+ desc = (char*)lpMsgBuf;
+ LocalFree( lpMsgBuf );
+ }
+
+ throw vmime::exceptions::filesystem_exception(desc, path);
+}
+
+windowsFile::windowsFile(const vmime::utility::file::path& path)
+: m_path(path), m_nativePath(windowsFileSystemFactory::pathToStringImpl(path))
+{
+}
+
+void windowsFile::createFile()
+{
+ HANDLE hFile = CreateFile(
+ m_nativePath.c_str(),
+ GENERIC_WRITE,
+ 0,
+ NULL,
+ CREATE_ALWAYS,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL);
+ if (hFile == INVALID_HANDLE_VALUE)
+ windowsFileSystemFactory::reportError(m_path, GetLastError());
+
+ CloseHandle(hFile);
+}
+
+void windowsFile::createDirectory(const bool createAll)
+{
+ createDirectoryImpl(m_path, m_path, createAll);
+}
+
+const bool windowsFile::isFile() const
+{
+ DWORD dwFileAttribute = GetFileAttributes(m_nativePath.c_str());
+ if (dwFileAttribute == INVALID_FILE_ATTRIBUTES)
+ return false;
+ return (dwFileAttribute & FILE_ATTRIBUTE_DIRECTORY) == 0;
+}
+
+const bool windowsFile::isDirectory() const
+{
+ DWORD dwFileAttribute = GetFileAttributes(m_nativePath.c_str());
+ if (dwFileAttribute == INVALID_FILE_ATTRIBUTES)
+ return false;
+ return (dwFileAttribute & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY;
+}
+
+const bool windowsFile::canRead() const
+{
+ HANDLE hFile = CreateFile(
+ m_nativePath.c_str(),
+ GENERIC_READ,
+ 0,
+ NULL,
+ OPEN_EXISTING,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL);
+ if (hFile == INVALID_HANDLE_VALUE)
+ return false;
+ CloseHandle(hFile);
+ return true;
+}
+
+const bool windowsFile::canWrite() const
+{
+ HANDLE hFile = CreateFile(
+ m_nativePath.c_str(),
+ GENERIC_WRITE,
+ 0,
+ NULL,
+ OPEN_ALWAYS,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL);
+ if (hFile == INVALID_HANDLE_VALUE)
+ return false;
+ CloseHandle(hFile);
+ return true;
+}
+
+const windowsFile::length_type windowsFile::getLength()
+{
+ HANDLE hFile = CreateFile(
+ m_nativePath.c_str(),
+ GENERIC_READ,
+ 0,
+ NULL,
+ OPEN_EXISTING,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL);
+ if (hFile == INVALID_HANDLE_VALUE)
+ windowsFileSystemFactory::reportError(m_path, GetLastError());
+
+ DWORD dwSize = GetFileSize(hFile, NULL);
+ CloseHandle(hFile);
+
+ return dwSize;
+}
+
+const vmime::utility::path& windowsFile::getFullPath() const
+{
+ return m_path;
+}
+
+const bool windowsFile::exists() const
+{
+ WIN32_FIND_DATA findData;
+ HANDLE hFind = FindFirstFile(m_nativePath.c_str(), &findData);
+ if (hFind != INVALID_HANDLE_VALUE)
+ {
+ FindClose(hFind);
+ return true;
+ }
+ return false;
+}
+
+const vmime::utility::file* windowsFile::getParent() const
+{
+ if (m_path.isEmpty())
+ return NULL;
+ else
+ return new windowsFile(m_path.getParent());
+}
+
+void windowsFile::rename(const path& newName)
+{
+ const vmime::string newNativeName = windowsFileSystemFactory::pathToStringImpl(newName);
+ if (MoveFile(m_nativePath.c_str(), newNativeName.c_str()))
+ {
+ m_path = newName;
+ m_nativePath = newNativeName;
+ }
+ else
+ windowsFileSystemFactory::reportError(m_path, GetLastError());
+}
+
+void windowsFile::remove()
+{
+ if (!DeleteFile(m_nativePath.c_str()))
+ windowsFileSystemFactory::reportError(m_path, GetLastError());
+}
+
+vmime::utility::fileWriter* windowsFile::getFileWriter()
+{
+ return new windowsFileWriter(m_path, m_nativePath);
+}
+
+vmime::utility::fileReader* windowsFile::getFileReader()
+{
+ return new windowsFileReader(m_path, m_nativePath);
+}
+
+vmime::utility::fileIterator* windowsFile::getFiles() const
+{
+ return new windowsFileIterator(m_path, m_nativePath);
+}
+
+void windowsFile::createDirectoryImpl(const vmime::utility::file::path& fullPath, const vmime::utility::file::path& path, const bool recursive)
+{
+ const vmime::string nativePath = windowsFileSystemFactory::pathToStringImpl(path);
+
+ windowsFile tmp(fullPath);
+ if (tmp.isDirectory())
+ return;
+
+ if (!path.isEmpty() && recursive)
+ createDirectoryImpl(fullPath, path.getParent(), true);
+
+ if (!CreateDirectory(nativePath.c_str(), NULL))
+ windowsFileSystemFactory::reportError(fullPath, GetLastError());
+}
+
+windowsFileIterator::windowsFileIterator(const vmime::utility::file::path& path, const vmime::string& nativePath)
+: m_path(path), m_nativePath(nativePath), m_moreElements(false), m_hFind(INVALID_HANDLE_VALUE)
+{
+ findFirst();
+}
+
+windowsFileIterator::~windowsFileIterator()
+{
+ if (m_hFind != INVALID_HANDLE_VALUE)
+ FindClose(m_hFind);
+}
+
+const bool windowsFileIterator::hasMoreElements() const
+{
+ return m_moreElements;
+}
+
+vmime::utility::file* windowsFileIterator::nextElement()
+{
+ vmime::utility::file* pFile = new windowsFile(m_path / vmime::utility::file::path::component(m_findData.cFileName));
+
+ findNext();
+
+ return pFile;
+}
+
+void windowsFileIterator::findFirst()
+{
+ m_hFind = FindFirstFile(m_nativePath.c_str(), &m_findData);
+ if (m_hFind == INVALID_HANDLE_VALUE)
+ {
+ m_moreElements = false;
+ return;
+ }
+
+ m_moreElements = true;
+ if (isCurrentOrParentDir())
+ findNext();
+}
+
+void windowsFileIterator::findNext()
+{
+ do
+ {
+ if (!FindNextFile(m_hFind, &m_findData))
+ {
+ m_moreElements = false;
+ return;
+ }
+ }
+ while (isCurrentOrParentDir());
+}
+
+bool windowsFileIterator::isCurrentOrParentDir() const
+{
+ vmime::string s(m_findData.cFileName);
+ if ((s == ".") || (s == ".."))
+ return true;
+ return false;
+}
+
+windowsFileReader::windowsFileReader(const vmime::utility::file::path& path, const vmime::string& nativePath)
+: m_path(path), m_nativePath(nativePath)
+{
+}
+
+vmime::utility::inputStream* windowsFileReader::getInputStream()
+{
+ HANDLE hFile = CreateFile(
+ m_nativePath.c_str(),
+ GENERIC_READ,
+ 0,
+ NULL,
+ OPEN_EXISTING,
+ 0,
+ NULL);
+ if (hFile == INVALID_HANDLE_VALUE)
+ windowsFileSystemFactory::reportError(m_path, GetLastError());
+ return new windowsFileReaderInputStream(m_path, hFile);
+}
+
+windowsFileReaderInputStream::windowsFileReaderInputStream(const vmime::utility::file::path& path, HANDLE hFile)
+: m_path(path), m_hFile(hFile)
+{
+}
+
+windowsFileReaderInputStream::~windowsFileReaderInputStream()
+{
+ CloseHandle(m_hFile);
+}
+
+const bool windowsFileReaderInputStream::eof() const
+{
+ DWORD dwSize = GetFileSize(m_hFile, NULL);
+ DWORD dwPosition = SetFilePointer(m_hFile, 0, NULL, FILE_CURRENT);
+ return (dwSize == dwPosition);
+}
+
+void windowsFileReaderInputStream::reset()
+{
+ SetFilePointer(m_hFile, 0, NULL, FILE_BEGIN);
+}
+
+const vmime::utility::stream::size_type windowsFileReaderInputStream::read(value_type* const data, const size_type count)
+{
+ DWORD dwBytesRead;
+ if (!ReadFile(m_hFile, (LPVOID)data, (DWORD)count, &dwBytesRead, NULL))
+ windowsFileSystemFactory::reportError(m_path, GetLastError());
+ return dwBytesRead;
+}
+
+const vmime::utility::stream::size_type windowsFileReaderInputStream::skip(const size_type count)
+{
+ DWORD dwCurPos = SetFilePointer(m_hFile, 0, NULL, FILE_CURRENT);
+ DWORD dwNewPos = SetFilePointer(m_hFile, (LONG)count, NULL, FILE_CURRENT);
+ return (dwNewPos - dwCurPos);
+}
+
+windowsFileWriter::windowsFileWriter(const vmime::utility::file::path& path, const vmime::string& nativePath)
+: m_path(path), m_nativePath(nativePath)
+{
+}
+
+vmime::utility::outputStream* windowsFileWriter::getOutputStream()
+{
+ HANDLE hFile = CreateFile(
+ m_nativePath.c_str(),
+ GENERIC_WRITE,
+ 0,
+ NULL,
+ CREATE_ALWAYS,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL);
+ if (hFile == INVALID_HANDLE_VALUE)
+ windowsFileSystemFactory::reportError(m_path, GetLastError());
+ return new windowsFileWriterOutputStream(m_path, hFile);
+}
+
+windowsFileWriterOutputStream::windowsFileWriterOutputStream(const vmime::utility::file::path& path, HANDLE hFile)
+: m_path(path), m_hFile(hFile)
+{
+}
+
+windowsFileWriterOutputStream::~windowsFileWriterOutputStream()
+{
+ CloseHandle(m_hFile);
+}
+
+void windowsFileWriterOutputStream::write(const value_type* const data, const size_type count)
+{
+ DWORD dwBytesWritten;
+ if (!WriteFile(m_hFile, data, (DWORD)count, &dwBytesWritten, NULL))
+ windowsFileSystemFactory::reportError(m_path, GetLastError());
+}
+
+} // windows
+} // platforms
+} // vmime
+
+
+#endif // VMIME_HAVE_FILESYSTEM_FEATURES