1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137
|
/*
* Copyright (c) Schrodinger, LLC.
*
* Basic file IO.
*/
#ifdef _WIN32
#include <vector>
#include <Windows.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include "File.h"
#include "FileStream.h"
#include "MemoryDebug.h"
#include <fstream>
#include <string>
#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 NULL.
*/
static char * fgetcontents(FILE *fp, long *size) {
long filesize = fgetsize(fp);
char *contents = pymol::malloc<char>(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<wchar_t> wfilename(len_filename + 1);
std::vector<wchar_t> wmode(mode, mode + strlen(mode) + 1);
if (!MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS,
filename, len_filename, wfilename.data(), wfilename.size()))
return NULL;
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 NULL.
*/
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
|