-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathFile.cpp
137 lines (110 loc) · 2.85 KB
/
File.cpp
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