📄 windowsfile.cpp
字号:
//// VMime library (http://vmime.sourceforge.net)// Copyright (C) 2002-2008 Vincent Richard <vincent@vincent-richard.net>//// This program is free software; you can redistribute it and/or// modify it under the terms of the GNU General Public License as// published by the Free Software Foundation; either version 2 of// the License, or (at your option) any later version.//// This program is distributed in the hope that it will be useful,// but WITHOUT ANY WARRANTY; without even the implied warranty of// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU// General Public License for more details.//// You should have received a copy of the GNU General Public License along// with this program; if not, write to the Free Software Foundation, Inc.,// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.//// Linking this library statically or dynamically with other modules is making// a combined work based on this library. Thus, the terms and conditions of// the GNU General Public License cover the whole combination.//#include "vmime/platforms/windows/windowsFile.hpp"#include <windows.h>#include <string.h>#include "vmime/exception.hpp"#include "vmime/utility/stringUtils.hpp"#if VMIME_HAVE_FILESYSTEM_FEATURESnamespace vmime {namespace platforms {namespace windows {ref <vmime::utility::file> windowsFileSystemFactory::create(const vmime::utility::file::path& path) const{ return vmime::create <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);}bool windowsFileSystemFactory::isValidPathComponent(const vmime::utility::file::path::component& comp) const{ return isValidPathComponent(comp, false);}bool windowsFileSystemFactory::isValidPathComponent( const vmime::utility::file::path::component& comp, bool firstComponent) const{ const string& buffer = comp.getBuffer(); // If first component, check if component is a drive if (firstComponent && (buffer.length() == 2) && (buffer[1] == ':')) { char drive = tolower(buffer[0]); if ((drive >= 'a') && (drive <= 'z')) return true; } // Check for invalid characters for (string::size_type i = 0 ; i < buffer.length() ; ++i) { const unsigned char c = buffer[i]; switch (c) { // Reserved characters case '<': case '>': case ':': case '"': case '/': case '\\': case '|': case '$': case '*': return false; default: if (c <= 31) return false; } } string upperBuffer = vmime::utility::stringUtils::toUpper(buffer); // Check for reserved names if (upperBuffer.length() == 3) { if (upperBuffer == "CON" || buffer == "PRN" || buffer == "AUX" || buffer == "NUL") return false; } else if (upperBuffer.length() == 4) { if ((upperBuffer.substr(0, 3) == "COM") && // COM0 to COM9 (upperBuffer[3] >= '0') && (upperBuffer[3] <= '9')) { return false; } else if ((upperBuffer.substr(0, 3) == "LPT") && // LPT0 to LPT9 (upperBuffer[3] >= '0') && (upperBuffer[3] <= '9')) { return false; } } return true;}bool windowsFileSystemFactory::isValidPath(const vmime::utility::file::path& path) const{ for (int i = 0 ; i < path.getSize() ; ++i) { if (!isValidPathComponent(path[i], (i==0))) 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);}bool windowsFile::isFile() const{ DWORD dwFileAttribute = GetFileAttributes(m_nativePath.c_str()); if (dwFileAttribute == INVALID_FILE_ATTRIBUTES) return false; return (dwFileAttribute & FILE_ATTRIBUTE_DIRECTORY) == 0;}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;}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;}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;}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;}ref <vmime::utility::file> windowsFile::getParent() const{ if (m_path.isEmpty()) return NULL; else return vmime::create <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());}ref <vmime::utility::fileWriter> windowsFile::getFileWriter(){ return vmime::create <windowsFileWriter>(m_path, m_nativePath);}ref <vmime::utility::fileReader> windowsFile::getFileReader(){ return vmime::create <windowsFileReader>(m_path, m_nativePath);}ref <vmime::utility::fileIterator> windowsFile::getFiles() const{ return vmime::create <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);}bool windowsFileIterator::hasMoreElements() const{ return m_moreElements;}ref <vmime::utility::file> windowsFileIterator::nextElement(){ ref <vmime::utility::file> pFile = vmime::create <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){}ref <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 vmime::create <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);}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){}ref <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 vmime::create <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());}void windowsFileWriterOutputStream::flush(){ // TODO}} // windows} // platforms} // vmime#endif // VMIME_HAVE_FILESYSTEM_FEATURES
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -