Skip to content

Commit 1e548d5

Browse files
authored
Merge pull request #550 from ghutchis/read-utf16
Read UTF-16 files through Qt decoding to a temporary file
2 parents b5b6c79 + 3f270fe commit 1e548d5

File tree

1 file changed

+64
-5
lines changed

1 file changed

+64
-5
lines changed

avogadro/backgroundfileformat.cpp

+64-5
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,18 @@
77

88
#include <avogadro/io/fileformat.h>
99

10+
#include <QtCore/QFile>
11+
#include <QtCore/QTemporaryDir>
12+
#include <QtCore/QTextStream>
13+
1014
namespace Avogadro {
1115

1216
BackgroundFileFormat::BackgroundFileFormat(Io::FileFormat* format,
1317
QObject* aparent)
14-
: QObject(aparent), m_format(format), m_molecule(nullptr), m_success(false)
18+
: QObject(aparent)
19+
, m_format(format)
20+
, m_molecule(nullptr)
21+
, m_success(false)
1522
{
1623
}
1724

@@ -35,8 +42,60 @@ void BackgroundFileFormat::read()
3542
m_error = tr("No file name set in BackgroundFileFormat!");
3643

3744
if (m_error.isEmpty()) {
38-
m_success = m_format->readFile(m_fileName.toLocal8Bit().data(),
39-
*m_molecule);
45+
// sometimes we hit UTF-16 files, so we need to convert them to UTF-8
46+
// first check whether the file is UTF-16
47+
QFile file(m_fileName);
48+
QTextStream in(&file);
49+
QString text;
50+
bool isUTF16 = false;
51+
if (file.open(QIODevice::ReadOnly)) {
52+
QByteArray data = file.read(2);
53+
// look for a byte-order mark
54+
if ((data.size() == 2 && data[0] == '\xff' && data[1] == '\xfe') ||
55+
(data.size() == 2 && data[0] == '\xfe' && data[1] == '\xff')) {
56+
// UTF-16, read the file and let QString handle decoding
57+
isUTF16 = true;
58+
file.close();
59+
file.open(QIODevice::ReadOnly | QIODevice::Text);
60+
#if QT_VERSION < 0x060000
61+
in.setCodec("UTF-16");
62+
#endif
63+
text = in.readAll();
64+
file.close();
65+
}
66+
}
67+
68+
if (!isUTF16)
69+
m_success =
70+
m_format->readFile(m_fileName.toLocal8Bit().data(), *m_molecule);
71+
else {
72+
// write it to a temporary file and we'll read it back in
73+
// some formats (like the generic output) need a file
74+
// not just a string bugger
75+
76+
// first, we need the *name* of the file, not the full path
77+
// because we're going to save a copy in a temp directory
78+
QTemporaryDir tempDir;
79+
QString tempFileName = tempDir.filePath(QFileInfo(m_fileName).fileName());
80+
QFile tempFile(tempFileName);
81+
if (tempFile.open(QIODevice::WriteOnly | QIODevice::Text)) {
82+
QTextStream out(&tempFile);
83+
// set it to UTF-8
84+
#if QT_VERSION > 0x060000
85+
out.setEncoding(QStringConverter::Utf8);
86+
#else
87+
out.setCodec("UTF-8");
88+
#endif
89+
out << text;
90+
out.flush();
91+
tempFile.close();
92+
m_success =
93+
m_format->readFile(tempFileName.toLocal8Bit().data(), *m_molecule);
94+
tempFile.remove();
95+
} else // try just reading the string
96+
m_success =
97+
m_format->readString(text.toLocal8Bit().data(), *m_molecule);
98+
}
4099

41100
if (!m_success)
42101
m_error = QString::fromStdString(m_format->error());
@@ -60,8 +119,8 @@ void BackgroundFileFormat::write()
60119
m_error = tr("No file name set in BackgroundFileFormat!");
61120

62121
if (m_error.isEmpty()) {
63-
m_success = m_format->writeFile(m_fileName.toLocal8Bit().data(),
64-
*m_molecule);
122+
m_success =
123+
m_format->writeFile(m_fileName.toLocal8Bit().data(), *m_molecule);
65124

66125
if (!m_success)
67126
m_error = QString::fromStdString(m_format->error());

0 commit comments

Comments
 (0)