You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cordova.apache.org by st...@apache.org on 2013/12/03 01:06:39 UTC

[1/4] git commit: add ubuntu platform

Updated Branches:
  refs/heads/dev bb626c6e7 -> 9a5278b0c


add ubuntu platform


Project: http://git-wip-us.apache.org/repos/asf/cordova-plugin-file/repo
Commit: http://git-wip-us.apache.org/repos/asf/cordova-plugin-file/commit/af8d7c29
Tree: http://git-wip-us.apache.org/repos/asf/cordova-plugin-file/tree/af8d7c29
Diff: http://git-wip-us.apache.org/repos/asf/cordova-plugin-file/diff/af8d7c29

Branch: refs/heads/dev
Commit: af8d7c29c6a9a11858416d39d199e8b13387d6d3
Parents: 27288cd
Author: Maxim Ermilov <ma...@canonical.com>
Authored: Sat Oct 26 02:18:11 2013 +0400
Committer: Maxim Ermilov <ma...@canonical.com>
Committed: Sat Oct 26 02:18:11 2013 +0400

----------------------------------------------------------------------
 plugin.xml               |  12 +
 src/ubuntu/file.cpp      | 776 ++++++++++++++++++++++++++++++++++++++++++
 src/ubuntu/file.h        |  74 ++++
 www/ubuntu/Entry.js      |  32 ++
 www/ubuntu/FileWriter.js | 134 ++++++++
 5 files changed, 1028 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cordova-plugin-file/blob/af8d7c29/plugin.xml
----------------------------------------------------------------------
diff --git a/plugin.xml b/plugin.xml
index 8e72e15..c08e553 100644
--- a/plugin.xml
+++ b/plugin.xml
@@ -102,6 +102,18 @@ xmlns:android="http://schemas.android.com/apk/res/android"
         <source-file src="src/android/DirectoryManager.java" target-dir="src/org/apache/cordova/file" />
     </platform>
 
+    <!-- ubuntu -->
+    <platform name="ubuntu">
+        <header-file src="src/ubuntu/file.h" />
+        <source-file src="src/ubuntu/file.cpp" />
+        <js-module src="www/ubuntu/Entry.js" name="Entry1">
+            <merges target="window.Entry" />
+        </js-module>
+        <js-module src="www/ubuntu/FileWriter.js" name="FileWriter1">
+            <merges target="window.FileWriter" />
+        </js-module>
+    </platform>
+
     <!-- ios -->
     <platform name="ios">
         <config-file target="config.xml" parent="/*">

