SharedBuffer::createWithContentsOfFile should use map file routines
authoryouenn.fablet@crf.canon.fr <youenn.fablet@crf.canon.fr@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 14 May 2015 07:57:52 +0000 (07:57 +0000)
committeryouenn.fablet@crf.canon.fr <youenn.fablet@crf.canon.fr@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 14 May 2015 07:57:52 +0000 (07:57 +0000)
https://bugs.webkit.org/show_bug.cgi?id=144192

Reviewed by Darin Adler.

Source/WebCore:

Made use of mmap routines within SharedBuffer::createWithContentsOfFile for EFL, GTK and Mac ports.
If mapping is failing, it falls back to the previous version of SharedBuffer::createWithContentsOfFile renamed as
SharedBuffer::createFromReadingFile (using open/read method).
File content is mapped until SharedBuffer is cleared, destroyed or additional content is appended to the SharedBuffer.

A helper class, MappedFileData, is introduced to handle mapped files through calls to open/mmap/munmap/close.

Patch covered by existing layout tests and added unit tests.

* platform/FileSystem.cpp:
(WebCore::MappedFileData::MappedFileData):
(WebCore::MappedFileData::operator=):
(WebCore::MappedFileData::~MappedFileData):
* platform/FileSystem.h:
(WebCore::MappedFileData::MappedFileData):
(WebCore::MappedFileData::operator bool):
(WebCore::MappedFileData::data):
(WebCore::MappedFileData::size):
* platform/SharedBuffer.cpp:
(WebCore::SharedBuffer::SharedBuffer):
(WebCore::SharedBuffer::createWithContentsOfFile): Making use of MappedFileData before using createFromReadingFile.
(WebCore::SharedBuffer::size): Checking whether data is coming from a MappedFileData.
(WebCore::SharedBuffer::data): Ditto.
(WebCore::SharedBuffer::append): Ditto.
(WebCore::SharedBuffer::clear): Clearing MappedFileData if needed.
(WebCore::SharedBuffer::copy): Transferring mapped data to buffer if needed.
(WebCore::SharedBuffer::getSomeData):
(WebCore::SharedBuffer::maybeTransferMappedFileData):
* platform/SharedBuffer.h:
* platform/gtk/SharedBufferGtk.cpp:
(WebCore::SharedBuffer::createFromReadingFile): renamed from createWithContentsOfFile.
* platform/mac/SharedBufferMac.mm:
(WebCore::SharedBuffer::createFromReadingFile): Dito.
* platform/posix/SharedBufferPOSIX.cpp:
(WebCore::SharedBuffer::createFromReadingFile): Ditto.
* platform/win/SharedBufferWin.cpp:
(WebCore::SharedBuffer::createFromReadingFile): Ditto.

Tools:

Adding SharedBuffer and FileSystem Unit tests to Mac and GTK, not yet for EFL.

* TestWebKitAPI/PlatformGTK.cmake:
* TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
* TestWebKitAPI/Tests/WebCore/FileSystem.cpp: Added.
(TestWebKitAPI::FileSystemTest::tempFilePath):
(TestWebKitAPI::FileSystemTest::tempEmptyFilePath):
(TestWebKitAPI::TEST_F):
* TestWebKitAPI/Tests/WebCore/SharedBuffer.cpp: Added.
(TestWebKitAPI::SharedBufferTest::tempFilePath):
(TestWebKitAPI::SharedBufferTest::tempEmptyFilePath):
(TestWebKitAPI::TEST_F):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@184331 268f45cc-cd09-0410-ab3c-d52691b4dbfc

14 files changed:
Source/WebCore/ChangeLog
Source/WebCore/platform/FileSystem.cpp
Source/WebCore/platform/FileSystem.h
Source/WebCore/platform/SharedBuffer.cpp
Source/WebCore/platform/SharedBuffer.h
Source/WebCore/platform/gtk/SharedBufferGtk.cpp
Source/WebCore/platform/mac/SharedBufferMac.mm
Source/WebCore/platform/posix/SharedBufferPOSIX.cpp
Source/WebCore/platform/win/SharedBufferWin.cpp
Tools/ChangeLog
Tools/TestWebKitAPI/PlatformGTK.cmake
Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj
Tools/TestWebKitAPI/Tests/WebCore/FileSystem.cpp [new file with mode: 0644]
Tools/TestWebKitAPI/Tests/WebCore/SharedBuffer.cpp [new file with mode: 0644]

