/* * Copyright (c) Schrodinger, LLC. * * Basic file IO. */ #ifdef _WIN32 #include #include #endif #include #include #include "File.h" #include "FileStream.h" #include "MemoryDebug.h" #include #include #include "pymol/zstring_view.h" /** * Get the size from the current file pointer to the end of the file */ static long fgetsize(FILE *fp) { long filesize, current = ftell(fp); fseek(fp, 0, SEEK_END); filesize = ftell(fp); fseek(fp, current, SEEK_SET); return filesize; } /** * Allocate memory and read the entire file from the given file pointer. * The file size is stored into the size pointer if not nullptr. */ static char * fgetcontents(FILE *fp, long *size) { long filesize = fgetsize(fp); char *contents = pymol::malloc(filesize + 255); if (!contents) return nullptr; if (1 != fread(contents, filesize, 1, fp)) { mfree(contents); return nullptr; } if (size) *size = filesize; contents[filesize] = '\0'; return contents; } #ifdef _WIN32 FILE * pymol_fopen(const char * filename, const char * mode) { FILE *fp = fopen(filename, mode); if (!fp) { size_t len_filename = strlen(filename); std::vector wfilename(len_filename + 1); std::vector wmode(mode, mode + strlen(mode) + 1); if (!MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, filename, len_filename, wfilename.data(), wfilename.size())) return nullptr; fp = _wfopen(wfilename.data(), wmode.data()); } return fp; } #endif /** * Allocate memory and read the entire file for the given filename. * The file size is stored into the size pointer if not nullptr. */ char * FileGetContents(const char *filename, long *size) { char *contents; FILE *fp = pymol_fopen(filename, "rb"); if (!fp) return nullptr; contents = fgetcontents(fp, size); fclose(fp); return contents; } namespace pymol { #ifdef _WIN32 std::wstring utf8_to_utf16(pymol::zstring_view utf8) { std::wstring utf16(utf8.size(), L'\0'); auto n = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, utf8.c_str(), -1, &utf16[0], utf16.size() + 1); if (n == 0) { throw std::runtime_error("Could not convert to UTF-16"); } utf16.resize(n - 1); return utf16; } #endif static long istream_get_size(std::istream& file) { auto current = file.tellg(); file.seekg(0, std::ios::end); auto filesize = file.tellg(); file.seekg(current); return filesize; } static std::string istream_get_contents(std::istream& file) { auto filesize = istream_get_size(file); std::string contents(filesize, '\0'); file.read(&contents[0], filesize); return contents; } std::string file_get_contents(pymol::zstring_view filename) { std::ifstream file; fstream_open(file, filename, std::ios::in | std::ios::binary); return istream_get_contents(file); } } // namespace pymol