http://git-wip-us.apache.org/repos/asf/cordova-plugin-file/blob/af8d7c29/src/ubuntu/file.cpp
----------------------------------------------------------------------
diff --git a/src/ubuntu/file.cpp b/src/ubuntu/file.cpp
new file mode 100644
index 0000000..cb85067
--- /dev/null
+++ b/src/ubuntu/file.cpp
@@ -0,0 +1,776 @@
+/*
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+#include "file.h"
+
+#include <QApplication>
+
+namespace {
+    class FileError {
+    public:
+        static const QString kEncodingErr;
+        static const QString kTypeMismatchErr;
+        static const QString kNotFoundErr;
+        static const QString kSecurityErr;
+        static const QString kAbortErr;
+        static const QString kNotReadableErr;
+        static const QString kNoModificationAllowedErr;
+        static const QString kInvalidStateErr;
+        static const QString kSyntaxErr;
+        static const QString kInvalidModificationErr;
+        static const QString kQuotaExceededErr;
+        static const QString kPathExistsErr;
+    };
+
+    QVariantMap file2map(const QFileInfo &fileInfo) {
+        QVariantMap res;
+
+        res.insert("name", fileInfo.fileName());
+        res.insert("fullPath", fileInfo.isDir() ? QDir::cleanPath(fileInfo.absoluteFilePath()) : fileInfo.absoluteFilePath());
+        res.insert("isDirectory", (int)fileInfo.isDir());
+        res.insert("isFile", (int)fileInfo.isFile());
+
+        return res;
+    }
+    QVariantMap dir2map(const QDir &dir) {
+        return file2map(QFileInfo(dir.absolutePath()));
+    }
+};
+
+const QString FileError::kEncodingErr("FileError.ENCODING_ERR");
+const QString FileError::kTypeMismatchErr("FileError.TYPE_MISMATCH_ERR");
+const QString FileError::kNotFoundErr("FileError.NOT_FOUND_ERR");
+const QString FileError::kSecurityErr("FileError.SECURITY_ERR");
+const QString FileError::kAbortErr("FileError.ABORT_ERR");
+const QString FileError::kNotReadableErr("FileError.NOT_READABLE_ERR");
+const QString FileError::kNoModificationAllowedErr("FileError.NO_MODIFICATION_ALLOWED_ERR");
+const QString FileError::kInvalidStateErr("FileError.INVALID_STATE_ERR");
+const QString FileError::kSyntaxErr("FileError.SYNTAX_ERR");
+const QString FileError::kInvalidModificationErr("FileError.INVALID_MODIFICATION_ERR");
+const QString FileError::kQuotaExceededErr("FileError.QUOTA_EXCEEDED_ERR");
+const QString FileError::kPathExistsErr("FileError.PATH_EXISTS_ERR");
+
+File::File(Cordova *cordova) :
+    CPlugin(cordova),
+    _persistentDir(QDir::homePath() + "/.local/share/cordova-ubuntu/persistent/" + QString(cordova->get_app_dir().toUtf8().toBase64())),
+    lastRequestId(1) {
+}
+
+void File::requestFileSystem(int scId, int ecId, unsigned short type, unsigned long long size) {
+    QDir dir;
+
+    //FIXEME,what is quota value
+    if (size >= 10000){
+        this->callback(ecId, FileError::kQuotaExceededErr);
+        return;
+    }
+
+    if (type == 0) {
+        dir = QDir::temp();
+    }
+    else {
+        dir = QDir(_persistentDir);
+        QDir::root().mkpath(dir.absolutePath());
+    }
+
+    if (type > 1) {
+        this->callback(ecId, FileError::kSyntaxErr);
+        return;
+    } else {
+        QVariantMap res;
+        res.insert("root", dir2map(dir));
+        if (type == 0)
+            res.insert("name", "temporary");
+        else
+            res.insert("name", "persistent");
+
+        this->cb(scId, res);
+    }
+}
+
+void File::resolveLocalFileSystemURI(int scId, int ecId, QString uri) {
+    QUrl url = QUrl::fromUserInput(uri);
+
+    if (!url.isValid() || uri[0] == '/' || uri[0] == '.') {
+        this->callback(ecId, FileError::kEncodingErr);
+        return;
+    }
+
+    if (url.scheme() != "file") {
+        this->callback(ecId, FileError::kTypeMismatchErr);
+        return;
+    }
+
+    QFileInfo fileInfo(url.path());
+
+    if (!fileInfo.exists()) {
+        this->callback(ecId, FileError::kNotFoundErr);
+        return;
+    }
+
+    this->cb(scId, file2map(fileInfo));
+}
+
+void File::getFile(int scId, int ecId, const QString &parentPath, const QString &rpath, const QVariantMap &options) {
+    QString path(rpath);
+
+    if (rpath[0] != '/') {
+        if (!parentPath.size() || !QFileInfo(parentPath).isDir())
+            path = _persistentDir + "/" + rpath;
+        else
+            path = parentPath + "/" + rpath;
+    }
+
+    //NOTE: colon is not safe in url, it is not a valid path in Win and Mac, simple disable it here.
+    if (path.contains(":")){
+        this->callback(ecId, FileError::kEncodingErr);
+        return;
+    }
+
+    QUrl url = QUrl::fromUserInput(path);
+    if (!url.isValid()) {
+        this->callback(ecId, FileError::kEncodingErr);
+        return;
+    }
+
+    if (url.scheme() != "file") {
+        this->callback(ecId, FileError::kTypeMismatchErr);
+        return;
+    }
+
+    bool create = options.value("create").toBool();
+    bool exclusive = options.value("exclusive").toBool();
+    QFile file(path);
+
+    // if create is false and the path represents a directory, return error
+    QFileInfo fileInfo(url.path());
+    if ((!create) && fileInfo.isDir()) {
+        this->callback(ecId, FileError::kTypeMismatchErr);
+        return;
+    }
+
+    // if file does exist, and create is true and exclusive is true, return error
+    if (file.exists()) {
+        if (create && exclusive) {
+            this->callback(ecId, FileError::kPathExistsErr);
+            return;
+        }
+    }
+    else {
+        // if file does not exist and create is false, return error
+        if (!create) {
+            this->callback(ecId, FileError::kNotFoundErr);
+            return;
+        }
+
+        file.open(QIODevice::WriteOnly);
+        file.close();
+
+        // Check if creation was successfull
+        if (!file.exists()) {
+            this->callback(ecId, FileError::kNoModificationAllowedErr);
+            return;
+        }
+    }
+
+    this->cb(scId, file2map(QFileInfo(file)));
+}
+
+void File::getDirectory(int scId, int ecId, QString parentPath, QString rpath, QVariantMap options) {
+    QString path(rpath);
+    if (rpath[0] != '/') {
+        path = parentPath + "/" + rpath;
+    }
+
+    //NOTE: colon is not safe in url, it is not a valid path in Win and Mac, simple disable it here.
+    if (path.contains(":")){
+        this->callback(ecId, FileError::kEncodingErr);
+        return;
+    }
+
+    QUrl url = QUrl::fromUserInput(path);
+    if (!url.isValid()) {
+        this->callback(ecId, FileError::kEncodingErr);
+        return;
+    }
+
+    if (url.scheme() != "file") {
+        this->callback(ecId, FileError::kTypeMismatchErr);
+        return;
+    }
+
+    bool create = options.value("create").toBool();
+    bool exclusive = options.value("exclusive").toBool();
+    QDir dir(path);
+
+    //  if create is false and the path represents a file, return error
+    QFileInfo fileInfo(url.path());
+    if ((!create) && fileInfo.isFile()) {
+        this->callback(ecId, FileError::kTypeMismatchErr);
+        return;
+    }
+
+    //  if directory does exist and create is true and exclusive is true, return error
+    if (dir.exists()) {
+        if (create && exclusive) {
+            this->callback(ecId, FileError::kPathExistsErr);
+            return;
+        }
+    }
+    else {
+        //  if directory does not exist and create is false and directory does not exist, return error
+        if (!create) {
+            this->callback(ecId, FileError::kNotFoundErr);
+            return;
+        }
+
+        //  if directory does not exist and create is false and directory does not exist, return error
+        QString folderName = dir.dirName();
+        dir.cdUp();
+        dir.mkdir(folderName);
+        dir.cd(folderName);
+
+        if (!dir.exists()) {
+            this->callback(ecId, FileError::kNoModificationAllowedErr);
+            return;
+        }
+    }
+
+    QVariantMap res;
+    res.insert("name", dir.dirName());
+    res.insert("fullPath", dir.absolutePath());
+    this->cb(scId, res);
+}
+
+void File::removeRecursively(int scId, int ecId, QString path) {
+    QDir dir(path);
+    if (File::rmDir(dir))
+        this->cb(scId);
+    else
+        this->callback(ecId, FileError::kNoModificationAllowedErr);
+}
+
+void File::write(int scId, int ecId, const QString &path, const QString &_data, unsigned long long position, bool binary) {
+    QFile file(path);
+
+    file.open(QIODevice::WriteOnly);
+    file.close();
+
+    if (!file.exists()) {
+        this->callback(ecId, FileError::kNotFoundErr);
+        return;
+    }
+
+    QFileInfo fileInfo(file);
+    if (!file.open(QIODevice::ReadWrite)) {
+        this->callback(ecId, FileError::kNoModificationAllowedErr);
+        return;
+    }
+
+    if (!binary) {
+        QTextStream textStream(&file);
+        textStream.setCodec("UTF-8");
+        textStream.setAutoDetectUnicode(true);
+
+        if (!textStream.seek(position)) {
+            file.close();
+            fileInfo.refresh();
+
+            this->callback(ecId, FileError::kInvalidModificationErr);
+            return;
+        }
+
+        textStream << _data;
+        textStream.flush();
+    } else {
+        QByteArray data(_data.toUtf8());
+        if (!file.seek(position)) {
+            file.close();
+            fileInfo.refresh();
+
+            this->callback(ecId, FileError::kInvalidModificationErr);
+            return;
+        }
+
+        file.write(data.data(), data.length());
+    }
+
+    file.flush();
+    file.close();
+    fileInfo.refresh();
+
+    this->cb(scId, fileInfo.size() - position);
+}
+
+void File::truncate(int scId, int ecId, const QString &path, unsigned long long size) {
+    QFile file(path);
+
+    if (!file.exists()) {
+        this->callback(ecId, FileError::kNotFoundErr);
+        return;
+    }
+
+    if (!file.resize(size)) {
+        this->callback(ecId, FileError::kNoModificationAllowedErr);
+        return;
+    }
+
+    this->cb(scId, size);
+}
+
+void File::getParent(int scId, int ecId, QString path) {
+    QDir dir(path);
+
+    //can't cdup more than app's root
+    // Try to change into upper directory
+    if (path != _persistentDir){
+        if (!dir.cdUp()) {
+            this->callback(ecId, FileError::kNotFoundErr);
+            return;
+        }
+
+    }
+    this->cb(scId, dir2map(dir));
+}
+
+void File::remove(int scId, int ecId, QString path) {
+    QFileInfo fileInfo(path);
+    if (!fileInfo.exists() || (path == _persistentDir)) {
+        this->callback(ecId, FileError::kNoModificationAllowedErr);
+        return;
+    }
+
+    if (fileInfo.isDir()) {
+        QDir dir(path);
+        if (dir.rmdir(dir.absolutePath())) {
+            this->cb(scId);
+            return;
+        }
+    } else {
+        QFile file(path);
+        if (file.remove()) {
+            this->cb(scId);
+            return;
+        }
+    }
+
+    this->callback(ecId, FileError::kInvalidModificationErr);
+}
+
+void File::getFileMetadata(int scId, int ecId, const QString &path) {
+    QFileInfo fileInfo(path);
+
+    if (!fileInfo.exists()) {
+        this->callback(ecId, FileError::kNotFoundErr);
+    } else {
+        QMimeType mime = _db.mimeTypeForFile(fileInfo.fileName());
+
+        QString args = QString("{name: %1, fullPath: %2, type: %3, lastModifiedDate: new Date(%4), size: %5}")
+            .arg(CordovaInternal::format(fileInfo.fileName())).arg(CordovaInternal::format(fileInfo.absoluteFilePath()))
+            .arg(CordovaInternal::format(mime.name())).arg(fileInfo.lastModified().toMSecsSinceEpoch())
+            .arg(fileInfo.size());
+
+        this->callback(scId, args);
+    }
+}
+
+void File::getMetadata(int scId, int ecId, const QString &path) {
+    QFileInfo fileInfo(path);
+
+    if (!fileInfo.exists())
+        this->callback(ecId, FileError::kNotFoundErr);
+    else
+        this->cb(scId, fileInfo.lastModified().toMSecsSinceEpoch());
+}
+
+void File::readEntries(int scId, int ecId, QString path) {
+    QDir dir(path);
+    QString entriesList;
+
+    if (!dir.exists()) {
+        this->callback(ecId, FileError::kNotFoundErr);
+        return;
+    }
+
+    for (const QFileInfo &fileInfo: dir.entryInfoList(QDir::Dirs | QDir::Files | QDir::NoDotAndDotDot)) {
+        entriesList += CordovaInternal::format(file2map(fileInfo)) + ",";
+    }
+
+    // Remove trailing comma
+    if (entriesList.size() > 0)
+        entriesList.remove(entriesList.size()-1, 1);
+    entriesList = "new Array(" + entriesList + ")";
+
+    this->callback(scId, entriesList);
+}
+
+void File::readAsText(int scId, int ecId, const QString &path, const QString &encoding, int sliceStart, int sliceEnd) {
+    QFile file(path);
+
+    if (!file.exists()) {
+        this->callback(ecId, FileError::kNotFoundErr);
+        return;
+    }
+
+    if (!file.open(QIODevice::ReadOnly)) {
+        this->callback(ecId, FileError::kNotReadableErr);
+        return;
+    }
+
+    QByteArray content = file.readAll();
+
+    if (sliceEnd == -1)
+        sliceEnd = content.size();
+    if (sliceEnd < 0) {
+        sliceEnd++;
+        sliceEnd = std::max(0, content.size() + sliceEnd);
+    }
+    if (sliceEnd > content.size())
+        sliceEnd = content.size();
+
+    if (sliceStart < 0)
+        sliceStart = std::max(0, content.size() + sliceStart);
+    if (sliceStart > content.size())
+        sliceStart = content.size();
+
+    if (sliceStart > sliceEnd)
+        sliceEnd = sliceStart;
+
+    //FIXME: encoding
+    content = content.mid(sliceStart, sliceEnd - sliceStart);
+
+    this->cb(scId, content);
+}
+
+void File::readAsArrayBuffer(int scId, int ecId, const QString &path, int sliceStart, int sliceEnd) {
+    const QString str2array("\
+    (function strToArray(str) {                 \
+        var res = new Uint8Array(str.length);   \
+        for (var i = 0; i < str.length; i++) {  \
+            res[i] = str.charCodeAt(i);         \
+        }                                       \
+        return res;                             \
+    })(\"%1\")");
+    QFile file(path);
+
+    if (!file.exists()) {
+        this->callback(ecId, FileError::kNotFoundErr);
+        return;
+    }
+
+    if (!file.open(QIODevice::ReadOnly)) {
+        this->callback(ecId, FileError::kNotReadableErr);
+        return;
+    }
+    QString res;
+    QByteArray content = file.readAll();
+
+    if (sliceEnd == -1)
+        sliceEnd = content.size();
+    if (sliceEnd < 0) {
+        sliceEnd++;
+        sliceEnd = std::max(0, content.size() + sliceEnd);
+    }
+    if (sliceEnd > content.size())
+        sliceEnd = content.size();
+
+    if (sliceStart < 0)
+        sliceStart = std::max(0, content.size() + sliceStart);
+    if (sliceStart > content.size())
+        sliceStart = content.size();
+
+    if (sliceStart > sliceEnd)
+        sliceEnd = sliceStart;
+
+    content = content.mid(sliceStart, sliceEnd - sliceStart);
+
+    res.reserve(content.length() * 6);
+    for (uchar c: content) {
+        res += "\\x";
+        res += QString::number(c, 16).rightJustified(2, '0').toUpper();
+    }
+
+    this->callback(scId, str2array.arg(res));
+}
+
+void File::readAsBinaryString(int scId, int ecId, const QString &path, int sliceStart, int sliceEnd) {
+    QFile file(path);
+
+    if (!file.exists()) {
+        this->callback(ecId, FileError::kNotFoundErr);
+        return;
+    }
+
+    if (!file.open(QIODevice::ReadOnly)) {
+        this->callback(ecId, FileError::kNotReadableErr);
+        return;
+    }
+    QString res;
+    QByteArray content = file.readAll();
+
+    if (sliceEnd == -1)
+        sliceEnd = content.size();
+    if (sliceEnd < 0) {
+        sliceEnd++;
+        sliceEnd = std::max(0, content.size() + sliceEnd);
+    }
+    if (sliceEnd > content.size())
+        sliceEnd = content.size();
+
+    if (sliceStart < 0)
+        sliceStart = std::max(0, content.size() + sliceStart);
+    if (sliceStart > content.size())
+        sliceStart = content.size();
+
+    if (sliceStart > sliceEnd)
+        sliceEnd = sliceStart;
+
+    content = content.mid(sliceStart, sliceEnd - sliceStart);
+
+    res.reserve(content.length() * 6);
+    for (uchar c: content) {
+        res += "\\x";
+        res += QString::number(c, 16).rightJustified(2, '0').toUpper();
+    }
+    this->callback(scId, "\"" + res + "\"");
+}
+
+void File::readAsDataURL(int scId, int ecId, const QString &path, int sliceStart, int sliceEnd) {
+    QFile file(path);
+    QFileInfo fileInfo(path);
+
+    if (path.startsWith("content:")){
+        this->callback(ecId, FileError::kNotReadableErr);
+        return;
+    }
+
+    if (!file.exists()) {
+        this->callback(ecId, FileError::kNotReadableErr);
+        return;
+    }
+    // Try to open file for reading
+    if (!file.open(QIODevice::ReadOnly)) {
+        this->callback(ecId, FileError::kNotReadableErr);
+        return;
+    }
+    // Read the file content
+    QByteArray content = file.readAll();
+    QString contentType(_db.mimeTypeForFile(fileInfo.fileName()).name());
+
+    if (sliceEnd == -1)
+        sliceEnd = content.size();
+    if (sliceEnd < 0) {
+        sliceEnd++;
+        sliceEnd = std::max(0, content.size() + sliceEnd);
+    }
+    if (sliceEnd > content.size())
+        sliceEnd = content.size();
+
+    if (sliceStart < 0)
+        sliceStart = std::max(0, content.size() + sliceStart);
+    if (sliceStart > content.size())
+        sliceStart = content.size();
+
+    if (sliceStart > sliceEnd)
+        sliceEnd = sliceStart;
+
+    content = content.mid(sliceStart, sliceEnd - sliceStart);
+
+    this->cb(scId, QString("data:%1;base64,").arg(contentType) + content.toBase64());
+}
+
+bool File::rmDir(QDir dir) {
+    if (dir == _persistentDir) {//can't remove root dir
+        return false;
+    }
+    bool result = true;
+    if (dir.exists()) {
+        // Iterate over entries and remove them
+        Q_FOREACH(const QFileInfo &fileInfo, dir.entryInfoList(QDir::Dirs | QDir::Files | QDir::NoDotAndDotDot)) {
+            if (fileInfo.isDir()) {
+                result = rmDir(fileInfo.absoluteFilePath());
+            }
+            else {
+                result = QFile::remove(fileInfo.absoluteFilePath());
+            }
+
+            if (!result) {
+                return result;
+            }
+        }
+
+        // Finally remove the current dir
+        return dir.rmdir(dir.absolutePath());
+    }
+    return result;
+}
+
+bool File::copyFile(int scId, int ecId,const QString& sourceFile, const QString& destinationParentDir, const QString& newName) {
+    if (!QDir(destinationParentDir).exists()){
+        this->callback(ecId, FileError::kNotFoundErr);
+        return false;
+    }
+
+    QFileInfo fileInfo(sourceFile);
+    QString fileName = ((newName.isEmpty()) ? fileInfo.fileName() : newName);
+    QString destinationFile(destinationParentDir + "/" + fileName);
+
+    //NOTE: colon is not safe in url, it is not a valid path in Win and Mac, simple disable it here.
+    if (!QUrl::fromUserInput(destinationFile).isValid() || destinationFile.contains(":")){
+        this->callback(ecId, FileError::kEncodingErr);
+        return false;
+    }
+
+    if (QFile::copy(sourceFile, destinationFile)){
+        this->cb(scId, file2map(QFileInfo(destinationFile)));
+        return true;
+    } else {
+        this->callback(ecId, FileError::kInvalidModificationErr);
+        return false;
+    }
+}
+
+void File::copyDir(int scId, int ecId,const QString& sourceFolder, const QString& destinationParentDir, const QString& newName) {
+    QDir sourceDir(sourceFolder);
+    QString dirName = ((newName.isEmpty()) ? sourceDir.dirName() : newName);
+    QString destFolder(destinationParentDir + "/" + dirName);
+
+    if (QFileInfo(destFolder).isFile()){
+        this->callback(ecId, FileError::kInvalidModificationErr);
+        return;
+    }
+    QDir destDir(destFolder);
+
+    if ((sourceFolder == destFolder) || (sourceFolder == destinationParentDir)){
+        this->callback(ecId, FileError::kInvalidModificationErr);
+        return;
+    }
+
+    if (!destDir.exists()){
+        destDir.mkdir(destFolder);;
+    } else{
+        this->callback(ecId, FileError::kInvalidModificationErr);
+        return;
+    }
+
+    if (copyFolder(sourceFolder, destFolder)){
+        this->cb(scId, dir2map(destDir));
+        return;
+    } else {
+        this->callback(ecId, FileError::kInvalidModificationErr);
+        return;
+    }
+}
+
+void File::copyTo(int scId, int ecId, const QString& source, const QString& destinationDir, const QString& newName) {
+    if (QFileInfo(source).isDir())
+        copyDir(scId, ecId, source, destinationDir, newName);
+    else
+        copyFile(scId, ecId, source, destinationDir, newName);
+}
+
+void File::moveFile(int scId, int ecId,const QString& sourceFile, const QString& destinationParentDir, const QString& newName) {
+    QString fileName = ((newName.isEmpty()) ? QFileInfo(sourceFile).fileName() : newName);
+    QString destinationFile(destinationParentDir + "/" + fileName);
+
+    if (QFileInfo(sourceFile) == QFileInfo(destinationFile)) {
+        this->callback(ecId, FileError::kInvalidModificationErr);
+        return;
+    }
+
+    if (!QFileInfo(destinationParentDir).exists()) {
+        this->callback(ecId, FileError::kNotFoundErr);
+        return;
+    }
+
+    if (QFileInfo(destinationFile).exists()) {
+        if (!QFile::remove(QFileInfo(destinationFile).absoluteFilePath())) {
+            this->callback(ecId, FileError::kInvalidModificationErr);
+            return;
+        }
+    }
+
+    QFile::rename(sourceFile, destinationFile);
+    this->cb(scId, file2map(QFileInfo(destinationFile)));
+}
+
+void File::moveDir(int scId, int ecId,const QString& sourceDir, const QString& destinationParentDir, const QString& newName){
+    QString dirName = ((newName.isEmpty()) ? QDir(sourceDir).dirName() : newName);
+    QString destFolder(destinationParentDir + "/" + dirName);
+    QDir destDir(destFolder);
+
+    if (!QFileInfo(destinationParentDir).exists()){
+        this->callback(ecId, FileError::kNotFoundErr);
+        return;
+    }
+
+    if (QFileInfo(destFolder).isFile()){
+        this->callback(ecId, FileError::kInvalidModificationErr);
+        return;
+    }
+
+    if ((QFileInfo(sourceDir) == QFileInfo(destFolder)) || (QFileInfo(sourceDir) == QFileInfo(destinationParentDir))) {
+        this->callback(ecId, FileError::kInvalidModificationErr);
+        return;
+    }
+
+    if (destDir.exists() && !QDir(destinationParentDir).rmdir(dirName)) {
+        this->callback(ecId, FileError::kInvalidModificationErr);
+        return;
+    }
+
+    if (copyFolder(sourceDir, destFolder)) {
+        rmDir(sourceDir);
+        this->cb(scId, file2map(QFileInfo(destFolder)));
+    } else {
+        this->callback(ecId, FileError::kNoModificationAllowedErr);
+    }
+}
+
+void File::moveTo(int scId, int ecId, const QString& source, const QString& destinationDir, const QString& newName) {
+    if (newName.contains(":")) {
+        this->callback(ecId, FileError::kEncodingErr);
+        return;
+    }
+    if (QFileInfo(source).isDir())
+        moveDir(scId, ecId, source, destinationDir, newName);
+    else
+        moveFile(scId, ecId, source, destinationDir, newName);
+}
+
+bool File::copyFolder(const QString& sourceFolder, const QString& destFolder) {
+    QDir sourceDir(sourceFolder);
+    if (!sourceDir.exists())
+        return false;
+    QDir destDir(destFolder);
+    if (!destDir.exists()){
+        destDir.mkdir(destFolder);
+    }
+    QStringList files = sourceDir.entryList(QDir::Files);
+    for (int i = 0; i< files.count(); i++)
+    {
+        QString srcName = sourceFolder + "/" + files[i];
+        QString destName = destFolder + "/" + files[i];
+        QFile::copy(srcName, destName);
+    }
+    files.clear();
+    files = sourceDir.entryList(QDir::AllDirs | QDir::NoDotAndDotDot);
+    for (int i = 0; i< files.count(); i++)
+    {
+        QString srcName = sourceFolder + "/" + files[i];
+        QString destName = destFolder + "/" + files[i];
+        copyFolder(srcName, destName);
+    }
+    return true;
+}

http://git-wip-us.apache.org/repos/asf/cordova-plugin-file/blob/af8d7c29/src/ubuntu/file.h
----------------------------------------------------------------------
diff --git a/src/ubuntu/file.h b/src/ubuntu/file.h
new file mode 100644
index 0000000..f518ab3
--- /dev/null
+++ b/src/ubuntu/file.h
@@ -0,0 +1,74 @@
+/*
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+#ifndef FILEAPI_H_SDASDASDAS
+#define FILEAPI_H_SDASDASDAS
+
+#include <QNetworkReply>
+#include <QtCore>
+
+#include <cplugin.h>
+#include <cordova.h>
+
+class File: public CPlugin {
+    Q_OBJECT
+public:
+    explicit File(Cordova *cordova);
+
+    virtual const QString fullName() override {
+        return File::fullID();
+    }
+
+    virtual const QString shortName() override {
+        return "File";
+    }
+
+    static const QString fullID() {
+        return "File";
+    }
+
+public slots:
+    void requestFileSystem(int scId, int ecId, unsigned short type, unsigned long long size);
+    void resolveLocalFileSystemURI(int scId, int ecId, QString uri);
+    void getDirectory(int scId, int ecId, QString parentPath, QString path, QVariantMap options);
+    void getFile(int scId, int ecId, const QString &parentPath, const QString &rpath, const QVariantMap &options);
+    void readEntries(int scId, int ecId, QString path);
+    void getParent(int scId, int ecId, QString path);
+    void copyTo(int scId, int ecId, const QString& source, const QString& destinationDir, const QString& newName);
+    void moveTo(int scId, int ecId, const QString& source, const QString& destinationDir, const QString& newName);
+    void getFileMetadata(int scId, int ecId, const QString &path);
+    void getMetadata(int scId, int ecId, const QString &path);
+    void remove(int scId, int ecId, QString path);
+    void removeRecursively(int scId, int ecId, QString path);
+    void readAsText(int scId, int ecId, const QString &path, const QString &encoding, int sliceStart, int sliceEnd);
+    void write(int scId, int ecId, const QString &path, const QString &_data, unsigned long long position, bool binary);
+    void readAsDataURL(int scId, int ecId, const QString &path, int sliceStart, int sliceEnd);
+    void readAsArrayBuffer(int scId, int ecId, const QString &path, int sliceStart, int sliceEnd);
+    void readAsBinaryString(int scId, int ecId, const QString &path, int sliceStart, int sliceEnd);
+    void truncate(int scId, int ecId, const QString &path, unsigned long long size);
+private:
+    void moveFile(int scId, int ecId,const QString& sourceFile, const QString& destinationParentDir, const QString& newName);
+    void moveDir(int scId, int ecId,const QString& sourceFolder, const QString& destFolder, const QString& newName);
+    bool copyFile(int scId, int ecId, const QString& sourceFile, const QString& destinationParentDir, const QString& newName);
+    void copyDir(int scId, int ecId, const QString& sourceFolder, const QString& destFolder, const QString& newName);
+    bool rmDir(QDir dir);
+    bool copyFolder(const QString& sourceFolder, const QString& destFolder);
+
+    QMimeDatabase _db;
+    const QString _persistentDir;
+    QNetworkAccessManager _manager;
+    int lastRequestId;
+};
+
+#endif

http://git-wip-us.apache.org/repos/asf/cordova-plugin-file/blob/af8d7c29/www/ubuntu/Entry.js
----------------------------------------------------------------------
diff --git a/www/ubuntu/Entry.js b/www/ubuntu/Entry.js
new file mode 100644
index 0000000..bb8d43c
--- /dev/null
+++ b/www/ubuntu/Entry.js
@@ -0,0 +1,32 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+*/
+
+module.exports = {
+    toURL:function() {
+        // TODO: refactor path in a cross-platform way so we can eliminate
+        // these kinds of platform-specific hacks.
+        return "file://localhost" + this.fullPath;
+    },
+    toURI: function() {
+        console.log("DEPRECATED: Update your code to use 'toURL'");
+        return "file://localhost" + this.fullPath;
+    }
+};

