1 /* 2 * Copyright (C) 2010 Google 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 are 6 * met: 7 * 8 * * Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * * Redistributions in binary form must reproduce the above 11 * copyright notice, this list of conditions and the following disclaimer 12 * in the documentation and/or other materials provided with the 13 * distribution. 14 * * Neither the name of Google Inc. nor the names of its 15 * contributors may be used to endorse or promote products derived from 16 * this software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31 #include "config.h" 32 #include "modules/filesystem/DirectoryReader.h" 33 34 #include "core/fileapi/FileError.h" 35 #include "modules/filesystem/EntriesCallback.h" 36 #include "modules/filesystem/Entry.h" 37 #include "modules/filesystem/ErrorCallback.h" 38 39 namespace WebCore { 40 41 class DirectoryReader::EntriesCallbackHelper : public EntriesCallback { 42 public: 43 explicit EntriesCallbackHelper(DirectoryReader* reader) 44 : m_reader(reader) 45 { 46 } 47 48 virtual void handleEvent(const EntryHeapVector& entries) OVERRIDE 49 { 50 m_reader->addEntries(entries); 51 } 52 53 private: 54 // FIXME: This Persistent keeps the reader alive until all of the readDirectory results are received. crbug.com/350285 55 Persistent<DirectoryReader> m_reader; 56 }; 57 58 class DirectoryReader::ErrorCallbackHelper : public ErrorCallback { 59 public: 60 explicit ErrorCallbackHelper(DirectoryReader* reader) 61 : m_reader(reader) 62 { 63 } 64 65 virtual void handleEvent(FileError* error) OVERRIDE 66 { 67 m_reader->onError(error); 68 } 69 70 private: 71 Persistent<DirectoryReader> m_reader; 72 }; 73 74 DirectoryReader::DirectoryReader(DOMFileSystemBase* fileSystem, const String& fullPath) 75 : DirectoryReaderBase(fileSystem, fullPath) 76 , m_isReading(false) 77 { 78 ScriptWrappable::init(this); 79 } 80 81 DirectoryReader::~DirectoryReader() 82 { 83 } 84 85 void DirectoryReader::readEntries(PassOwnPtr<EntriesCallback> entriesCallback, PassOwnPtr<ErrorCallback> errorCallback) 86 { 87 if (!m_isReading) { 88 m_isReading = true; 89 filesystem()->readDirectory(this, m_fullPath, adoptPtr(new EntriesCallbackHelper(this)), adoptPtr(new ErrorCallbackHelper(this))); 90 } 91 92 if (m_error) { 93 filesystem()->scheduleCallback(errorCallback, PassRefPtrWillBeRawPtr<FileError>(m_error.get())); 94 return; 95 } 96 97 if (m_entriesCallback) { 98 // Non-null m_entriesCallback means multiple readEntries() calls are made concurrently. We don't allow doing it. 99 filesystem()->scheduleCallback(errorCallback, FileError::create(FileError::INVALID_STATE_ERR)); 100 return; 101 } 102 103 if (!m_hasMoreEntries || !m_entries.isEmpty()) { 104 filesystem()->scheduleCallback(entriesCallback, m_entries); 105 m_entries.clear(); 106 return; 107 } 108 109 m_entriesCallback = entriesCallback; 110 m_errorCallback = errorCallback; 111 } 112 113 void DirectoryReader::addEntries(const EntryHeapVector& entries) 114 { 115 m_entries.appendVector(entries); 116 m_errorCallback = nullptr; 117 if (m_entriesCallback) { 118 OwnPtr<EntriesCallback> entriesCallback = m_entriesCallback.release(); 119 EntryHeapVector entries; 120 entries.swap(m_entries); 121 entriesCallback->handleEvent(entries); 122 } 123 } 124 125 void DirectoryReader::onError(FileError* error) 126 { 127 m_error = error; 128 m_entriesCallback = nullptr; 129 if (m_errorCallback) { 130 OwnPtr<ErrorCallback> errorCallback = m_errorCallback.release(); 131 errorCallback->handleEvent(error); 132 } 133 } 134 135 void DirectoryReader::trace(Visitor* visitor) 136 { 137 visitor->trace(m_entries); 138 visitor->trace(m_error); 139 DirectoryReaderBase::trace(visitor); 140 } 141 142 } 143