index 380cdc9..81c2b7c 100644 (file)
@@ -1,3 +1,48 @@
+2015-05-14  Youenn Fablet  <youenn.fablet@crf.canon.fr>
+
+        SharedBuffer::createWithContentsOfFile should use map file routines
+        https://bugs.webkit.org/show_bug.cgi?id=144192
+
+        Reviewed by Darin Adler.
+
+        Made use of mmap routines within SharedBuffer::createWithContentsOfFile for EFL, GTK and Mac ports.
+        If mapping is failing, it falls back to the previous version of SharedBuffer::createWithContentsOfFile renamed as
+        SharedBuffer::createFromReadingFile (using open/read method).
+        File content is mapped until SharedBuffer is cleared, destroyed or additional content is appended to the SharedBuffer.
+
+        A helper class, MappedFileData, is introduced to handle mapped files through calls to open/mmap/munmap/close.
+
+        Patch covered by existing layout tests and added unit tests.
+
+        * platform/FileSystem.cpp:
+        (WebCore::MappedFileData::MappedFileData):
+        (WebCore::MappedFileData::operator=):
+        (WebCore::MappedFileData::~MappedFileData):
+        * platform/FileSystem.h:
+        (WebCore::MappedFileData::MappedFileData):
+        (WebCore::MappedFileData::operator bool):
+        (WebCore::MappedFileData::data):
+        (WebCore::MappedFileData::size):
+        * platform/SharedBuffer.cpp:
+        (WebCore::SharedBuffer::SharedBuffer):
+        (WebCore::SharedBuffer::createWithContentsOfFile): Making use of MappedFileData before using createFromReadingFile.
+        (WebCore::SharedBuffer::size): Checking whether data is coming from a MappedFileData.
+        (WebCore::SharedBuffer::data): Ditto.
+        (WebCore::SharedBuffer::append): Ditto.
+        (WebCore::SharedBuffer::clear): Clearing MappedFileData if needed.
+        (WebCore::SharedBuffer::copy): Transferring mapped data to buffer if needed.
+        (WebCore::SharedBuffer::getSomeData):
+        (WebCore::SharedBuffer::maybeTransferMappedFileData):
+        * platform/SharedBuffer.h:
+        * platform/gtk/SharedBufferGtk.cpp:
+        (WebCore::SharedBuffer::createFromReadingFile): renamed from createWithContentsOfFile.
+        * platform/mac/SharedBufferMac.mm:
+        (WebCore::SharedBuffer::createFromReadingFile): Dito.
+        * platform/posix/SharedBufferPOSIX.cpp:
+        (WebCore::SharedBuffer::createFromReadingFile): Ditto.
+        * platform/win/SharedBufferWin.cpp:
+        (WebCore::SharedBuffer::createFromReadingFile): Ditto.
+
 2015-05-13  Simon Fraser  <simon.fraser@apple.com>
 
         Get the ScriptController from the correct frame for media elements and plug-ins
