blob: e9707e037d0018677160ab3088467dd5de3ffd3f [file] [log] [blame]
/*
* Copyright (C) 2008 Apple Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_FILEAPI_FILE_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_FILEAPI_FILE_H_
#include "base/memory/scoped_refptr.h"
#include "base/optional.h"
#include "base/time/time.h"
#include "third_party/blink/renderer/bindings/core/v8/array_buffer_or_array_buffer_view_or_blob_or_usv_string.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/fileapi/blob.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
#include "third_party/blink/renderer/platform/wtf/casting.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
namespace blink {
class ExceptionState;
class ExecutionContext;
class FilePropertyBag;
class FileMetadata;
class FormControlState;
class KURL;
class CORE_EXPORT File final : public Blob {
DEFINE_WRAPPERTYPEINFO();
public:
// AllContentTypes should only be used when the full path/name are trusted;
// otherwise, it could allow arbitrary pages to determine what applications an
// user has installed.
enum ContentTypeLookupPolicy {
kWellKnownContentTypes,
kAllContentTypes,
};
// The user should not be able to browse to some files, such as the ones
// generated by the Filesystem API.
enum UserVisibility { kIsUserVisible, kIsNotUserVisible };
// Constructor in File.idl
static File* Create(
ExecutionContext*,
const HeapVector<ArrayBufferOrArrayBufferViewOrBlobOrUSVString>&,
const String& file_name,
const FilePropertyBag*);
// For deserialization.
static File* CreateFromSerialization(
const String& path,
const String& name,
const String& relative_path,
UserVisibility user_visibility,
bool has_snapshot_data,
uint64_t size,
const base::Optional<base::Time>& last_modified,
scoped_refptr<BlobDataHandle> blob_data_handle) {
return MakeGarbageCollected<File>(
path, name, relative_path, user_visibility, has_snapshot_data, size,
last_modified, std::move(blob_data_handle));
}
static File* CreateFromIndexedSerialization(
const String& name,
uint64_t size,
const base::Optional<base::Time>& last_modified,
scoped_refptr<BlobDataHandle> blob_data_handle) {
return MakeGarbageCollected<File>(
String(), name, String(), kIsNotUserVisible, true, size, last_modified,
std::move(blob_data_handle));
}
// For session restore feature.
// See also AppendToControlState().
static File* CreateFromControlState(const FormControlState& state,
wtf_size_t& index);
static String PathFromControlState(const FormControlState& state,
wtf_size_t& index);
static File* CreateWithRelativePath(const String& path,
const String& relative_path);
// If filesystem files live in the remote filesystem, the port might pass the
// valid metadata (whose length field is non-negative) and cache in the File
// object.
//
// Otherwise calling size(), lastModifiedTime() and slice() will synchronously
// query the file metadata.
static File* CreateForFileSystemFile(const String& name,
const FileMetadata& metadata,
UserVisibility user_visibility) {
return MakeGarbageCollected<File>(name, metadata, user_visibility);
}
static File* CreateForFileSystemFile(const KURL& url,
const FileMetadata& metadata,
UserVisibility user_visibility) {
return MakeGarbageCollected<File>(url, metadata, user_visibility);
}
File(const String& path,
ContentTypeLookupPolicy = kWellKnownContentTypes,
UserVisibility = File::kIsUserVisible);
File(const String& path,
const String& name,
ContentTypeLookupPolicy,
UserVisibility);
File(const String& path,
const String& name,
const String& relative_path,
UserVisibility,
bool has_snapshot_data,
uint64_t size,
const base::Optional<base::Time>& last_modified,
scoped_refptr<BlobDataHandle>);
File(const String& name,
const base::Optional<base::Time>& modification_time,
scoped_refptr<BlobDataHandle>);
File(const String& name, const FileMetadata&, UserVisibility);
File(const KURL& file_system_url, const FileMetadata&, UserVisibility);
File(const File&);
KURL FileSystemURL() const {
#if DCHECK_IS_ON()
DCHECK(HasValidFileSystemURL());
#endif
return file_system_url_;
}
// Create a file with a name exposed to the author (via File.name and
// associated DOM properties) that differs from the one provided in the path.
static File* CreateForUserProvidedFile(const String& path,
const String& display_name) {
if (display_name.IsEmpty()) {
return MakeGarbageCollected<File>(path, File::kAllContentTypes,
File::kIsUserVisible);
}
return MakeGarbageCollected<File>(
path, display_name, File::kAllContentTypes, File::kIsUserVisible);
}
static File* CreateForFileSystemFile(
const String& path,
const String& name,
ContentTypeLookupPolicy policy = kWellKnownContentTypes) {
if (name.IsEmpty())
return MakeGarbageCollected<File>(path, policy, File::kIsNotUserVisible);
return MakeGarbageCollected<File>(path, name, policy,
File::kIsNotUserVisible);
}
File* Clone(const String& name = String()) const;
uint64_t size() const override;
Blob* slice(int64_t start,
int64_t end,
const String& content_type,
ExceptionState&) const override;
bool IsFile() const override { return true; }
bool HasBackingFile() const override { return has_backing_file_; }
void AppendTo(BlobData&) const override;
const String& GetPath() const {
#if DCHECK_IS_ON()
DCHECK(HasValidFilePath());
#endif
return path_;
}
const String& name() const { return name_; }
// Getter for the lastModified IDL attribute,
// http://dev.w3.org/2006/webapi/FileAPI/#file-attrs
int64_t lastModified() const;
// Getter for the lastModifiedDate IDL attribute,
// http://www.w3.org/TR/FileAPI/#dfn-lastModifiedDate
ScriptValue lastModifiedDate(ScriptState* script_state) const;
// Returns File's last modified time.
// If the modification time isn't known, the current time is returned.
base::Time LastModifiedTime() const;
// Similar to |LastModifiedTime()|, except this returns base::nullopt rather
// than the current time if the modified time is unknown.
// This is used by SerializedScriptValue to serialize the last modified time
// of a File object.
// This method calls CaptureSnapshotIfNeeded, and thus can involve synchronous
// IPC and file operations.
base::Optional<base::Time> LastModifiedTimeForSerialization() const;
UserVisibility GetUserVisibility() const { return user_visibility_; }
// Returns the relative path of this file in the context of a directory
// selection.
const String& webkitRelativePath() const { return relative_path_; }
// Returns true if this has a valid snapshot metadata
// (i.e. snapshot_size_.has_value()).
bool HasValidSnapshotMetadata() const { return snapshot_size_.has_value(); }
// Returns true if the sources (file path, file system URL, or blob handler)
// of the file objects are same or not.
bool HasSameSource(const File& other) const;
// Return false if this File instance is not serializable to FormControlState.
bool AppendToControlState(FormControlState& state);
private:
// Note that this involves synchronous file operation. Think twice before
// calling this function.
void CaptureSnapshotIfNeeded() const;
#if DCHECK_IS_ON()
// Instances backed by a file must have an empty file system URL.
bool HasValidFileSystemURL() const {
return !HasBackingFile() || file_system_url_.IsEmpty();
}
// Instances not backed by a file must have an empty path set.
bool HasValidFilePath() const { return HasBackingFile() || path_.IsEmpty(); }
#endif
bool has_backing_file_;
UserVisibility user_visibility_;
String path_;
String name_;
KURL file_system_url_;
// If snapshot_size_ has no value, the snapshot metadata is invalid and
// we retrieve the latest metadata synchronously in size(),
// LastModifiedTime() and slice().
// Otherwise, the snapshot metadata are used directly in those methods.
mutable base::Optional<uint64_t> snapshot_size_;
mutable base::Optional<base::Time> snapshot_modification_time_;
String relative_path_;
};
template <>
struct DowncastTraits<File> {
static bool AllowFrom(const Blob& blob) { return blob.IsFile(); }
};
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_CORE_FILEAPI_FILE_H_