http://git-wip-us.apache.org/repos/asf/cordova-plugin-file/blob/af8d7c29/www/ubuntu/FileWriter.js
----------------------------------------------------------------------
diff --git a/www/ubuntu/FileWriter.js b/www/ubuntu/FileWriter.js
new file mode 100644
index 0000000..454366d
--- /dev/null
+++ b/www/ubuntu/FileWriter.js
@@ -0,0 +1,134 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+*/
+
+var exec = require('cordova/exec'),
+    FileError = require('./FileError'),
+    ProgressEvent = require('./ProgressEvent');
+
+function write(data) {
+console.log(19);
+console.log(91);
+console.log(19);
+
+    var that=this;
+    var supportsBinary = (typeof window.Blob !== 'undefined' && typeof window.ArrayBuffer !== 'undefined');
+    var isBinary;
+
+    // Check to see if the incoming data is a blob
+    if (data instanceof File || (supportsBinary && data instanceof Blob)) {
+        var fileReader = new FileReader();
+        fileReader.onload = function() {
+            // Call this method again, with the arraybuffer as argument
+            FileWriter.prototype.write.call(that, this.result);
+        };
+        if (supportsBinary) {
+            fileReader.readAsArrayBuffer(data);
+        } else {
+            fileReader.readAsText(data);
+        }
+        return;
+    }
+
+    // Mark data type for safer transport over the binary bridge
+    isBinary = supportsBinary && (data instanceof ArrayBuffer);
+
+    // Throw an exception if we are already writing a file
+    if (this.readyState === FileWriter.WRITING) {
+        throw new FileError(FileError.INVALID_STATE_ERR);
+    }
+
+    // WRITING state
+    this.readyState = FileWriter.WRITING;
+
+    var me = this;
+
+    // If onwritestart callback
+    if (typeof me.onwritestart === "function") {
+        me.onwritestart(new ProgressEvent("writestart", {"target":me}));
+    }
+
+    if (data instanceof ArrayBuffer || data.buffer instanceof ArrayBuffer) {
+        data = new Uint8Array(data);
+	var binary = "";
+	for (var i = 0; i < data.byteLength; i++) {
+            binary += String.fromCharCode(data[i]);
+	}
+        data = binary;
+    }
+
+    // Write file
+    exec(
+        // Success callback
+        function(r) {
+            // If DONE (cancelled), then don't do anything
+            if (me.readyState === FileWriter.DONE) {
+                return;
+            }
+
+            // position always increases by bytes written because file would be extended
+            me.position += r;
+            // The length of the file is now where we are done writing.
+
+            me.length = me.position;
+
+            // DONE state
+            me.readyState = FileWriter.DONE;
+
+            // If onwrite callback
+            if (typeof me.onwrite === "function") {
+                me.onwrite(new ProgressEvent("write", {"target":me}));
+            }
+
+            // If onwriteend callback
+            if (typeof me.onwriteend === "function") {
+                me.onwriteend(new ProgressEvent("writeend", {"target":me}));
+            }
+        },
+        // Error callback
+        function(e) {
+            // If DONE (cancelled), then don't do anything
+            if (me.readyState === FileWriter.DONE) {
+                return;
+            }
+
+            // DONE state
+            me.readyState = FileWriter.DONE;
+
+            // Save error
+            me.error = new FileError(e);
+
+            // If onerror callback
+            if (typeof me.onerror === "function") {
+                me.onerror(new ProgressEvent("error", {"target":me}));
+            }
+
+            // If onwriteend callback
+            if (typeof me.onwriteend === "function") {
+                me.onwriteend(new ProgressEvent("writeend", {"target":me}));
+            }
+        }, "File", "write", [this.fileName, data, this.position, isBinary]);
+};
+
+module.exports = {
+    write: write
+};
+
+require("cordova/commandProxy").add("FileWriter", module.exports);


