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:
Niels Martin Hansen 2006-08-28 20:00:51 +00:00
parent 2af4a0c5c8
commit f7abf13dd5
4 changed files with 105 additions and 4 deletions

View file

@ -80,6 +80,30 @@ wxString TextFileReader::GetEncoding(const wxString _filename) {
for (int i=0;i<4;i++) b[i] = 0;
// 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;
ifile.open(_filename.mb_str(wxConvLocal));
if (!ifile.is_open()) {
@ -87,6 +111,7 @@ wxString TextFileReader::GetEncoding(const wxString _filename) {
}
ifile.read((char*)b,4);
ifile.close();
#endif
// Try to get the byte order mark from them
if (b[0] == 0xEF && b[1] == 0xBB && b[2] == 0xBF) return _T("UTF-8");
@ -151,9 +176,15 @@ wxString TextFileReader::ReadLineFromFile() {
char aux;
wchar_t ch = 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()) {
// Read two chars from file
file.read(charbuffer,2);
#endif
// Swap bytes for big endian
if (swap) {
@ -171,10 +202,31 @@ wxString TextFileReader::ReadLineFromFile() {
// Read ASCII/UTF-8 line from file
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;
getline(file,buffer);
wxString lineresult(buffer.c_str(),*conv);
wxbuffer = lineresult;
#endif
}
// Remove line breaks
@ -202,10 +254,18 @@ wxString TextFileReader::ReadLineFromFile() {
// Open file
void TextFileReader::Open() {
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);
if (!file.is_open()) {
throw _T("Failed opening file.");
throw _T("Failed opening file for reading.");
}
#endif
open = true;
}
@ -214,7 +274,11 @@ void TextFileReader::Open() {
// Close file
void TextFileReader::Close() {
if (!open) return;
#ifdef WIN32
fclose(file);
#else
file.close();
#endif
open = false;
}
@ -222,7 +286,11 @@ void TextFileReader::Close() {
//////////////////////////////////
// Checks if there's more to read
bool TextFileReader::HasMoreLines() {
#ifdef WIN32
return !feof(file);
#else
return (!file.eof());
#endif
}

View file

@ -43,6 +43,9 @@
#include <wx/wxprec.h>
#include <wx/dynarray.h>
#include <fstream>
#ifdef WIN32
#include <stdio.h>
#endif
/////////
@ -51,7 +54,11 @@ class TextFileReader {
private:
wxString filename;
wxString encoding;
#ifdef WIN32
FILE *file;
#else
std::ifstream file;
#endif
wxMBConv *conv;
bool Is16;
bool swap;

View file

@ -78,10 +78,17 @@ TextFileWriter::~TextFileWriter() {
void TextFileWriter::Open() {
// Open file
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);
if (!file.is_open()) {
throw _T("Failed opening file.");
throw _T("Failed opening file for writing.");
}
#endif
open = true;
// Set encoding
@ -93,7 +100,11 @@ void TextFileWriter::Open() {
// Close file
void TextFileWriter::Close() {
if (!open) return;
#ifdef WIN32
fclose(file);
#else
file.close();
#endif
open = false;
if (customConv) delete conv;
}
@ -121,8 +132,12 @@ void TextFileWriter::WriteLineToFile(wxString line,bool addLineBreak) {
wxWCharBuffer buf = temp.wc_str(*conv);
if (!buf.data())
return;
size_t len = wcslen(buf.data())*2;
file.write((const char*)buf.data(),len);
size_t len = wcslen(buf.data());
#ifdef WIN32
fwrite(buf.data(), sizeof(wchar_t), len, file);
#else
file.write((const char*)buf.data(),len*sizeof(wchar_t));
#endif
}
// 8-bit
@ -131,7 +146,11 @@ void TextFileWriter::WriteLineToFile(wxString line,bool addLineBreak) {
if (!buf.data())
return;
size_t len = strlen(buf.data());
#ifdef WIN32
fwrite(buf.data(), 1, len, file);
#else
file.write(buf.data(),len);
#endif
}
}

View file

@ -41,6 +41,9 @@
///////////
// Headers
#include <wx/wxprec.h>
#ifdef WIN32
#include <stdio.h>
#endif
/////////
@ -49,7 +52,11 @@ class TextFileWriter {
private:
wxString filename;
wxString encoding;
#ifdef WIN32
FILE *file;
#else
std::ofstream file;
#endif
wxMBConv *conv;
bool customConv;
bool open;