index 97b846e..946d5f3 100644 (file)
@@ -1,5 +1,6 @@
 /*
  * Copyright (C) 2007, 2011 Apple Inc. All rights reserved.
+ * Copyright (C) 2015 Canon Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 #include "FileSystem.h"
 
 #include <wtf/HexNumber.h>
+#include <wtf/text/CString.h>
 #include <wtf/text/StringBuilder.h>
 
+#if !PLATFORM(WIN)
+#include <fcntl.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#endif
+
 namespace WebCore {
 
 // The following lower-ASCII characters need escaping to be used in a filename
@@ -113,4 +122,61 @@ bool excludeFromBackup(const String&)
 
 #endif
 
+MappedFileData::~MappedFileData()
+{
+#if !PLATFORM(WIN)
+    if (!m_fileData)
+        return;
+    munmap(m_fileData, m_fileSize);
+#endif
+}
+
+MappedFileData::MappedFileData(const String& filePath, bool& success)
+{
+#if PLATFORM(WIN)
+    // FIXME: Implement mapping
+    success = false;
+#else
+    CString fsRep = fileSystemRepresentation(filePath);
+    int fd = !fsRep.isNull() ? open(fsRep.data(), O_RDONLY) : -1;
+    if (fd < 0) {
+        success = false;
+        return;
+    }
+
+    struct stat fileStat;
+    if (fstat(fd, &fileStat)) {
+        close(fd);
+        success = false;
+        return;
+    }
+
+    if (fileStat.st_size < 0 || fileStat.st_size > std::numeric_limits<unsigned>::max()) {
+        close(fd);
+        success = false;
+        return;
+    }
+
+    unsigned size = static_cast<unsigned>(fileStat.st_size);
+
+    if (!size) {
+        close(fd);
+        success = true;
+        return;
+    }
+
+    void* data = mmap(0, size, PROT_READ, MAP_FILE | MAP_SHARED, fd, 0);
+    close(fd);
+
+    if (data == MAP_FAILED) {
+        success = false;
+        return;
+    }
+
+    success = true;
+    m_fileData = data;
+    m_fileSize = size;
+#endif
+}
+
 } // namespace WebCore
index 3a7fb4b..13ab29b 100644 (file)
@@ -1,6 +1,7 @@
 /*
  * Copyright (C) 2007, 2008, 2011 Apple Inc. All rights reserved.
  * Copyright (C) 2008 Collabora, Ltd. All rights reserved.
+ * Copyright (C) 2015 Canon Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -204,6 +205,36 @@ WEBCORE_EXPORT String localUserSpecificStorageDirectory();
 String roamingUserSpecificStorageDirectory();
 #endif
 
+class MappedFileData {
+public:
+    MappedFileData() { }
+    MappedFileData(MappedFileData&&);
+    WEBCORE_EXPORT MappedFileData(const String& filePath, bool& success);
+    WEBCORE_EXPORT ~MappedFileData();
+    MappedFileData& operator=(MappedFileData&&);
+
+    explicit operator bool() const { return !!m_fileData; }
+    const void* data() const { return m_fileData; }
+    unsigned size() const { return m_fileSize; }
+
+private:
+    void* m_fileData { nullptr };
+    unsigned m_fileSize { 0 };
+};
+
+inline MappedFileData::MappedFileData(MappedFileData&& other)
+    : m_fileData(std::exchange(other.m_fileData, nullptr))
+    , m_fileSize(std::exchange(other.m_fileSize, 0))
+{
+}
+
+inline MappedFileData& MappedFileData::operator=(MappedFileData&& other)
+{
+    m_fileData = std::exchange(other.m_fileData, nullptr);
+    m_fileSize = std::exchange(other.m_fileSize, 0);
+    return *this;
+}
+
 } // namespace WebCore
 
 #endif // FileSystem_h
index 9db7fad..646e2ac 100644 (file)
@@ -1,6 +1,7 @@
 /*
  * Copyright (C) 2006, 2008 Apple Inc. All rights reserved.
  * Copyright (C) Research In Motion Limited 2009-2010. All rights reserved.
+ * Copyright (C) 2015 Canon Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -82,12 +83,29 @@ SharedBuffer::SharedBuffer(const unsigned char* data, unsigned size)
 {
     append(reinterpret_cast<const char*>(data), size);
 }
-    
+
+SharedBuffer::SharedBuffer(MappedFileData&& fileData)
+    : m_buffer(adoptRef(new DataBuffer))
+    , m_fileData(WTF::move(fileData))
+{
+}
+
 SharedBuffer::~SharedBuffer()
 {
     clear();
 }
 
+RefPtr<SharedBuffer> SharedBuffer::createWithContentsOfFile(const String& filePath)
+{
+    bool mappingSuccess;
+    MappedFileData mappedFileData(filePath, mappingSuccess);
+
+    if (!mappingSuccess)
+        return SharedBuffer::createFromReadingFile(filePath);
+
+    return adoptRef(new SharedBuffer(WTF::move(mappedFileData)));
+}
+
 PassRefPtr<SharedBuffer> SharedBuffer::adoptVector(Vector<char>& vector)
 {
     RefPtr<SharedBuffer> buffer = create();
@@ -101,15 +119,20 @@ unsigned SharedBuffer::size() const
     if (hasPlatformData())
         return platformDataSize();
     
+    if (m_fileData)
+        return m_fileData.size();
+
     return m_size;
 }
 
 const char* SharedBuffer::data() const
 {
-
     if (hasPlatformData())
         return platformData();
 
+    if (m_fileData)
+        return static_cast<const char*>(m_fileData.data());
+
 #if USE(NETWORK_CFDATA_ARRAY_CALLBACK)
     if (const char* buffer = singleDataArrayBuffer())
         return buffer;
@@ -160,6 +183,7 @@ void SharedBuffer::append(const char* data, unsigned length)
     if (!length)
         return;
 
+    maybeTransferMappedFileData();
     maybeTransferPlatformData();
 
 #if !USE(NETWORK_CFDATA_ARRAY_CALLBACK)
@@ -210,6 +234,8 @@ void SharedBuffer::append(const Vector<char>& data)
 
 void SharedBuffer::clear()
 {
+    m_fileData = { };
+
     clearPlatformData();
     
 #if !USE(NETWORK_CFDATA_ARRAY_CALLBACK)
@@ -227,7 +253,8 @@ void SharedBuffer::clear()
 PassRefPtr<SharedBuffer> SharedBuffer::copy() const
 {
     RefPtr<SharedBuffer> clone { adoptRef(*new SharedBuffer) };
-    if (hasPlatformData()) {
+
+    if (hasPlatformData() || m_fileData) {
         clone->append(data(), size());
         return clone.release();
     }
@@ -310,7 +337,7 @@ unsigned SharedBuffer::getSomeData(const char*& someData, unsigned position) con
         return 0;
     }
 
-    if (hasPlatformData()) {
+    if (hasPlatformData() || m_fileData) {
         ASSERT_WITH_SECURITY_IMPLICATION(position < size());
         someData = data() + position;
         return totalSize - position;
@@ -343,6 +370,14 @@ unsigned SharedBuffer::getSomeData(const char*& someData, unsigned position) con
 #endif
 }
 
+void SharedBuffer::maybeTransferMappedFileData()
+{
+    if (m_fileData) {
+        auto fileData = WTF::move(m_fileData);
+        append(static_cast<const char*>(fileData.data()), fileData.size());
+    }
+}
+
 #if !USE(CF) && !USE(SOUP)
 
 inline void SharedBuffer::clearPlatformData()
index 0455d79..44aa818 100644 (file)
@@ -27,6 +27,7 @@
 #ifndef SharedBuffer_h
 #define SharedBuffer_h
 
+#include "FileSystem.h"
 #include <runtime/ArrayBuffer.h>
 #include <wtf/Forward.h>
 #include <wtf/RefCounted.h>
@@ -55,7 +56,7 @@ public:
     static PassRefPtr<SharedBuffer> create(const char* c, unsigned i) { return adoptRef(new SharedBuffer(c, i)); }
     static PassRefPtr<SharedBuffer> create(const unsigned char* c, unsigned i) { return adoptRef(new SharedBuffer(c, i)); }
 
-    WEBCORE_EXPORT static PassRefPtr<SharedBuffer> createWithContentsOfFile(const String& filePath);
+    WEBCORE_EXPORT static RefPtr<SharedBuffer> createWithContentsOfFile(const String& filePath);
 
     WEBCORE_EXPORT static PassRefPtr<SharedBuffer> adoptVector(Vector<char>& vector);
     
@@ -92,7 +93,7 @@ public:
     WEBCORE_EXPORT void append(const char*, unsigned);
     void append(const Vector<char>&);
 
-    void clear();
+    WEBCORE_EXPORT void clear();
     const char* platformData() const;
     unsigned platformDataSize() const;
 
@@ -101,7 +102,7 @@ public:
     void append(CFDataRef);
 #endif
 
-    PassRefPtr<SharedBuffer> copy() const;
+    WEBCORE_EXPORT PassRefPtr<SharedBuffer> copy() const;
     
     // Return the number of consecutive bytes after "position". "data"
     // points to the first byte.
@@ -129,7 +130,10 @@ private:
     explicit SharedBuffer(unsigned);
     WEBCORE_EXPORT SharedBuffer(const char*, unsigned);
     WEBCORE_EXPORT SharedBuffer(const unsigned char*, unsigned);
-    
+    explicit SharedBuffer(MappedFileData&&);
+
+    static RefPtr<SharedBuffer> createFromReadingFile(const String& filePath);
+
     // Calling this function will force internal segmented buffers
     // to be merged into a flat buffer. Use getSomeData() whenever possible
     // for better performance.
@@ -139,6 +143,8 @@ private:
     void maybeTransferPlatformData();
     bool maybeAppendPlatformData(SharedBuffer*);
 
+    void maybeTransferMappedFileData();
+
     void copyBufferAndClear(char* destination, unsigned bytesToCopy) const;
 
     void appendToDataBuffer(const char *, unsigned) const;
@@ -167,6 +173,8 @@ private:
     explicit SharedBuffer(SoupBuffer*);
     GUniquePtr<SoupBuffer> m_soupBuffer;
 #endif
+
+    MappedFileData m_fileData;
 };
 
 PassRefPtr<SharedBuffer> utf8Buffer(const String&);
index ed8de47..9f6b6c4 100644 (file)
@@ -28,7 +28,7 @@
 
 namespace WebCore {
 
-PassRefPtr<SharedBuffer> SharedBuffer::createWithContentsOfFile(const String& filePath)
+RefPtr<SharedBuffer> SharedBuffer::createFromReadingFile(const String& filePath)
 {
     if (filePath.isEmpty())
         return 0;
index ea482f0..1ad28ad 100644 (file)
@@ -122,7 +122,7 @@ RetainPtr<CFDataRef> SharedBuffer::createCFData()
     return adoptCF((CFDataRef)adoptNS([[WebCoreSharedBufferData alloc] initWithSharedBufferDataBuffer:m_buffer.get()]).leakRef());
 }
 
-PassRefPtr<SharedBuffer> SharedBuffer::createWithContentsOfFile(const String& filePath)
+RefPtr<SharedBuffer> SharedBuffer::createFromReadingFile(const String& filePath)
 {
     NSData *resourceData = [NSData dataWithContentsOfFile:filePath];
     if (resourceData) 
index e77b8ec..863dbe2 100644 (file)
@@ -35,7 +35,7 @@
 
 namespace WebCore {
 
-PassRefPtr<SharedBuffer> SharedBuffer::createWithContentsOfFile(const String& filePath)
+RefPtr<SharedBuffer> SharedBuffer::createFromReadingFile(const String& filePath)
 {
     if (filePath.isEmpty())
         return 0;
index f5dd228..2aab3cd 100644 (file)
@@ -33,7 +33,7 @@
 
 namespace WebCore {
 
-PassRefPtr<SharedBuffer> SharedBuffer::createWithContentsOfFile(const String& filePath)
+RefPtr<SharedBuffer> SharedBuffer::createFromReadingFile(const String& filePath)
 {
     if (filePath.isEmpty())
         return 0;
index 7c39d29..d93a841 100644 (file)
@@ -1,3 +1,23 @@
+2015-05-14  Youenn Fablet  <youenn.fablet@crf.canon.fr>
+
+        SharedBuffer::createWithContentsOfFile should use map file routines
+        https://bugs.webkit.org/show_bug.cgi?id=144192
+
+        Reviewed by Darin Adler.
+
+        Adding SharedBuffer and FileSystem Unit tests to Mac and GTK, not yet for EFL.
+
+        * TestWebKitAPI/PlatformGTK.cmake:
+        * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
+        * TestWebKitAPI/Tests/WebCore/FileSystem.cpp: Added.
+        (TestWebKitAPI::FileSystemTest::tempFilePath):
+        (TestWebKitAPI::FileSystemTest::tempEmptyFilePath):
+        (TestWebKitAPI::TEST_F):
+        * TestWebKitAPI/Tests/WebCore/SharedBuffer.cpp: Added.
+        (TestWebKitAPI::SharedBufferTest::tempFilePath):
+        (TestWebKitAPI::SharedBufferTest::tempEmptyFilePath):
+        (TestWebKitAPI::TEST_F):
+
 2015-05-13  Alex Christensen  <achristensen@webkit.org>
 
         [Content Extensions] Test interactions between multiple extensions and multiple domains.
index 06b3057..cc47e08 100644 (file)
@@ -11,6 +11,7 @@ set(ForwardingHeadersForTestWebKitAPI_NAME TestWebKitAPI-forwarding-headers)
 
 include_directories(
     ${FORWARDING_HEADERS_DIR}
+    ${FORWARDING_HEADERS_DIR}/JavaScriptCore
     ${WEBKIT2_DIR}/UIProcess/API/C/soup
     ${WEBKIT2_DIR}/UIProcess/API/C/gtk
     ${WEBKIT2_DIR}/UIProcess/API/gtk
@@ -122,6 +123,8 @@ add_executable(TestWebCore
     ${TESTWEBKITAPI_DIR}/TestsController.cpp
     ${TESTWEBKITAPI_DIR}/Tests/WebCore/LayoutUnit.cpp
     ${TESTWEBKITAPI_DIR}/Tests/WebCore/URL.cpp
+    ${TESTWEBKITAPI_DIR}/Tests/WebCore/SharedBuffer.cpp
+    ${TESTWEBKITAPI_DIR}/Tests/WebCore/FileSystem.cpp
 )
 
 target_link_libraries(TestWebCore ${test_webcore_LIBRARIES})
index 1f5ac15..9a1f29e 100644 (file)
@@ -45,6 +45,8 @@
                37D36F321B004DD400BAF5D9 /* ProvisionalURLChange.mm in Sources */ = {isa = PBXBuildFile; fileRef = 37D36F311B004DD400BAF5D9 /* ProvisionalURLChange.mm */; };
                37DC6791140D7D7600ABCCDB /* DOMRangeOfString.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 37DC678F140D7D3A00ABCCDB /* DOMRangeOfString.html */; };
                37E1064C1697681800B78BD0 /* DOMHTMLTableCellElementCellAbove.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 37E1064B169767F700B78BD0 /* DOMHTMLTableCellElementCellAbove.html */; };
