[WTF] Move currentCPUTime and sleep(Seconds) to CPUTime.h and Seconds.h respectively
[WebKit-https.git] / Source / WebCore / fileapi / File.cpp
1 /*
2  * Copyright (C) 2008 Apple Inc. All Rights Reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #include "config.h"
27 #include "File.h"
28
29 #include "BlobURL.h"
30 #include "FileMetadata.h"
31 #include "FileSystem.h"
32 #include "MIMETypeRegistry.h"
33 #include "ThreadableBlobRegistry.h"
34 #include <wtf/DateMath.h>
35 #include <wtf/text/WTFString.h>
36
37 namespace WebCore {
38
39 Ref<File> File::createWithRelativePath(const String& path, const String& relativePath)
40 {
41     auto file = File::create(path);
42     file->setRelativePath(relativePath);
43     return file;
44 }
45
46 File::File(const String& path)
47     : Blob(uninitializedContructor)
48     , m_path(path)
49 {
50     m_internalURL = BlobURL::createInternalURL();
51     m_size = -1;
52     computeNameAndContentType(m_path, String(), m_name, m_type);
53     ThreadableBlobRegistry::registerFileBlobURL(m_internalURL, path, m_type);
54 }
55
56 File::File(const String& path, const String& nameOverride)
57     : Blob(uninitializedContructor)
58     , m_path(path)
59 {
60     m_internalURL = BlobURL::createInternalURL();
61     m_size = -1;
62     computeNameAndContentType(m_path, nameOverride, m_name, m_type);
63     ThreadableBlobRegistry::registerFileBlobURL(m_internalURL, path, m_type);
64 }
65
66 File::File(DeserializationContructor, const String& path, const URL& url, const String& type, const String& name)
67     : Blob(deserializationContructor, url, type, -1, path)
68     , m_path(path)
69     , m_name(name)
70 {
71 }
72
73 static BlobPropertyBag convertPropertyBag(const File::PropertyBag& initialBag)
74 {
75     BlobPropertyBag bag;
76     bag.type = initialBag.type;
77     return bag;
78 }
79
80 File::File(Vector<BlobPartVariant>&& blobPartVariants, const String& filename, const PropertyBag& propertyBag)
81     : Blob(WTFMove(blobPartVariants), convertPropertyBag(propertyBag))
82     , m_name(filename)
83     , m_overrideLastModifiedDate(propertyBag.lastModified.value_or(WallTime::now().secondsSinceEpoch().milliseconds()))
84 {
85 }
86
87 File::File(const Blob& blob, const String& name)
88     : Blob(referencingExistingBlobConstructor, blob)
89     , m_name(name)
90 {
91     ASSERT(!blob.isFile());
92 }
93
94 File::File(const File& file, const String& name)
95     : Blob(referencingExistingBlobConstructor, file)
96     , m_path(file.path())
97     , m_relativePath(file.relativePath())
98     , m_name(!name.isNull() ? name : file.name())
99     , m_overrideLastModifiedDate(file.m_overrideLastModifiedDate)
100     , m_isDirectory(file.isDirectory())
101 {
102 }
103
104 double File::lastModified() const
105 {
106     if (m_overrideLastModifiedDate)
107         return m_overrideLastModifiedDate.value();
108
109     double result;
110
111     // FIXME: This does sync-i/o on the main thread and also recalculates every time the method is called.
112     // The i/o should be performed on a background thread,
113     // and the result should be cached along with an asynchronous monitor for changes to the file.
114     time_t modificationTime;
115     if (FileSystem::getFileModificationTime(m_path, modificationTime) && FileSystem::isValidFileTime(modificationTime))
116         result = modificationTime * msPerSecond;
117     else
118         result = WallTime::now().secondsSinceEpoch().milliseconds();
119
120     return WTF::timeClip(result);
121 }
122
123 void File::computeNameAndContentType(const String& path, const String& nameOverride, String& effectiveName, String& effectiveContentType)
124 {
125 #if ENABLE(FILE_REPLACEMENT)
126     if (shouldReplaceFile(path)) {
127         computeNameAndContentTypeForReplacedFile(path, nameOverride, effectiveName, effectiveContentType);
128         return;
129     }
130 #endif
131     effectiveName = nameOverride.isNull() ? FileSystem::pathGetFileName(path) : nameOverride;
132     size_t index = effectiveName.reverseFind('.');
133     if (index != notFound)
134         effectiveContentType = MIMETypeRegistry::getMIMETypeForExtension(effectiveName.substring(index + 1));
135 }
136
137 String File::contentTypeForFile(const String& path)
138 {
139     String name;
140     String type;
141     computeNameAndContentType(path, String(), name, type);
142
143     return type;
144 }
145
146 bool File::isDirectory() const
147 {
148     if (!m_isDirectory)
149         m_isDirectory = FileSystem::fileIsDirectory(m_path, FileSystem::ShouldFollowSymbolicLinks::Yes);
150     return *m_isDirectory;
151 }
152
153 } // namespace WebCore