[2/4] git commit: [ubuntu] change location of persistent dir

Posted by st...@apache.org.
[ubuntu] change location of persistent dir


Project: http://git-wip-us.apache.org/repos/asf/cordova-plugin-file/repo
Commit: http://git-wip-us.apache.org/repos/asf/cordova-plugin-file/commit/ab9de01d
Tree: http://git-wip-us.apache.org/repos/asf/cordova-plugin-file/tree/ab9de01d
Diff: http://git-wip-us.apache.org/repos/asf/cordova-plugin-file/diff/ab9de01d

Branch: refs/heads/dev
Commit: ab9de01de2765392dc397e9d7a5ce1c6a983ca56
Parents: af8d7c2
Author: Maxim Ermilov <ma...@canonical.com>
Authored: Mon Nov 11 18:21:36 2013 +0400
Committer: Maxim Ermilov <ma...@canonical.com>
Committed: Mon Nov 11 18:21:36 2013 +0400

----------------------------------------------------------------------
 src/ubuntu/file.cpp      | 11 ++++-------
 src/ubuntu/file.h        |  1 -
 www/ubuntu/FileWriter.js |  4 ----
 3 files changed, 4 insertions(+), 12 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cordova-plugin-file/blob/ab9de01d/src/ubuntu/file.cpp
