Text file reader and writer classes now have special cases for Win32, for properly handling Unicode filenames.
Originally committed to SVN as r533.
This commit is contained in:
parent
2af4a0c5c8
commit
f7abf13dd5
4 changed files with 105 additions and 4 deletions
|
@ -80,6 +80,30 @@ wxString TextFileReader::GetEncoding(const wxString _filename) {
|
||||||
for (int i=0;i<4;i++) b[i] = 0;
|
for (int i=0;i<4;i++) b[i] = 0;
|
||||||
|
|
||||||
// Read four bytes from file
|
// Read four bytes from file
|
||||||
|
#ifdef WIN32
|
||||||
|
// TODO: maybe make this use posix-style fopen() api's instead as well?
|
||||||
|
HANDLE ifile = CreateFile(
|
||||||
|
_filename.c_str(), // filename
|
||||||
|
FILE_READ_DATA, // access mode
|
||||||
|
FILE_SHARE_READ, // share mode
|
||||||
|
0, // security descriptor
|
||||||
|
OPEN_EXISTING, // creation disposition
|
||||||
|
FILE_FLAG_SEQUENTIAL_SCAN, // flags
|
||||||
|
0); // template file
|
||||||
|
if (ifile == INVALID_HANDLE_VALUE) {
|
||||||
|
return _T("unknown");
|
||||||
|
}
|
||||||
|
DWORD numread;
|
||||||
|
if (!ReadFile(ifile, (char*)b, 4, &numread, 0)) {
|
||||||
|
// Unable to open
|
||||||
|
return _T("unknown");
|
||||||
|
}
|
||||||
|
if (numread < 4) {
|
||||||
|
// File too short to decide, assume local
|
||||||
|
return _T("Local");
|
||||||
|
}
|
||||||
|
CloseHandle(ifile);
|
||||||
|
#else
|
||||||
ifstream ifile;
|
ifstream ifile;
|
||||||
ifile.open(_filename.mb_str(wxConvLocal));
|
ifile.open(_filename.mb_str(wxConvLocal));
|
||||||
if (!ifile.is_open()) {
|
if (!ifile.is_open()) {
|
||||||
|
@ -87,6 +111,7 @@ wxString TextFileReader::GetEncoding(const wxString _filename) {
|
||||||
}
|
}
|
||||||
ifile.read((char*)b,4);
|
ifile.read((char*)b,4);
|
||||||
ifile.close();
|
ifile.close();
|
||||||
|
#endif
|
||||||
|
|
||||||
// Try to get the byte order mark from them
|
// Try to get the byte order mark from them
|
||||||
if (b[0] == 0xEF && b[1] == 0xBB && b[2] == 0xBF) return _T("UTF-8");
|
if (b[0] == 0xEF && b[1] == 0xBB && b[2] == 0xBF) return _T("UTF-8");
|
||||||
|
@ -151,9 +176,15 @@ wxString TextFileReader::ReadLineFromFile() {
|
||||||
char aux;
|
char aux;
|
||||||
wchar_t ch = 0;
|
wchar_t ch = 0;
|
||||||
int n = 0;
|
int n = 0;
|
||||||
|
#ifdef WIN32
|
||||||
|
while (ch != L'\n' && !feof(file)) {
|
||||||
|
// Read two chars from file
|
||||||
|
fread(charbuffer, 2, 1, file);
|
||||||
|
#else
|
||||||
while (ch != L'\n' && !file.eof()) {
|
while (ch != L'\n' && !file.eof()) {
|
||||||
// Read two chars from file
|
// Read two chars from file
|
||||||
file.read(charbuffer,2);
|
file.read(charbuffer,2);
|
||||||
|
#endif
|
||||||
|
|
||||||
// Swap bytes for big endian
|
// Swap bytes for big endian
|
||||||
if (swap) {
|
if (swap) {
|
||||||
|
@ -171,10 +202,31 @@ wxString TextFileReader::ReadLineFromFile() {
|
||||||
|
|
||||||
// Read ASCII/UTF-8 line from file
|
// Read ASCII/UTF-8 line from file
|
||||||
else {
|
else {
|
||||||
|
#ifdef WIN32
|
||||||
|
char *buffer = new char[512];
|
||||||
|
while (1) {
|
||||||
|
buffer[511] = '\1';
|
||||||
|
if (fgets(buffer, 512, file)) {
|
||||||
|
// read succeeded
|
||||||
|
wxString linepart(buffer, *conv);
|
||||||
|
wxbuffer += linepart;
|
||||||
|
if (buffer[511] == '\1') {
|
||||||
|
// our sentinel \1 wasn't overwritten, meaning an EOL was found
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// otherwise the sentinel \1 was overwritten (presumably with \0), so just loop on
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// hit EOF
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
std::string buffer;
|
std::string buffer;
|
||||||
getline(file,buffer);
|
getline(file,buffer);
|
||||||
wxString lineresult(buffer.c_str(),*conv);
|
wxString lineresult(buffer.c_str(),*conv);
|
||||||
wxbuffer = lineresult;
|
wxbuffer = lineresult;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove line breaks
|
// Remove line breaks
|
||||||
|
@ -202,10 +254,18 @@ wxString TextFileReader::ReadLineFromFile() {
|
||||||
// Open file
|
// Open file
|
||||||
void TextFileReader::Open() {
|
void TextFileReader::Open() {
|
||||||
if (open) return;
|
if (open) return;
|
||||||
|
#ifdef WIN32
|
||||||
|
// binary mode, because ascii mode is never to be trusted
|
||||||
|
file = _tfopen(filename.c_str(), _T("rb"));
|
||||||
|
if (file == 0) {
|
||||||
|
throw _T("Failed opening file for reading.");
|
||||||
|
}
|
||||||
|
#else
|
||||||
file.open(filename.mb_str(wxConvLocal),std::ios::in | std::ios::binary);
|
file.open(filename.mb_str(wxConvLocal),std::ios::in | std::ios::binary);
|
||||||
if (!file.is_open()) {
|
if (!file.is_open()) {
|
||||||
throw _T("Failed opening file.");
|
throw _T("Failed opening file for reading.");
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
open = true;
|
open = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -214,7 +274,11 @@ void TextFileReader::Open() {
|
||||||
// Close file
|
// Close file
|
||||||
void TextFileReader::Close() {
|
void TextFileReader::Close() {
|
||||||
if (!open) return;
|
if (!open) return;
|
||||||
|
#ifdef WIN32
|
||||||
|
fclose(file);
|
||||||
|
#else
|
||||||
file.close();
|
file.close();
|
||||||
|
#endif
|
||||||
open = false;
|
open = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -222,7 +286,11 @@ void TextFileReader::Close() {
|
||||||
//////////////////////////////////
|
//////////////////////////////////
|
||||||
// Checks if there's more to read
|
// Checks if there's more to read
|
||||||
bool TextFileReader::HasMoreLines() {
|
bool TextFileReader::HasMoreLines() {
|
||||||
|
#ifdef WIN32
|
||||||
|
return !feof(file);
|
||||||
|
#else
|
||||||
return (!file.eof());
|
return (!file.eof());
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -43,6 +43,9 @@
|
||||||
#include <wx/wxprec.h>
|
#include <wx/wxprec.h>
|
||||||
#include <wx/dynarray.h>
|
#include <wx/dynarray.h>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
#ifdef WIN32
|
||||||
|
#include <stdio.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/////////
|
/////////
|
||||||
|
@ -51,7 +54,11 @@ class TextFileReader {
|
||||||
private:
|
private:
|
||||||
wxString filename;
|
wxString filename;
|
||||||
wxString encoding;
|
wxString encoding;
|
||||||
|
#ifdef WIN32
|
||||||
|
FILE *file;
|
||||||
|
#else
|
||||||
std::ifstream file;
|
std::ifstream file;
|
||||||
|
#endif
|
||||||
wxMBConv *conv;
|
wxMBConv *conv;
|
||||||
bool Is16;
|
bool Is16;
|
||||||
bool swap;
|
bool swap;
|
||||||
|
|
|
@ -78,10 +78,17 @@ TextFileWriter::~TextFileWriter() {
|
||||||
void TextFileWriter::Open() {
|
void TextFileWriter::Open() {
|
||||||
// Open file
|
// Open file
|
||||||
if (open) return;
|
if (open) return;
|
||||||
|
#ifdef WIN32
|
||||||
|
file = _tfopen(filename.c_str(), _T("wb"));
|
||||||
|
if (!file) {
|
||||||
|
throw _T("Failed opening file for writing.");
|
||||||
|
}
|
||||||
|
#else
|
||||||
file.open(filename.mb_str(wxConvLocal),std::ios::out | std::ios::binary | std::ios::trunc);
|
file.open(filename.mb_str(wxConvLocal),std::ios::out | std::ios::binary | std::ios::trunc);
|
||||||
if (!file.is_open()) {
|
if (!file.is_open()) {
|
||||||
throw _T("Failed opening file.");
|
throw _T("Failed opening file for writing.");
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
open = true;
|
open = true;
|
||||||
|
|
||||||
// Set encoding
|
// Set encoding
|
||||||
|
@ -93,7 +100,11 @@ void TextFileWriter::Open() {
|
||||||
// Close file
|
// Close file
|
||||||
void TextFileWriter::Close() {
|
void TextFileWriter::Close() {
|
||||||
if (!open) return;
|
if (!open) return;
|
||||||
|
#ifdef WIN32
|
||||||
|
fclose(file);
|
||||||
|
#else
|
||||||
file.close();
|
file.close();
|
||||||
|
#endif
|
||||||
open = false;
|
open = false;
|
||||||
if (customConv) delete conv;
|
if (customConv) delete conv;
|
||||||
}
|
}
|
||||||
|
@ -121,8 +132,12 @@ void TextFileWriter::WriteLineToFile(wxString line,bool addLineBreak) {
|
||||||
wxWCharBuffer buf = temp.wc_str(*conv);
|
wxWCharBuffer buf = temp.wc_str(*conv);
|
||||||
if (!buf.data())
|
if (!buf.data())
|
||||||
return;
|
return;
|
||||||
size_t len = wcslen(buf.data())*2;
|
size_t len = wcslen(buf.data());
|
||||||
file.write((const char*)buf.data(),len);
|
#ifdef WIN32
|
||||||
|
fwrite(buf.data(), sizeof(wchar_t), len, file);
|
||||||
|
#else
|
||||||
|
file.write((const char*)buf.data(),len*sizeof(wchar_t));
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// 8-bit
|
// 8-bit
|
||||||
|
@ -131,7 +146,11 @@ void TextFileWriter::WriteLineToFile(wxString line,bool addLineBreak) {
|
||||||
if (!buf.data())
|
if (!buf.data())
|
||||||
return;
|
return;
|
||||||
size_t len = strlen(buf.data());
|
size_t len = strlen(buf.data());
|
||||||
|
#ifdef WIN32
|
||||||
|
fwrite(buf.data(), 1, len, file);
|
||||||
|
#else
|
||||||
file.write(buf.data(),len);
|
file.write(buf.data(),len);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -41,6 +41,9 @@
|
||||||
///////////
|
///////////
|
||||||
// Headers
|
// Headers
|
||||||
#include <wx/wxprec.h>
|
#include <wx/wxprec.h>
|
||||||
|
#ifdef WIN32
|
||||||
|
#include <stdio.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/////////
|
/////////
|
||||||
|
@ -49,7 +52,11 @@ class TextFileWriter {
|
||||||
private:
|
private:
|
||||||
wxString filename;
|
wxString filename;
|
||||||
wxString encoding;
|
wxString encoding;
|
||||||
|
#ifdef WIN32
|
||||||
|
FILE *file;
|
||||||
|
#else
|
||||||
std::ofstream file;
|
std::ofstream file;
|
||||||
|
#endif
|
||||||
wxMBConv *conv;
|
wxMBConv *conv;
|
||||||
bool customConv;
|
bool customConv;
|
||||||
bool open;
|
bool open;
|
||||||
|
|
Loading…
Reference in a new issue