Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / core / fileapi / File.cpp
index de776d5..a7d1d80 100644 (file)
@@ -26,6 +26,8 @@
 #include "config.h"
 #include "core/fileapi/File.h"
 
+#include "bindings/core/v8/ExceptionState.h"
+#include "core/dom/ExceptionCode.h"
 #include "platform/FileMetadata.h"
 #include "platform/MIMETypeRegistry.h"
 #include "public/platform/Platform.h"
@@ -33,7 +35,7 @@
 #include "wtf/CurrentTime.h"
 #include "wtf/DateMath.h"
 
-namespace WebCore {
+namespace blink {
 
 static String getContentTypeFromFileName(const String& name, File::ContentTypeLookupPolicy policy)
 {
@@ -84,27 +86,29 @@ static PassOwnPtr<BlobData> createBlobDataForFileSystemURL(const KURL& fileSyste
     return blobData.release();
 }
 
-PassRefPtr<File> File::createWithRelativePath(const String& path, const String& relativePath)
+PassRefPtrWillBeRawPtr<File> File::createWithRelativePath(const String& path, const String& relativePath)
 {
-    RefPtr<File> file = adoptRef(new File(path, AllContentTypes));
+    RefPtrWillBeRawPtr<File> file = adoptRefWillBeNoop(new File(path, File::AllContentTypes, File::IsUserVisible));
     file->m_relativePath = relativePath;
     return file.release();
 }
 
-File::File(const String& path, ContentTypeLookupPolicy policy)
+File::File(const String& path, ContentTypeLookupPolicy policy, UserVisibility userVisibility)
     : Blob(BlobDataHandle::create(createBlobDataForFile(path, policy), -1))
     , m_hasBackingFile(true)
+    , m_userVisibility(userVisibility)
     , m_path(path)
-    , m_name(blink::Platform::current()->fileUtilities()->baseName(path))
+    , m_name(Platform::current()->fileUtilities()->baseName(path))
     , m_snapshotSize(-1)
     , m_snapshotModificationTime(invalidFileTime())
 {
     ScriptWrappable::init(this);
 }
 
-File::File(const String& path, const String& name, ContentTypeLookupPolicy policy)
+File::File(const String& path, const String& name, ContentTypeLookupPolicy policy, UserVisibility userVisibility)
     : Blob(BlobDataHandle::create(createBlobDataForFileWithName(path, name, policy), -1))
     , m_hasBackingFile(true)
+    , m_userVisibility(userVisibility)
     , m_path(path)
     , m_name(name)
     , m_snapshotSize(-1)
@@ -113,9 +117,10 @@ File::File(const String& path, const String& name, ContentTypeLookupPolicy polic
     ScriptWrappable::init(this);
 }
 
-File::File(const String& path, const String& name, const String& relativePath, bool hasSnaphotData, uint64_t size, double lastModified, PassRefPtr<BlobDataHandle> blobDataHandle)
+File::File(const String& path, const String& name, const String& relativePath, UserVisibility userVisibility, bool hasSnaphotData, uint64_t size, double lastModified, PassRefPtr<BlobDataHandle> blobDataHandle)
     : Blob(blobDataHandle)
     , m_hasBackingFile(!path.isEmpty() || !relativePath.isEmpty())
+    , m_userVisibility(userVisibility)
     , m_path(path)
     , m_name(name)
     , m_snapshotSize(hasSnaphotData ? static_cast<long long>(size) : -1)
@@ -128,6 +133,7 @@ File::File(const String& path, const String& name, const String& relativePath, b
 File::File(const String& name, double modificationTime, PassRefPtr<BlobDataHandle> blobDataHandle)
     : Blob(blobDataHandle)
     , m_hasBackingFile(false)
+    , m_userVisibility(File::IsNotUserVisible)
     , m_name(name)
     , m_snapshotSize(Blob::size())
     , m_snapshotModificationTime(modificationTime)
@@ -136,8 +142,9 @@ File::File(const String& name, double modificationTime, PassRefPtr<BlobDataHandl
 }
 
 File::File(const String& name, const FileMetadata& metadata)
-    : Blob(BlobDataHandle::create(createBlobDataForFileWithMetadata(name, metadata),  metadata.length))
+    : Blob(BlobDataHandle::create(createBlobDataForFileWithMetadata(name, metadata), metadata.length))
     , m_hasBackingFile(true)
+    , m_userVisibility(File::IsNotUserVisible)
     , m_path(metadata.platformPath)
     , m_name(name)
     , m_snapshotSize(metadata.length)
@@ -149,6 +156,8 @@ File::File(const String& name, const FileMetadata& metadata)
 File::File(const KURL& fileSystemURL, const FileMetadata& metadata)
     : Blob(BlobDataHandle::create(createBlobDataForFileSystemURL(fileSystemURL, metadata), metadata.length))
     , m_hasBackingFile(true)
+    , m_userVisibility(File::IsNotUserVisible)
+    , m_name(decodeURLEscapeSequences(fileSystemURL.lastPathComponent()))
     , m_fileSystemURL(fileSystemURL)
     , m_snapshotSize(metadata.length)
     , m_snapshotModificationTime(metadata.modificationTime)
@@ -156,18 +165,44 @@ File::File(const KURL& fileSystemURL, const FileMetadata& metadata)
     ScriptWrappable::init(this);
 }
 
-double File::lastModifiedDate() const
+double File::lastModifiedMS() const
 {
     if (hasValidSnapshotMetadata() && isValidFileTime(m_snapshotModificationTime))
         return m_snapshotModificationTime * msPerSecond;
 
     time_t modificationTime;
-    if (getFileModificationTime(m_path, modificationTime) && isValidFileTime(modificationTime))
+    if (hasBackingFile() && getFileModificationTime(m_path, modificationTime) && isValidFileTime(modificationTime))
         return modificationTime * msPerSecond;
 
     return currentTime() * msPerSecond;
 }
 
+long long File::lastModified() const
+{
+    double modifiedDate = lastModifiedMS();
+
+    // The getter should return the current time when the last modification time isn't known.
+    if (!isValidFileTime(modifiedDate))
+        modifiedDate = currentTimeMS();
+
+    // lastModified returns a number, not a Date instance,
+    // http://dev.w3.org/2006/webapi/FileAPI/#file-attrs
+    return floor(modifiedDate);
+}
+
+double File::lastModifiedDate() const
+{
+    double modifiedDate = lastModifiedMS();
+
+    // The getter should return the current time when the last modification time isn't known.
+    if (!isValidFileTime(modifiedDate))
+        modifiedDate = currentTimeMS();
+
+    // lastModifiedDate returns a Date instance,
+    // http://www.w3.org/TR/FileAPI/#dfn-lastModifiedDate
+    return modifiedDate;
+}
+
 unsigned long long File::size() const
 {
     if (hasValidSnapshotMetadata())
@@ -176,15 +211,20 @@ unsigned long long File::size() const
     // FIXME: JavaScript cannot represent sizes as large as unsigned long long, we need to
     // come up with an exception to throw if file size is not representable.
     long long size;
-    if (!getFileSize(m_path, size))
+    if (!hasBackingFile() || !getFileSize(m_path, size))
         return 0;
     return static_cast<unsigned long long>(size);
 }
 
-PassRefPtr<Blob> File::slice(long long start, long long end, const String& contentType) const
+PassRefPtrWillBeRawPtr<Blob> File::slice(long long start, long long end, const String& contentType, ExceptionState& exceptionState) const
 {
+    if (hasBeenClosed()) {
+        exceptionState.throwDOMException(InvalidStateError, "File has been closed.");
+        return nullptr;
+    }
+
     if (!m_hasBackingFile)
-        return Blob::slice(start, end, contentType);
+        return Blob::slice(start, end, contentType, exceptionState);
 
     // FIXME: This involves synchronous file operation. We need to figure out how to make it asynchronous.
     long long size;
@@ -215,7 +255,7 @@ void File::captureSnapshot(long long& snapshotSize, double& snapshotModification
     // Obtains a snapshot of the file by capturing its current size and modification time. This is used when we slice a file for the first time.
     // If we fail to retrieve the size or modification time, probably due to that the file has been deleted, 0 size is returned.
     FileMetadata metadata;
-    if (!getFileMetadata(m_path, metadata)) {
+    if (!hasBackingFile() || !getFileMetadata(m_path, metadata)) {
         snapshotSize = 0;
         snapshotModificationTime = invalidFileTime();
         return;
@@ -225,6 +265,24 @@ void File::captureSnapshot(long long& snapshotSize, double& snapshotModification
     snapshotModificationTime = metadata.modificationTime;
 }
 
+void File::close(ExecutionContext* executionContext, ExceptionState& exceptionState)
+{
+    if (hasBeenClosed()) {
+        exceptionState.throwDOMException(InvalidStateError, "Blob has been closed.");
+        return;
+    }
+
+    // Reset the File to its closed representation, an empty
+    // Blob. The name isn't cleared, as it should still be
+    // available.
+    m_hasBackingFile = false;
+    m_path = String();
+    m_fileSystemURL = KURL();
+    invalidateSnapshotMetadata();
+    m_relativePath = String();
+    Blob::close(executionContext, exceptionState);
+}
+
 void File::appendTo(BlobData& blobData) const
 {
     if (!m_hasBackingFile) {
@@ -244,4 +302,4 @@ void File::appendTo(BlobData& blobData) const
     blobData.appendFile(m_path, 0, size, modificationTime);
 }
 
-} // namespace WebCore
+} // namespace blink