----------------------------------------------------------------------
diff --git a/src/ubuntu/file.cpp b/src/ubuntu/file.cpp
index cb85067..4c751e2 100644
--- a/src/ubuntu/file.cpp
+++ b/src/ubuntu/file.cpp
@@ -63,8 +63,8 @@ const QString FileError::kPathExistsErr("FileError.PATH_EXISTS_ERR");
 
 File::File(Cordova *cordova) :
     CPlugin(cordova),
-    _persistentDir(QDir::homePath() + "/.local/share/cordova-ubuntu/persistent/" + QString(cordova->get_app_dir().toUtf8().toBase64())),
-    lastRequestId(1) {
+    _persistentDir(QString("%1/.local/share/%2/persistent").arg(QDir::homePath()).arg(QCoreApplication::applicationName())) {
+    QDir::root().mkpath(QDir(_persistentDir).absolutePath());
 }
 
 void File::requestFileSystem(int scId, int ecId, unsigned short type, unsigned long long size) {
@@ -76,13 +76,10 @@ void File::requestFileSystem(int scId, int ecId, unsigned short type, unsigned l
         return;
     }
 
-    if (type == 0) {
+    if (type == 0)
         dir = QDir::temp();
-    }
-    else {
+    else
         dir = QDir(_persistentDir);
-        QDir::root().mkpath(dir.absolutePath());
-    }
 
     if (type > 1) {
         this->callback(ecId, FileError::kSyntaxErr);

http://git-wip-us.apache.org/repos/asf/cordova-plugin-file/blob/ab9de01d/src/ubuntu/file.h
----------------------------------------------------------------------
diff --git a/src/ubuntu/file.h b/src/ubuntu/file.h
index f518ab3..0037ad2 100644
--- a/src/ubuntu/file.h
+++ b/src/ubuntu/file.h
@@ -68,7 +68,6 @@ private:
     QMimeDatabase _db;
     const QString _persistentDir;
     QNetworkAccessManager _manager;
-    int lastRequestId;
 };
 
 #endif

http://git-wip-us.apache.org/repos/asf/cordova-plugin-file/blob/ab9de01d/www/ubuntu/FileWriter.js
----------------------------------------------------------------------
diff --git a/www/ubuntu/FileWriter.js b/www/ubuntu/FileWriter.js
index 454366d..85cad8a 100644
--- a/www/ubuntu/FileWriter.js
+++ b/www/ubuntu/FileWriter.js
@@ -24,10 +24,6 @@ var exec = require('cordova/exec'),
     ProgressEvent = require('./ProgressEvent');
 
 function write(data) {
-console.log(19);
-console.log(91);
-console.log(19);
-
     var that=this;
     var supportsBinary = (typeof window.Blob !== 'undefined' && typeof window.ArrayBuffer !== 'undefined');
     var isBinary;


[4/4] git commit: added ubuntu support

Posted by st...@apache.org.
added ubuntu support


Project: http://git-wip-us.apache.org/repos/asf/cordova-plugin-file/repo
Commit: http://git-wip-us.apache.org/repos/asf/cordova-plugin-file/commit/9a5278b0
Tree: http://git-wip-us.apache.org/repos/asf/cordova-plugin-file/tree/9a5278b0
Diff: http://git-wip-us.apache.org/repos/asf/cordova-plugin-file/diff/9a5278b0

Branch: refs/heads/dev
Commit: 9a5278b0c7acf2258395cd14244bd0242480c287
Parents: bb626c6 5a1a7a2
Author: Steven Gill <st...@gmail.com>
Authored: Mon Dec 2 16:06:28 2013 -0800
Committer: Steven Gill <st...@gmail.com>
Committed: Mon Dec 2 16:06:28 2013 -0800

----------------------------------------------------------------------
 plugin.xml               |  13 +
 src/ubuntu/file.cpp      | 773 ++++++++++++++++++++++++++++++++++++++++++
 src/ubuntu/file.h        |  73 ++++
 www/ubuntu/Entry.js      |  32 ++
 www/ubuntu/FileWriter.js | 130 +++++++
 5 files changed, 1021 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cordova-plugin-file/blob/9a5278b0/plugin.xml
----------------------------------------------------------------------
diff --cc plugin.xml
index b1865bf,c08e553..3621c16
--- a/plugin.xml
+++ b/plugin.xml
@@@ -104,26 -102,16 +104,39 @@@ xmlns:android="http://schemas.android.c
          <source-file src="src/android/DirectoryManager.java" target-dir="src/org/apache/cordova/file" />
      </platform>
  
 +    <!-- amazon-fireos -->
 +    <platform name="amazon-fireos">
 +        <config-file target="res/xml/config.xml" parent="/*">
 +            <feature name="File" >
 +                <param name="android-package" value="org.apache.cordova.file.FileUtils"/>
 +            </feature>
 +        </config-file>
 +
 +        <config-file target="AndroidManifest.xml" parent="/*">
 +            <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
 +        </config-file>
 +
 +        <source-file src="src/android/EncodingException.java" target-dir="src/org/apache/cordova/file" />
 +        <source-file src="src/android/FileExistsException.java" target-dir="src/org/apache/cordova/file" />
 +        <source-file src="src/android/InvalidModificationException.java" target-dir="src/org/apache/cordova/file" />
 +        <source-file src="src/android/NoModificationAllowedException.java" target-dir="src/org/apache/cordova/file" />
 +        <source-file src="src/android/TypeMismatchException.java" target-dir="src/org/apache/cordova/file" />
 +        <source-file src="src/android/FileUtils.java" target-dir="src/org/apache/cordova/file" />
 +        <source-file src="src/android/FileHelper.java" target-dir="src/org/apache/cordova/file" />
 +        <source-file src="src/android/DirectoryManager.java" target-dir="src/org/apache/cordova/file" />
++
++    </platform>
++
+     <!-- ubuntu -->
+     <platform name="ubuntu">
+         <header-file src="src/ubuntu/file.h" />
+         <source-file src="src/ubuntu/file.cpp" />
+         <js-module src="www/ubuntu/Entry.js" name="Entry1">
+             <merges target="window.Entry" />
+         </js-module>
+         <js-module src="www/ubuntu/FileWriter.js" name="FileWriter1">
+             <merges target="window.FileWriter" />
+         </js-module>
      </platform>
  
      <!-- ios -->


[3/4] git commit: [ubuntu] use cordova/exec/proxy

Posted by st...@apache.org.
[ubuntu] use cordova/exec/proxy


Project: http://git-wip-us.apache.org/repos/asf/cordova-plugin-file/repo
Commit: http://git-wip-us.apache.org/repos/asf/cordova-plugin-file/commit/5a1a7a28
Tree: http://git-wip-us.apache.org/repos/asf/cordova-plugin-file/tree/5a1a7a28
Diff: http://git-wip-us.apache.org/repos/asf/cordova-plugin-file/diff/5a1a7a28

Branch: refs/heads/dev
Commit: 5a1a7a28d1818888fb905387ceef0f6d1353924f
Parents: ab9de01
Author: Maxim Ermilov <ma...@canonical.com>
Authored: Fri Nov 22 20:15:56 2013 +0400
Committer: Maxim Ermilov <ma...@canonical.com>
Committed: Fri Nov 22 20:15:56 2013 +0400

----------------------------------------------------------------------
 www/ubuntu/FileWriter.js | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cordova-plugin-file/blob/5a1a7a28/www/ubuntu/FileWriter.js
----------------------------------------------------------------------
diff --git a/www/ubuntu/FileWriter.js b/www/ubuntu/FileWriter.js
index 85cad8a..52a17fc 100644
--- a/www/ubuntu/FileWriter.js
+++ b/www/ubuntu/FileWriter.js
@@ -127,4 +127,4 @@ module.exports = {
     write: write
 };
 
-require("cordova/commandProxy").add("FileWriter", module.exports);
+require("cordova/exec/proxy").add("FileWriter", module.exports);