Teach `File` how to change its encoding

If a `File` is in "text" mode, then it has an encoding.  This
encoding defaults to UTF-8; however, it can be set only at time of
construction (by using `fs.open`).

This modification allows the user to change the encoding on-the-fly
for "text" mode `File` instances.

See #11234 https://github.com/ariya/phantomjs/pull/11234
Spin off from #11168 https://github.com/ariya/phantomjs/pull/11168
1.x
execjosh 2013-03-26 21:22:53 +09:00 committed by Ariya Hidayat
parent 3d874d9e0d
commit b159144a48
3 changed files with 114 additions and 0 deletions

View File

@ -216,6 +216,49 @@ void File::close()
deleteLater();
}
bool File::setEncoding(const QString &encoding) {
if (encoding.isEmpty() || encoding.isNull()) {
return false;
}
// "Binary" mode doesn't use/need text codecs
if ((QTextStream *)NULL == m_fileStream) {
// TODO: Should we switch to "text" mode?
return false;
}
// Since there can be multiple names for the same codec (i.e., "utf8" and
// "utf-8"), we need to get the codec in the system first and use its
// canonical name
QTextCodec *codec = QTextCodec::codecForName(encoding.toAscii());
if ((QTextCodec *)NULL == codec) {
return false;
}
// Check whether encoding actually needs to be changed
const QString encodingBeforeUpdate(m_fileStream->codec()->name());
if (0 == encodingBeforeUpdate.compare(QString(codec->name()), Qt::CaseInsensitive)) {
return false;
}
m_fileStream->setCodec(codec);
// Return whether update was successful
const QString encodingAfterUpdate(m_fileStream->codec()->name());
return 0 != encodingBeforeUpdate.compare(encodingAfterUpdate, Qt::CaseInsensitive);
}
QString File::getEncoding() const
{
QString encoding;
if ((QTextStream *)NULL != m_fileStream) {
encoding = QString(m_fileStream->codec()->name());
}
return encoding;
}
// private:
bool File::_isUnbuffered() const

View File

@ -64,6 +64,9 @@ public slots:
void flush();
void close();
QString getEncoding() const;
bool setEncoding(const QString &encoding);
private:
bool _isUnbuffered() const;

View File

@ -59,6 +59,74 @@ describe("Basic Files API (read, write, remove, ...)", function() {
expect(content).toEqual("hello\nworld\nasdf\n");
});
it("should be able to get the encoding (default: UTF-8)", function() {
var encoding = "";
try {
var f = fs.open(FILENAME, "r");
encoding = f.getEncoding();
f.close();
} catch (e) {
console.log(e);
}
expect(encoding).toEqual("UTF-8");
});
it("should be able to set the encoding via options", function() {
var encoding = "";
try {
var f = fs.open(FILENAME, {
charset: "UTF-8"
, mode: "r"
});
encoding = f.getEncoding();
f.close();
} catch (e) {
console.log(e);
}
expect(encoding).toEqual("UTF-8");
try {
var f = fs.open(FILENAME, {
charset: "SJIS"
, mode: "r"
});
encoding = f.getEncoding();
f.close();
} catch (e) {
console.log(e);
}
expect(encoding).toEqual("Shift_JIS");
});
it("should be able to change the encoding", function() {
var encoding = "";
try {
var f = fs.open(FILENAME, {
charset: "UTF-8"
, mode: "r"
});
f.setEncoding("utf8");
encoding = f.getEncoding();
f.close();
} catch (e) {
console.log(e);
}
expect(encoding).toEqual("UTF-8");
try {
var f = fs.open(FILENAME, {
charset: "SJIS"
, mode: "r"
});
f.setEncoding("eucjp");
encoding = f.getEncoding();
f.close();
} catch (e) {
console.log(e);
}
expect(encoding).toEqual("EUC-JP");
});
it("should be able to copy a file", function() {
expect(fs.exists(FILENAME_COPY)).toBeFalsy();
fs.copy(FILENAME, FILENAME_COPY);