mirror of https://github.com/vitalif/phantomjs
commit
d40fb8e637
|
@ -37,11 +37,16 @@
|
||||||
|
|
||||||
// File
|
// File
|
||||||
// public:
|
// public:
|
||||||
File::File(QFile *openfile, QObject *parent) :
|
File::File(QFile *openfile, QTextCodec *codec, QObject *parent) :
|
||||||
QObject(parent),
|
QObject(parent),
|
||||||
m_file(openfile)
|
m_file(openfile)
|
||||||
{
|
{
|
||||||
m_fileStream.setDevice(m_file);
|
m_fileStream.setDevice(m_file);
|
||||||
|
if ((QTextCodec *)NULL == codec) {
|
||||||
|
m_fileStream.setCodec(QTextCodec::codecForName("UTF-8"));
|
||||||
|
} else {
|
||||||
|
m_fileStream.setCodec(codec);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
File::~File()
|
File::~File()
|
||||||
|
@ -273,12 +278,40 @@ QString FileSystem::absolute(const QString &relativePath) const
|
||||||
return QFileInfo(relativePath).absoluteFilePath();
|
return QFileInfo(relativePath).absoluteFilePath();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline QString getCharset(const QVariant &val) {
|
||||||
|
QVariant::Type type = val.type();
|
||||||
|
|
||||||
|
// val must be either a string or null/undefined.
|
||||||
|
if (QVariant::String != type && QVariant::Invalid != type) {
|
||||||
|
qDebug() << "FileSystem::open - " << "Charset must be a string!";
|
||||||
|
return QString();
|
||||||
|
}
|
||||||
|
|
||||||
|
QString charset = val.toString();
|
||||||
|
|
||||||
|
// Default to UTF-8
|
||||||
|
if (charset.isEmpty()) {
|
||||||
|
charset = "UTF-8";
|
||||||
|
}
|
||||||
|
|
||||||
|
return charset;
|
||||||
|
}
|
||||||
|
|
||||||
// Files
|
// Files
|
||||||
QObject *FileSystem::_open(const QString &path, const QString &mode) const
|
QObject *FileSystem::_open(const QString &path, const QVariantMap &opts) const
|
||||||
{
|
{
|
||||||
File *f = NULL;
|
File *f = NULL;
|
||||||
QFile *_f = new QFile(path);
|
QFile *_f = new QFile(path);
|
||||||
QFile::OpenMode modeCode = QFile::NotOpen;
|
QFile::OpenMode modeCode = QFile::NotOpen;
|
||||||
|
QVariant modeVar = opts["mode"];
|
||||||
|
|
||||||
|
// Ensure only strings
|
||||||
|
if (modeVar.type() != QVariant::String) {
|
||||||
|
qDebug() << "FileSystem::open - " << "Mode must be a string!" << modeVar;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString mode = modeVar.toString();
|
||||||
|
|
||||||
// Ensure only one "mode character" has been selected
|
// Ensure only one "mode character" has been selected
|
||||||
if ( mode.length() != 1) {
|
if ( mode.length() != 1) {
|
||||||
|
@ -316,9 +349,16 @@ QObject *FileSystem::_open(const QString &path, const QString &mode) const
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString charset = getCharset(opts["charset"]);
|
||||||
|
QTextCodec *codec = QTextCodec::codecForName(charset.toAscii());
|
||||||
|
if ((QTextCodec *)NULL == codec) {
|
||||||
|
qDebug() << "FileSystem::open - " << "Unknown charset:" << charset;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
// Try to Open
|
// Try to Open
|
||||||
if ( _f->open(modeCode) ) {
|
if ( _f->open(modeCode) ) {
|
||||||
f = new File(_f);
|
f = new File(_f, codec);
|
||||||
if ( f ) {
|
if ( f ) {
|
||||||
return f;
|
return f;
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,6 +33,7 @@
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QStringList>
|
#include <QStringList>
|
||||||
#include <QFile>
|
#include <QFile>
|
||||||
|
#include <QTextCodec>
|
||||||
#include <QTextStream>
|
#include <QTextStream>
|
||||||
#include <QVariant>
|
#include <QVariant>
|
||||||
|
|
||||||
|
@ -41,7 +42,7 @@ class File : public QObject
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
File(QFile *openfile, QObject *parent = 0);
|
File(QFile *openfile, QTextCodec *codec, QObject *parent = 0);
|
||||||
virtual ~File();
|
virtual ~File();
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
|
@ -87,10 +88,10 @@ public slots:
|
||||||
bool _removeTree(const QString &path) const;
|
bool _removeTree(const QString &path) const;
|
||||||
|
|
||||||
// Files
|
// Files
|
||||||
// 'open(path, mode)' implemented in "filesystem-shim.js" using '_open(path, mode)'
|
// 'open(path, mode|options)' implemented in "filesystem-shim.js" using '_open(path, opts)'
|
||||||
QObject *_open(const QString &path, const QString &mode) const;
|
QObject *_open(const QString &path, const QVariantMap &opts) const;
|
||||||
// 'read(path)' implemented in "filesystem-shim.js"
|
// 'read(path, options)' implemented in "filesystem-shim.js"
|
||||||
// 'write(path, mode)' implemented in the "filesystem-shim.js"
|
// 'write(path, mode|options)' implemented in the "filesystem-shim.js"
|
||||||
// 'remove(path)' implemented in "filesystem-shim.js" using '_remove(path)'
|
// 'remove(path)' implemented in "filesystem-shim.js" using '_remove(path)'
|
||||||
bool _remove(const QString &path) const;
|
bool _remove(const QString &path) const;
|
||||||
// 'copy(source, destination)' implemented in "filesystem-shim.js" using '_copy(source, destination)'
|
// 'copy(source, destination)' implemented in "filesystem-shim.js" using '_copy(source, destination)'
|
||||||
|
|
|
@ -36,11 +36,30 @@
|
||||||
* It will throw exception if it fails.
|
* It will throw exception if it fails.
|
||||||
*
|
*
|
||||||
* @param path Path of the file to open
|
* @param path Path of the file to open
|
||||||
* @param mode Open Mode. A string made of 'r', 'w', 'a/+' characters.
|
* @param modeOrOpts
|
||||||
|
* mode: Open Mode. A string made of 'r', 'w', 'a/+' characters.
|
||||||
|
* opts: Options.
|
||||||
|
* - mode (see Open Mode above)
|
||||||
|
* - charset An IANA, case insensitive, charset name.
|
||||||
* @return "file" object
|
* @return "file" object
|
||||||
*/
|
*/
|
||||||
exports.open = function (path, mode) {
|
exports.open = function (path, modeOrOpts) {
|
||||||
var file = exports._open(path, mode);
|
var file, opts;
|
||||||
|
|
||||||
|
// Extract charset from opts
|
||||||
|
if (modeOrOpts == null) {
|
||||||
|
// Empty options
|
||||||
|
opts = {};
|
||||||
|
} else if (typeof modeOrOpts !== 'object') {
|
||||||
|
opts = {
|
||||||
|
mode: modeOrOpts
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
opts = modeOrOpts;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Open file
|
||||||
|
file = exports._open(path, opts);
|
||||||
if (file) {
|
if (file) {
|
||||||
return file;
|
return file;
|
||||||
}
|
}
|
||||||
|
@ -51,10 +70,16 @@ exports.open = function (path, mode) {
|
||||||
* It will throw an exception if it fails.
|
* It will throw an exception if it fails.
|
||||||
*
|
*
|
||||||
* @param path Path of the file to read from
|
* @param path Path of the file to read from
|
||||||
|
* @param opts Options.
|
||||||
|
* - charset An IANA, case insensitive, charset name.
|
||||||
* @return file content
|
* @return file content
|
||||||
*/
|
*/
|
||||||
exports.read = function (path) {
|
exports.read = function (path, opts) {
|
||||||
var f = exports.open(path, 'r'),
|
if (opts == null || typeof opts !== 'object') {
|
||||||
|
opts = {};
|
||||||
|
}
|
||||||
|
opts.mode = 'r';
|
||||||
|
var f = exports.open(path, opts),
|
||||||
content = f.read();
|
content = f.read();
|
||||||
|
|
||||||
f.close();
|
f.close();
|
||||||
|
@ -66,10 +91,17 @@ exports.read = function (path) {
|
||||||
*
|
*
|
||||||
* @param path Path of the file to read from
|
* @param path Path of the file to read from
|
||||||
* @param content Content to write to the file
|
* @param content Content to write to the file
|
||||||
* @param mode Open Mode. A string made of 'w' or 'a / +' characters.
|
* @param modeOrOpts
|
||||||
|
* mode: Open Mode. A string made of 'r', 'w', 'a/+' characters.
|
||||||
|
* opts: Options.
|
||||||
|
* - mode (see Open Mode above)
|
||||||
|
* - charset An IANA, case insensitive, charset name.
|
||||||
*/
|
*/
|
||||||
exports.write = function (path, content, mode) {
|
exports.write = function (path, content, modeOrOpts) {
|
||||||
var f = exports.open(path, mode);
|
if (modeOrOpts == null) {
|
||||||
|
modeOrOpts = {};
|
||||||
|
}
|
||||||
|
var f = exports.open(path, modeOrOpts);
|
||||||
|
|
||||||
f.write(content);
|
f.write(content);
|
||||||
f.close();
|
f.close();
|
||||||
|
|
|
@ -3,6 +3,7 @@ describe("Basic Files API (read, write, remove, ...)", function() {
|
||||||
FILENAME_COPY = FILENAME + ".copy",
|
FILENAME_COPY = FILENAME + ".copy",
|
||||||
FILENAME_MOVED = FILENAME + ".moved",
|
FILENAME_MOVED = FILENAME + ".moved",
|
||||||
FILENAME_EMPTY = FILENAME + ".empty",
|
FILENAME_EMPTY = FILENAME + ".empty",
|
||||||
|
FILENAME_ENC = FILENAME + ".enc",
|
||||||
ABSENT = "absent-01.test";
|
ABSENT = "absent-01.test";
|
||||||
|
|
||||||
it("should be able to create and write a file", function() {
|
it("should be able to create and write a file", function() {
|
||||||
|
@ -80,4 +81,20 @@ describe("Basic Files API (read, write, remove, ...)", function() {
|
||||||
fs.copy(ABSENT, FILENAME_COPY);
|
fs.copy(ABSENT, FILENAME_COPY);
|
||||||
}).toThrow("Unable to copy file '" + ABSENT + "' at '" + FILENAME_COPY + "'");
|
}).toThrow("Unable to copy file '" + ABSENT + "' at '" + FILENAME_COPY + "'");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("should be read/write utf8 text by default", function() {
|
||||||
|
var content, output = "ÄABCÖ";
|
||||||
|
try {
|
||||||
|
var f = fs.open(FILENAME_ENC, "w");
|
||||||
|
f.write(output);
|
||||||
|
f.close();
|
||||||
|
|
||||||
|
f = fs.open(FILENAME_ENC, "r");
|
||||||
|
content = f.read();
|
||||||
|
f.close();
|
||||||
|
|
||||||
|
fs.remove(FILENAME_ENC);
|
||||||
|
} catch (e) { }
|
||||||
|
expect(content).toEqual(output);
|
||||||
|
});
|
||||||
});
|
});
|
Loading…
Reference in New Issue