aboutsummaryrefslogtreecommitdiff
path: root/contrib/epee/include/file_io_utils.h
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/epee/include/file_io_utils.h')
-rw-r--r--contrib/epee/include/file_io_utils.h455
1 files changed, 455 insertions, 0 deletions
diff --git a/contrib/epee/include/file_io_utils.h b/contrib/epee/include/file_io_utils.h
new file mode 100644
index 000000000..7e8521838
--- /dev/null
+++ b/contrib/epee/include/file_io_utils.h
@@ -0,0 +1,455 @@
+// Copyright (c) 2006-2013, Andrey N. Sabelnikov, www.sabelnikov.net
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// * Neither the name of the Andrey N. Sabelnikov nor the
+// names of its contributors may be used to endorse or promote products
+// derived from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER BE LIABLE FOR ANY
+// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+
+#ifndef _FILE_IO_UTILS_H_
+#define _FILE_IO_UTILS_H_
+
+
+//#include <sys/types.h>
+//#include <sys/stat.h>
+
+#include <iostream>
+#include <boost/filesystem.hpp>
+
+
+#ifndef MAKE64
+ #define MAKE64(low,high) ((__int64)(((DWORD)(low)) | ((__int64)((DWORD)(high))) << 32))
+#endif
+
+#ifdef WINDOWS_PLATFORM
+#include <psapi.h>
+#include <strsafe.h>
+#include <string.h>
+#include <mbstring.h>
+
+#endif
+
+
+
+namespace epee
+{
+namespace file_io_utils
+{
+#ifdef WINDOWS_PLATFORM
+
+ inline
+ std::string get_temp_file_name_a()
+ {
+ std::string str_result;
+ char sz_temp[MAX_PATH*2] = {0};
+ if(!::GetTempPathA( sizeof( sz_temp ), sz_temp ))
+ return str_result;
+
+ char sz_temp_file[MAX_PATH*2] = {0};
+ if(!::GetTempFileNameA( sz_temp, "mail", 0, sz_temp_file))
+ return str_result;
+ sz_temp_file[sizeof(sz_temp_file)-1] = 0; //be happy!
+ str_result = sz_temp_file;
+ return str_result;
+ }
+
+
+#ifdef BOOST_LEXICAL_CAST_INCLUDED
+ inline
+ bool get_not_used_filename(const std::string& folder, OUT std::string& result_name)
+ {
+ DWORD folder_attr = ::GetFileAttributesA(folder.c_str());
+ if(folder_attr == INVALID_FILE_ATTRIBUTES)
+ return false;
+ if(!(folder_attr&FILE_ATTRIBUTE_DIRECTORY))
+ return false;
+
+
+ std::string base_name = folder + "\\tmp";
+ std::string tmp_name;
+ bool name_found = false;
+ int current_index = 0;
+ tmp_name = base_name + boost::lexical_cast<std::string>(current_index) + ".tmp";
+ while(!name_found)
+ {
+ if(INVALID_FILE_ATTRIBUTES == ::GetFileAttributesA(tmp_name.c_str()))
+ name_found = true;
+ else
+ {
+ current_index++;
+ tmp_name = base_name + boost::lexical_cast<std::string>(current_index) + ".tmp";
+ }
+ }
+ result_name = tmp_name;
+ return true;
+ }
+#endif
+
+ inline
+ std::string get_temp_folder_a()
+ {
+ std::string str_result;
+ char sz_temp[MAX_PATH*2] = {0};
+ if(!::GetTempPathA( sizeof( sz_temp ), sz_temp ))
+ return str_result;
+ sz_temp[(sizeof(sz_temp)/sizeof(sz_temp[0])) -1] = 0;
+ str_result = sz_temp;
+ return str_result;
+ }
+
+ std::string convert_from_device_path_to_standart(const std::string& path)
+ {
+
+
+ STRSAFE_LPSTR pszFilename = (STRSAFE_LPSTR)path.c_str();
+
+ // Translate path with device name to drive letters.
+ char szTemp[4000] = {0};
+
+ if (::GetLogicalDriveStringsA(sizeof(szTemp)-1, szTemp))
+ {
+ char szName[MAX_PATH];
+ char szDrive[3] = " :";
+ BOOL bFound = FALSE;
+ char* p = szTemp;
+
+ do
+ {
+ // Copy the drive letter to the template string
+ *szDrive = *p;
+
+ // Look up each device name
+ if (::QueryDosDeviceA(szDrive, szName, sizeof(szName)))
+ {
+ UINT uNameLen = strlen(szName);
+
+ if (uNameLen < MAX_PATH)
+ {
+ bFound = _mbsnbicmp((const unsigned char*)pszFilename, (const unsigned char*)szName,
+ uNameLen) == 0;
+
+ if (bFound)
+ {
+ // Reconstruct pszFilename using szTempFile
+ // Replace device path with DOS path
+ char szTempFile[MAX_PATH] = {0};
+ StringCchPrintfA(szTempFile,
+ MAX_PATH,
+ "%s%s",
+ szDrive,
+ pszFilename+uNameLen);
+ return szTempFile;
+ //::StringCchCopyNA(pszFilename, MAX_PATH+1, szTempFile, strlen(szTempFile));
+ }
+ }
+ }
+
+ // Go to the next NULL character.
+ while (*p++);
+ } while (!bFound && *p); // end of string
+ }
+
+ return "";
+ }
+
+ inline
+ std::string get_process_path_by_pid(DWORD pid)
+ {
+ std::string res;
+
+ HANDLE hprocess = 0;
+ if( hprocess = ::OpenProcess( PROCESS_QUERY_INFORMATION|PROCESS_VM_READ, FALSE, pid) )
+ {
+ char buff[MAX_PATH]= {0};
+ if(!::GetModuleFileNameExA( hprocess, 0, buff, MAX_PATH - 1 ))
+ res = "Unknown_b";
+ else
+ {
+ buff[MAX_PATH - 1]=0; //be happy!
+ res = buff;
+ std::string::size_type a = res.rfind( '\\' );
+ if ( a != std::string::npos )
+ res.erase( 0, a+1);
+
+ }
+ ::CloseHandle( hprocess );
+ }else
+ res = "Unknown_a";
+
+ return res;
+ }
+
+
+
+
+
+ inline
+ std::wstring get_temp_file_name_w()
+ {
+ std::wstring str_result;
+ wchar_t sz_temp[MAX_PATH*2] = {0};
+ if(!::GetTempPathW( sizeof(sz_temp)/sizeof(sz_temp[0]), sz_temp ))
+ return str_result;
+
+ wchar_t sz_temp_file[MAX_PATH+1] = {0};
+ if(!::GetTempFileNameW( sz_temp, L"mail", 0, sz_temp_file))
+ return str_result;
+
+ sz_temp_file[(sizeof(sz_temp_file)/sizeof(sz_temp_file[0]))-1] = 0; //be happy!
+ str_result = sz_temp_file;
+ return str_result;
+ }
+#endif
+ inline
+ bool is_file_exist(const std::string& path)
+ {
+ boost::filesystem::path p(path);
+ return boost::filesystem::exists(p);
+ }
+
+ /*
+ inline
+ bool save_string_to_handle(HANDLE hfile, const std::string& str)
+ {
+
+
+
+ if( INVALID_HANDLE_VALUE != hfile )
+ {
+ DWORD dw;
+ if( !::WriteFile( hfile, str.data(), (DWORD) str.size(), &dw, NULL) )
+ {
+ int err_code = GetLastError();
+ //LOG_PRINT("Failed to write to file handle: " << hfile<< " Last error code:" << err_code << " : " << log_space::get_win32_err_descr(err_code), LOG_LEVEL_2);
+ return false;
+ }
+ ::CloseHandle(hfile);
+ return true;
+ }else
+ {
+ //LOG_WIN32_ERROR(::GetLastError());
+ return false;
+ }
+
+ return false;
+ }*/
+
+
+
+ inline
+ bool save_string_to_file(const std::string& path_to_file, const std::string& str)
+ {
+
+ try
+ {
+ std::ofstream fstream;
+ fstream.exceptions(std::ifstream::failbit | std::ifstream::badbit);
+ fstream.open(path_to_file, std::ios_base::binary | std::ios_base::out | std::ios_base::trunc);
+ fstream << str;
+ fstream.close();
+ return true;
+ }
+
+ catch(...)
+ {
+ return false;
+ }
+ }
+
+ /*
+ inline
+ bool load_form_handle(HANDLE hfile, std::string& str)
+ {
+ if( INVALID_HANDLE_VALUE != hfile )
+ {
+ bool res = true;
+ DWORD dw = 0;
+ DWORD fsize = ::GetFileSize(hfile, &dw);
+ if(fsize > 300000000)
+ {
+ ::CloseHandle(hfile);
+ return false;
+ }
+ if(fsize)
+ {
+ str.resize(fsize);
+ if(!::ReadFile( hfile, (LPVOID)str.data(), (DWORD)str.size(), &dw, NULL))
+ res = false;
+ }
+ ::CloseHandle(hfile);
+ return res;
+ }
+ return false;
+ }
+ */
+ inline
+ bool get_file_time(const std::string& path_to_file, OUT time_t& ft)
+ {
+ boost::system::error_code ec;
+ ft = boost::filesystem::last_write_time(boost::filesystem::path(path_to_file), ec);
+ if(!ec)
+ return true;
+ else
+ return false;
+ }
+
+ inline
+ bool set_file_time(const std::string& path_to_file, const time_t& ft)
+ {
+ boost::system::error_code ec;
+ boost::filesystem::last_write_time(boost::filesystem::path(path_to_file), ft, ec);
+ if(!ec)
+ return true;
+ else
+ return false;
+ }
+
+
+ inline
+ bool load_file_to_string(const std::string& path_to_file, std::string& target_str)
+ {
+ try
+ {
+ std::ifstream fstream;
+ fstream.exceptions(std::ifstream::failbit | std::ifstream::badbit);
+ fstream.open(path_to_file, std::ios_base::binary | std::ios_base::in | std::ios::ate);
+
+ std::ifstream::pos_type file_size = fstream.tellg();
+
+ if(file_size > 1000000000)
+ return false;//don't go crazy
+ size_t file_size_t = static_cast<size_t>(file_size);
+
+ target_str.resize(file_size_t);
+
+ fstream.seekg (0, std::ios::beg);
+ fstream.read((char*)target_str.data(), target_str.size());
+ fstream.close();
+ return true;
+ }
+
+ catch(...)
+ {
+ return false;
+ }
+ }
+
+ inline
+ bool append_string_to_file(const std::string& path_to_file, const std::string& str)
+ {
+ try
+ {
+ std::ofstream fstream;
+ fstream.exceptions(std::ifstream::failbit | std::ifstream::badbit);
+ fstream.open(path_to_file.c_str(), std::ios_base::binary | std::ios_base::out | std::ios_base::app);
+ fstream << str;
+ fstream.close();
+ return true;
+ }
+
+ catch(...)
+ {
+ return false;
+ }
+ }
+
+ /*
+ bool remove_dir_and_subirs(const char* path_to_dir);
+
+ inline
+ bool clean_dir(const char* path_to_dir)
+ {
+ if(!path_to_dir)
+ return false;
+
+ std::string folder = path_to_dir;
+ WIN32_FIND_DATAA find_data = {0};
+ HANDLE hfind = ::FindFirstFileA((folder + "\\*.*").c_str(), &find_data);
+ if(INVALID_HANDLE_VALUE == hfind)
+ return false;
+ do{
+ if(!strcmp("..", find_data.cFileName) || (!strcmp(".", find_data.cFileName)))
+ continue;
+
+ if(find_data.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY)
+ {
+ if(!remove_dir_and_subirs((folder + "\\" + find_data.cFileName).c_str()))
+ return false;
+ }else
+ {
+ if(!::DeleteFileA((folder + "\\" + find_data.cFileName).c_str()))
+ return false;
+ }
+
+
+ }while(::FindNextFileA(hfind, &find_data));
+ ::FindClose(hfind);
+
+ return true;
+ }
+ */
+#ifdef WINDOWS_PLATFORM
+ inline bool get_folder_content(const std::string& path, std::list<WIN32_FIND_DATAA>& OUT target_list)
+ {
+ WIN32_FIND_DATAA find_data = {0};
+ HANDLE hfind = ::FindFirstFileA((path + "\\*.*").c_str(), &find_data);
+ if(INVALID_HANDLE_VALUE == hfind)
+ return false;
+ do{
+ if(!strcmp("..", find_data.cFileName) || (!strcmp(".", find_data.cFileName)))
+ continue;
+
+ target_list.push_back(find_data);
+
+ }while(::FindNextFileA(hfind, &find_data));
+ ::FindClose(hfind);
+
+ return true;
+ }
+#endif
+ inline bool get_folder_content(const std::string& path, std::list<std::string>& OUT target_list, bool only_files = false)
+ {
+ try
+ {
+
+ boost::filesystem::directory_iterator end_itr; // default construction yields past-the-end
+ for ( boost::filesystem::directory_iterator itr( path ); itr != end_itr; ++itr )
+ {
+ if ( only_files && boost::filesystem::is_directory(itr->status()) )
+ {
+ continue;
+ }
+ target_list.push_back(itr->path().filename().string());
+ }
+
+ }
+
+ catch(...)
+ {
+ return false;
+ }
+ return true;
+ }
+}
+}
+
+#endif //_FILE_IO_UTILS_H_