Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / modules / filesystem / DirectoryReader.cpp
index 338d108..f3d524b 100644 (file)
 #include "modules/filesystem/Entry.h"
 #include "modules/filesystem/ErrorCallback.h"
 
-namespace WebCore {
+namespace blink {
 
-DirectoryReader::DirectoryReader(PassRefPtr<DOMFileSystemBase> fileSystem, const String& fullPath)
+class DirectoryReader::EntriesCallbackHelper final : public EntriesCallback {
+public:
+    explicit EntriesCallbackHelper(DirectoryReader* reader)
+        : m_reader(reader)
+    {
+    }
+
+    virtual void handleEvent(const EntryHeapVector& entries) override
+    {
+        m_reader->addEntries(entries);
+    }
+
+    virtual void trace(Visitor* visitor) override
+    {
+        visitor->trace(m_reader);
+        EntriesCallback::trace(visitor);
+    }
+
+private:
+    // FIXME: This Member keeps the reader alive until all of the readDirectory results are received. crbug.com/350285
+    Member<DirectoryReader> m_reader;
+};
+
+class DirectoryReader::ErrorCallbackHelper final : public ErrorCallback {
+public:
+    explicit ErrorCallbackHelper(DirectoryReader* reader)
+        : m_reader(reader)
+    {
+    }
+
+    virtual void handleEvent(FileError* error) override
+    {
+        m_reader->onError(error);
+    }
+
+    virtual void trace(Visitor* visitor) override
+    {
+        visitor->trace(m_reader);
+        ErrorCallback::trace(visitor);
+    }
+
+private:
+    Member<DirectoryReader> m_reader;
+};
+
+DirectoryReader::DirectoryReader(DOMFileSystemBase* fileSystem, const String& fullPath)
     : DirectoryReaderBase(fileSystem, fullPath)
+    , m_isReading(false)
 {
-    ScriptWrappable::init(this);
 }
 
-void DirectoryReader::readEntries(PassOwnPtr<EntriesCallback> entriesCallback, PassOwnPtr<ErrorCallback> errorCallback)
+DirectoryReader::~DirectoryReader()
 {
-    if (!m_hasMoreEntries) {
-        filesystem()->scheduleCallback(entriesCallback, EntryVector());
+}
+
+void DirectoryReader::readEntries(EntriesCallback* entriesCallback, ErrorCallback* errorCallback)
+{
+    if (!m_isReading) {
+        m_isReading = true;
+        filesystem()->readDirectory(this, m_fullPath, new EntriesCallbackHelper(this), new ErrorCallbackHelper(this));
+    }
+
+    if (m_error) {
+        filesystem()->scheduleCallback(errorCallback, m_error);
         return;
     }
-    filesystem()->readDirectory(this, m_fullPath, entriesCallback, errorCallback);
+
+    if (m_entriesCallback) {
+        // Non-null m_entriesCallback means multiple readEntries() calls are made concurrently. We don't allow doing it.
+        filesystem()->scheduleCallback(errorCallback, FileError::create(FileError::INVALID_STATE_ERR));
+        return;
+    }
+
+    if (!m_hasMoreEntries || !m_entries.isEmpty()) {
+        filesystem()->scheduleCallback(entriesCallback, m_entries);
+        m_entries.clear();
+        return;
+    }
+
+    m_entriesCallback = entriesCallback;
+    m_errorCallback = errorCallback;
+}
+
+void DirectoryReader::addEntries(const EntryHeapVector& entries)
+{
+    m_entries.appendVector(entries);
+    m_errorCallback = nullptr;
+    if (m_entriesCallback) {
+        EntriesCallback* entriesCallback = m_entriesCallback.release();
+        EntryHeapVector entries;
+        entries.swap(m_entries);
+        entriesCallback->handleEvent(entries);
+    }
+}
+
+void DirectoryReader::onError(FileError* error)
+{
+    m_error = error;
+    m_entriesCallback = nullptr;
+    if (m_errorCallback) {
+        ErrorCallback* errorCallback = m_errorCallback.release();
+        errorCallback->handleEvent(error);
+    }
+}
+
+void DirectoryReader::trace(Visitor* visitor)
+{
+    visitor->trace(m_entries);
+    visitor->trace(m_error);
+    visitor->trace(m_entriesCallback);
+    visitor->trace(m_errorCallback);
+    DirectoryReaderBase::trace(visitor);
 }
 
 }