+               41973B5B1AF2286A006C7B36 /* FileSystem.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 41973B5A1AF2286A006C7B36 /* FileSystem.cpp */; };
+               41973B5D1AF22875006C7B36 /* SharedBuffer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 41973B5C1AF22875006C7B36 /* SharedBuffer.cpp */; };
                4BFDFFA71314776C0061F24B /* HitTestResultNodeHandle_Bundle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BFDFFA61314776C0061F24B /* HitTestResultNodeHandle_Bundle.cpp */; };
                51393E221523952D005F39C5 /* DOMWindowExtensionBasic_Bundle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 51393E1D1523944A005F39C5 /* DOMWindowExtensionBasic_Bundle.cpp */; };
                5142B2731517C8C800C32B19 /* ContextMenuCanCopyURL.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 5142B2721517C89100C32B19 /* ContextMenuCanCopyURL.html */; };
                37E1064A1697676400B78BD0 /* DOMHTMLTableCellCellAbove.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = DOMHTMLTableCellCellAbove.mm; sourceTree = "<group>"; };
                37E1064B169767F700B78BD0 /* DOMHTMLTableCellElementCellAbove.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = DOMHTMLTableCellElementCellAbove.html; sourceTree = "<group>"; };
                37E38C33169B7D010084C28C /* WebViewDidRemoveFrameFromHierarchy.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WebViewDidRemoveFrameFromHierarchy.mm; sourceTree = "<group>"; };
+               41973B5A1AF2286A006C7B36 /* FileSystem.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FileSystem.cpp; sourceTree = "<group>"; };
+               41973B5C1AF22875006C7B36 /* SharedBuffer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SharedBuffer.cpp; sourceTree = "<group>"; };
                440A1D3814A0103A008A66F2 /* URL.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = URL.cpp; sourceTree = "<group>"; };
                44A622C114A0E2B60048515B /* WTFStringUtilities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WTFStringUtilities.h; sourceTree = "<group>"; };
                4A410F4B19AF7BD6002EBAB5 /* UserMedia.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = UserMedia.cpp; sourceTree = "<group>"; };
                08FB7795FE84155DC02AAC07 /* Source */ = {
                        isa = PBXGroup;
                        children = (
+                               44A82E7B19251B3500C1C8C4 /* Cocoa */,
                                0F139E711A423A1D00F590F5 /* cocoa */,
                                BC575944126E733C006F0F12 /* InjectedBundle */,
                                2E9660DC16C07D7B00371B42 /* ios */,
                                7CB184C41AA3F2100066EDFD /* ContentExtensions.cpp */,
                                CD5451E919E41F9D0016936F /* CSSParser.cpp */,
                                26F6E1EF1ADC749B00DE696B /* DFAMinimizer.cpp */,
+                               41973B5A1AF2286A006C7B36 /* FileSystem.cpp */,
                                14464012167A8305000BD218 /* LayoutUnit.cpp */,
+                               41973B5C1AF22875006C7B36 /* SharedBuffer.cpp */,
                                CDC2C7141797089D00E627FB /* TimeRanges.cpp */,
                                440A1D3814A0103A008A66F2 /* URL.cpp */,
                        );
                        children = (
                                93A7EB3C18FA63A4009E7670 /* URLExtras.mm */,
                        );
-                       path = Cocoa;
+                       name = Cocoa;
+                       path = Tests/Cocoa;
                        sourceTree = "<group>";
                };
                7560917619259C59009EF06E /* ios */ = {
                BCB9EB66112366D800A137E0 /* Tests */ = {
                        isa = PBXGroup;
                        children = (
-                               44A82E7B19251B3500C1C8C4 /* Cocoa */,
                                7560917619259C59009EF06E /* ios */,
                                FE217ECB1640A54A0052988B /* JavaScriptCore */,
                                C07E6CAD13FD67650038B22B /* mac */,
                                2D1FE0B01AD465C1006CD9E6 /* FixedLayoutSize.mm in Sources */,
                                1CB9BC381A67482300FE5678 /* WeakPtr.cpp in Sources */,
                                2E7765CD16C4D80A00BA2BB1 /* mainIOS.mm in Sources */,
+                               41973B5D1AF22875006C7B36 /* SharedBuffer.cpp in Sources */,
                                7AA6A1521AAC0B31002B2ED3 /* WorkQueue.cpp in Sources */,
                                2E7765CF16C4D81100BA2BB1 /* mainMac.mm in Sources */,
+                               41973B5B1AF2286A006C7B36 /* FileSystem.cpp in Sources */,
                                7A5623111AD5AF3E0096B920 /* MenuTypesForMouseEvents.cpp in Sources */,
                                26F6E1F01ADC749B00DE696B /* DFAMinimizer.cpp in Sources */,
                                7A99D9941AD4A29D00373141 /* MenuTypesForMouseEvents.mm in Sources */,
diff --git a/Tools/TestWebKitAPI/Tests/WebCore/FileSystem.cpp b/Tools/TestWebKitAPI/Tests/WebCore/FileSystem.cpp
new file mode 100644 (file)
index 0000000..fb23a4b
--- /dev/null
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2015 Canon 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. AND ITS CONTRIBUTORS ``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 ITS 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.
+ */
+
+#include "config.h"
+
+#include "Test.h"
+#include <WebCore/FileSystem.h>
+#include <wtf/MainThread.h>
+#include <wtf/StringExtras.h>
+
+using namespace WebCore;
+
+namespace TestWebKitAPI {
+
+const char* FileSystemTestData = "This is a test";
+
+// FIXME: Refactor FileSystemTest and SharedBufferTest as a single class.
+class FileSystemTest : public testing::Test {
+public:
+    virtual void SetUp() override
+    {
+        WTF::initializeMainThread();
+        
+        // create temp file
+        PlatformFileHandle handle;
+        m_tempFilePath = openTemporaryFile("tempTestFile", handle);
+        writeToFile(handle, FileSystemTestData, strlen(FileSystemTestData));
+        closeFile(handle); 
+
+        m_tempEmptyFilePath = openTemporaryFile("tempEmptyTestFile", handle);
+        closeFile(handle); 
+    }
+
+    virtual void TearDown() override
+    {
+        deleteFile(m_tempFilePath);
+        deleteFile(m_tempEmptyFilePath);
+    }
+
+    const String& tempFilePath() { return m_tempFilePath; }
+    const String& tempEmptyFilePath() { return m_tempEmptyFilePath; }
+
+private:
+    String m_tempFilePath;
+    String m_tempEmptyFilePath;
+};
+
+TEST_F(FileSystemTest, MappingMissingFile)
+{
+    bool success;
+    MappedFileData mappedFileData(String("not_existing_file"), success);
+    EXPECT_FALSE(success);
+    EXPECT_TRUE(!mappedFileData);
+}
+
+TEST_F(FileSystemTest, MappingExistingFile)
+{
+    bool success;
+    MappedFileData mappedFileData(tempFilePath(), success);
+    EXPECT_TRUE(success);
+    EXPECT_TRUE(!!mappedFileData);
+    EXPECT_TRUE(mappedFileData.size() == strlen(FileSystemTestData));
+    EXPECT_TRUE(strnstr(FileSystemTestData, static_cast<const char*>(mappedFileData.data()), mappedFileData.size()));
+}
+
+TEST_F(FileSystemTest, MappingExistingEmptyFile)
+{
+    bool success;
+    MappedFileData mappedFileData(tempEmptyFilePath(), success);
+    EXPECT_TRUE(success);
+    EXPECT_TRUE(!mappedFileData);
+}
+
+}
diff --git a/Tools/TestWebKitAPI/Tests/WebCore/SharedBuffer.cpp b/Tools/TestWebKitAPI/Tests/WebCore/SharedBuffer.cpp
new file mode 100644 (file)
index 0000000..19e90b6
--- /dev/null
@@ -0,0 +1,119 @@
+/*
+ * Copyright (C) 2015 Canon 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. AND ITS CONTRIBUTORS ``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 ITS 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.
+ */
+
+#include "config.h"
+
+#include "Test.h"
+#include <WebCore/SharedBuffer.h>
+#include <wtf/MainThread.h>
+#include <wtf/StringExtras.h>
+
+using namespace WebCore;
+
+namespace TestWebKitAPI {
+
+const char* SharedBufferTestData = "This is a test";
+
+class SharedBufferTest : public testing::Test {
+public:
+    virtual void SetUp() override
+    {
+        WTF::initializeMainThread();
+        
+        // create temp file
+        PlatformFileHandle handle;
+        m_tempFilePath = openTemporaryFile("tempTestFile", handle);
+        writeToFile(handle, SharedBufferTestData, strlen(SharedBufferTestData));
+        closeFile(handle); 
+
+        m_tempEmptyFilePath = openTemporaryFile("tempEmptyTestFile", handle);
+        closeFile(handle); 
+    }
+
+    virtual void TearDown() override
+    {
+        deleteFile(m_tempFilePath);
+        deleteFile(m_tempEmptyFilePath);
+    }
+
+    const String& tempFilePath() { return m_tempFilePath; }
+    const String& tempEmptyFilePath() { return m_tempEmptyFilePath; }
+
+private:
+    String m_tempFilePath;
+    String m_tempEmptyFilePath;
+};
+
+TEST_F(SharedBufferTest, createWithContentsOfMissingFile)
+{
+    RefPtr<SharedBuffer> buffer = SharedBuffer::createWithContentsOfFile(String("not_existing_file"));
+    ASSERT_NULL(buffer);
+}
+
+TEST_F(SharedBufferTest, createWithContentsOfExistingFile)
+{
+    RefPtr<SharedBuffer> buffer = SharedBuffer::createWithContentsOfFile(tempFilePath());
+    ASSERT_NOT_NULL(buffer);
+    EXPECT_TRUE(buffer->size() == strlen(SharedBufferTestData));
+    EXPECT_TRUE(String(SharedBufferTestData) == String(buffer->data(), buffer->size()));
+}
+
+TEST_F(SharedBufferTest, createWithContentsOfExistingEmptyFile)
+{
+    RefPtr<SharedBuffer> buffer = SharedBuffer::createWithContentsOfFile(tempEmptyFilePath());
+    ASSERT_NOT_NULL(buffer);
+    EXPECT_TRUE(buffer->isEmpty());
+}
+
+TEST_F(SharedBufferTest, copyBufferCreatedWithContentsOfExistingFile)
+{
+    RefPtr<SharedBuffer> buffer = SharedBuffer::createWithContentsOfFile(tempFilePath());
+    ASSERT_NOT_NULL(buffer);
+    RefPtr<SharedBuffer> copy = buffer->copy();
+    EXPECT_TRUE(buffer->size() == copy->size());
+    EXPECT_TRUE(strnstr(buffer->data(), copy->data(), buffer->size()));
+}
+
+TEST_F(SharedBufferTest, clearBufferCreatedWithContentsOfExistingFile)
+{
+    RefPtr<SharedBuffer> buffer = SharedBuffer::createWithContentsOfFile(tempFilePath());
+    ASSERT_NOT_NULL(buffer);
+    buffer->clear();
+    EXPECT_TRUE(!buffer->size());
+    EXPECT_TRUE(!buffer->data());
+}
+
+
+TEST_F(SharedBufferTest, appendBufferCreatedWithContentsOfExistingFile)
+{
+    RefPtr<SharedBuffer> buffer = SharedBuffer::createWithContentsOfFile(tempFilePath());
+    ASSERT_NOT_NULL(buffer);
+    buffer->append("a", 1);
+    EXPECT_TRUE(buffer->size() == (strlen(SharedBufferTestData) + 1));
+    EXPECT_TRUE(strnstr(buffer->data(), SharedBufferTestData, strlen(SharedBufferTestData)));
+    EXPECT_EQ('a', buffer->data()[strlen(SharedBufferTestData)]);
+}
+
+}