/** * Recursive search for node with string */ fs_node_t* evaluatePath(const char* path, fs_node_t* current_node) { if (!path) { return 0; } if (path[0] == '/') { return evaluatePath(path + 1, get_vfs()); } char* buffer = strchr(path, '/'); if (buffer == 0) { if (strcmp(path, "") == 0) { return current_node; } else { return finddir_fs(current_node, path); } } else { char splitLeftBuffer[buffer - path + 1]; memcpy((void*) splitLeftBuffer, (void*) path, buffer - path); splitLeftBuffer[buffer - path] = '\0'; fs_node_t* temp = finddir_fs(current_node, splitLeftBuffer); if (temp != 0) { return evaluatePath(buffer + 1, temp); } return 0; } }
void ServiceWalker::computeWalkerPath() { std::list<PathWay> pathWayList; Propagator pathPropagator; pathPropagator.init(*_building); pathPropagator.getAllPaths(_maxDistance, pathWayList); float maxPathValue = 0.0; PathWay* bestPath = NULL; for (std::list<PathWay>::iterator itPath = pathWayList.begin(); itPath != pathWayList.end(); ++itPath) { PathWay &path = *itPath; float pathValue = evaluatePath(path); if (pathValue > maxPathValue) { bestPath = &path; maxPathValue = pathValue; } } if (bestPath == NULL) { // no good path _isDeleted = true; return; } reservePath(*bestPath); setPathWay(*bestPath); setIJ(_pathWay.getOrigin().getI(), _pathWay.getOrigin().getJ()); Scenario::instance().getCity().getWalkerList().push_back(this); }
void DOMFileSystem::getFile(ScriptExecutionContext& context, FileSystemFileEntry& fileEntry, GetFileCallback&& completionCallback) { auto virtualPath = fileEntry.virtualPath(); auto fullPath = evaluatePath(virtualPath); m_workQueue->dispatch([context = makeRef(context), fullPath = crossThreadCopy(fullPath), virtualPath = crossThreadCopy(virtualPath), completionCallback = WTFMove(completionCallback)]() mutable { auto validatedVirtualPath = validatePathIsExpectedType(fullPath, WTFMove(virtualPath), FileMetadata::Type::File); callOnMainThread([context = WTFMove(context), fullPath = crossThreadCopy(fullPath), validatedVirtualPath = crossThreadCopy(validatedVirtualPath), completionCallback = WTFMove(completionCallback)]() mutable { if (validatedVirtualPath.hasException()) completionCallback(validatedVirtualPath.releaseException()); else completionCallback(File::create(fullPath)); }); }); }
// https://wicg.github.io/entries-api/#dom-filesystemdirectoryentry-getfile // https://wicg.github.io/entries-api/#dom-filesystemdirectoryentry-getdirectory void DOMFileSystem::getEntry(ScriptExecutionContext& context, FileSystemDirectoryEntry& directory, const String& virtualPath, const FileSystemDirectoryEntry::Flags& flags, GetEntryCallback&& completionCallback) { ASSERT(&directory.filesystem() == this); if (!isValidVirtualPath(virtualPath)) { callOnMainThread([completionCallback = WTFMove(completionCallback)] { completionCallback(Exception { TypeMismatchError, "Path is invalid"_s }); }); return; } if (flags.create) { callOnMainThread([completionCallback = WTFMove(completionCallback)] { completionCallback(Exception { SecurityError, "create flag cannot be true"_s }); }); return; } auto resolvedVirtualPath = resolveRelativeVirtualPath(directory.virtualPath(), virtualPath); ASSERT(resolvedVirtualPath[0] == '/'); auto fullPath = evaluatePath(resolvedVirtualPath); if (fullPath == m_rootPath) { callOnMainThread([this, context = makeRef(context), completionCallback = WTFMove(completionCallback)]() mutable { completionCallback(Ref<FileSystemEntry> { root(context) }); }); return; } m_workQueue->dispatch([this, context = makeRef(context), fullPath = crossThreadCopy(fullPath), resolvedVirtualPath = crossThreadCopy(resolvedVirtualPath), completionCallback = WTFMove(completionCallback)]() mutable { auto entryType = fileType(fullPath); callOnMainThread([this, context = WTFMove(context), resolvedVirtualPath = crossThreadCopy(resolvedVirtualPath), entryType, completionCallback = WTFMove(completionCallback)]() mutable { if (!entryType) { completionCallback(Exception { NotFoundError, "Cannot find entry at given path"_s }); return; } switch (entryType.value()) { case FileMetadata::Type::Directory: completionCallback(Ref<FileSystemEntry> { FileSystemDirectoryEntry::create(context, *this, resolvedVirtualPath) }); break; case FileMetadata::Type::File: completionCallback(Ref<FileSystemEntry> { FileSystemFileEntry::create(context, *this, resolvedVirtualPath) }); break; default: completionCallback(Exception { NotFoundError, "Cannot find entry at given path"_s }); break; } }); }); }
void DOMFileSystem::getParent(ScriptExecutionContext& context, FileSystemEntry& entry, GetParentCallback&& completionCallback) { ASSERT(&entry.filesystem() == this); auto virtualPath = resolveRelativeVirtualPath(entry.virtualPath(), ".."); ASSERT(virtualPath[0] == '/'); auto fullPath = evaluatePath(virtualPath); m_workQueue->dispatch([this, context = makeRef(context), fullPath = crossThreadCopy(fullPath), virtualPath = crossThreadCopy(virtualPath), completionCallback = WTFMove(completionCallback)]() mutable { auto validatedVirtualPath = validatePathIsExpectedType(fullPath, WTFMove(virtualPath), FileMetadata::Type::Directory); callOnMainThread([this, context = WTFMove(context), validatedVirtualPath = crossThreadCopy(validatedVirtualPath), completionCallback = WTFMove(completionCallback)]() mutable { if (validatedVirtualPath.hasException()) completionCallback(validatedVirtualPath.releaseException()); else completionCallback(FileSystemDirectoryEntry::create(context, *this, validatedVirtualPath.releaseReturnValue())); }); }); }
/* evaluate a path of any type and return the object value it refers to * (or the result of the method it refers to) */ shared_ptr<Object> evaluateObject(const string& path) { assert (!path.empty()); auto parts = getExpressionParts(path); if (parts.size() > 1) { auto property = evaluatePath(parts); if (property.first == nullptr) { return nullptr; } return evaluatePropertyOrMethod(property.first, property.second); } else { return context.lookupObject(parts[0]); } }
void DOMFileSystem::listDirectory(ScriptExecutionContext& context, FileSystemDirectoryEntry& directory, DirectoryListingCallback&& completionHandler) { ASSERT(&directory.filesystem() == this); auto directoryVirtualPath = directory.virtualPath(); auto fullPath = evaluatePath(directoryVirtualPath); if (fullPath == m_rootPath) { Vector<Ref<FileSystemEntry>> children; children.append(fileAsEntry(context)); completionHandler(WTFMove(children)); return; } m_workQueue->dispatch([this, context = makeRef(context), completionHandler = WTFMove(completionHandler), fullPath = crossThreadCopy(fullPath), directoryVirtualPath = crossThreadCopy(directoryVirtualPath)]() mutable { auto listedChildren = listDirectoryWithMetadata(fullPath); callOnMainThread([this, context = WTFMove(context), completionHandler = WTFMove(completionHandler), listedChildren = crossThreadCopy(listedChildren), directoryVirtualPath = directoryVirtualPath.isolatedCopy()]() mutable { completionHandler(toFileSystemEntries(context, *this, WTFMove(listedChildren), directoryVirtualPath)); }); }); }