Bug 1936326 - Move IOUtils and PathUtils into XPCOM r=xpcom-reviewers,shtrom,zeid,nika

Differential Revision: https://phabricator.services.mozilla.com/D232251
This commit is contained in:
Beth Rennie
2025-04-03 15:28:31 +00:00
parent 37fd93165d
commit d471649fe2
33 changed files with 239 additions and 234 deletions

View File

@@ -413,6 +413,11 @@ DOMInterfaces = {
'headerFile': 'IDBEvents.h', 'headerFile': 'IDBEvents.h',
}, },
'IOUtils': {
'nativeType': 'mozilla::IOUtils',
'headerFile': 'mozilla/IOUtils.h',
},
'InspectorFontFace': { 'InspectorFontFace': {
'wrapperCache': False, 'wrapperCache': False,
}, },
@@ -589,6 +594,11 @@ DOMInterfaces = {
'headerFile': 'CanvasPath.h' 'headerFile': 'CanvasPath.h'
}, },
'PathUtils': {
'nativeType': 'mozilla::PathUtils',
'headerFile': 'mozilla/PathUtils.h',
},
'Performance' : { 'Performance' : {
'implicitJSContext': [ 'implicitJSContext': [
'mark' 'mark'
@@ -858,7 +868,8 @@ DOMInterfaces = {
}, },
'SyncReadFile': { 'SyncReadFile': {
'headerFile': 'mozilla/dom/IOUtils.h', 'nativeType': 'mozilla::SyncReadFile',
'headerFile': 'mozilla/IOUtils.h',
}, },
'Text': { 'Text': {

View File

@@ -14,12 +14,6 @@ with Files("*ocationProvider*"):
with Files("windows/*LocationProvider*"): with Files("windows/*LocationProvider*"):
BUG_COMPONENT = ("Core", "DOM: Geolocation") BUG_COMPONENT = ("Core", "DOM: Geolocation")
with Files("IOUtils*"):
BUG_COMPONENT = ("Toolkit", "IOUtils and PathUtils")
with Files("PathUtils*"):
BUG_COMPONENT = ("Toolkit", "IOUtils and PathUtils")
with Files("mac/*LocationProvider*"): with Files("mac/*LocationProvider*"):
BUG_COMPONENT = ("Core", "DOM: Geolocation") BUG_COMPONENT = ("Core", "DOM: Geolocation")
@@ -32,21 +26,9 @@ with Files("linux/*LocationProvider*"):
with Files("android/*LocationProvider*"): with Files("android/*LocationProvider*"):
BUG_COMPONENT = ("Core", "DOM: Geolocation") BUG_COMPONENT = ("Core", "DOM: Geolocation")
with Files("tests/chrome.toml"):
BUG_COMPONENT = ("Toolkit", "IOUtils and PathUtils")
with Files("tests/*constants*"):
BUG_COMPONENT = ("Toolkit", "IOUtils and PathUtils")
with Files("tests/ioutils/**"):
BUG_COMPONENT = ("Toolkit", "IOUtils and PathUtils")
with Files("tests/mochitest.toml"): with Files("tests/mochitest.toml"):
BUG_COMPONENT = ("Core", "DOM: Device Interfaces") BUG_COMPONENT = ("Core", "DOM: Device Interfaces")
with Files("test/*pathutils*"):
BUG_COMPONENT = ("Toolkit", "IOUtils and PathUtils")
with Files("tests/*1197901*"): with Files("tests/*1197901*"):
BUG_COMPONENT = ("Core", "DOM: Device Interfaces") BUG_COMPONENT = ("Core", "DOM: Device Interfaces")
@@ -78,17 +60,10 @@ EXPORTS += [
"nsOSPermissionRequestBase.h", "nsOSPermissionRequestBase.h",
] ]
EXPORTS.mozilla.dom += [
"IOUtils.h",
"PathUtils.h",
]
UNIFIED_SOURCES += [ UNIFIED_SOURCES += [
"IOUtils.cpp",
"nsDeviceSensors.cpp", "nsDeviceSensors.cpp",
"nsHapticFeedback.cpp", "nsHapticFeedback.cpp",
"nsOSPermissionRequestBase.cpp", "nsOSPermissionRequestBase.cpp",
"PathUtils.cpp",
] ]
EXTRA_JS_MODULES += [ EXTRA_JS_MODULES += [
@@ -110,5 +85,4 @@ LOCAL_INCLUDES += [
"/xpcom/base", "/xpcom/base",
] ]
MOCHITEST_CHROME_MANIFESTS += ["tests/chrome.toml", "tests/ioutils/chrome.toml"]
MOCHITEST_MANIFESTS += ["tests/mochitest.toml"] MOCHITEST_MANIFESTS += ["tests/mochitest.toml"]

View File

@@ -1,6 +0,0 @@
[DEFAULT]
["test_pathutils.html"]
["test_pathutils_worker.xhtml"]
support-files = ["pathutils_worker.js"]

View File

@@ -8,7 +8,7 @@
# documentation and how to modify this file. # documentation and how to modify this file.
repo: mozilla-central repo: mozilla-central
created_at: '2021-10-14T12:50:40.073465' created_at: '2021-10-14T12:50:40.073465'
updated_at: '2025-04-01T14:21:39.951774+00:00' updated_at: '2025-04-02T20:26:15.852994+00:00'
export: export:
path: ./docs/mots/index.rst path: ./docs/mots/index.rst
format: rst format: rst
@@ -3245,6 +3245,8 @@ modules:
- name: 'Core: XPCOM' - name: 'Core: XPCOM'
description: The cross-platform object model and core data structures. description: The cross-platform object model and core data structures.
includes: includes:
- dom/chrome-webidl/IOUtils.webidl
- dom/chrome-webidl/PathUtils.webidl
- startupcache/**/* - startupcache/**/*
- xpcom/**/* - xpcom/**/*
- xpcom/base/**/* - xpcom/base/**/*
@@ -3253,6 +3255,8 @@ modules:
- xpcom/docs/**/* - xpcom/docs/**/*
- xpcom/ds/**/* - xpcom/ds/**/*
- xpcom/glue/**/* - xpcom/glue/**/*
- xpcom/io/**/*
- xpcom/ioutils/**/*
- xpcom/reflect/**/* - xpcom/reflect/**/*
- xpcom/rust/**/* - xpcom/rust/**/*
- xpcom/system/**/* - xpcom/system/**/*
@@ -3271,6 +3275,7 @@ modules:
url: :ref:`XPCOM` url: :ref:`XPCOM`
components: components:
- Core::XPCOM - Core::XPCOM
- Toolkit::IOUtils and PathUtils
review_group: xpcom-reviewers review_group: xpcom-reviewers
owners: owners:
- *nika - *nika
@@ -4541,5 +4546,5 @@ modules:
- Ryan Tilder - Ryan Tilder
group: dev-platform group: dev-platform
hashes: hashes:
config: 1f1a65ce9444d293f1f1b8fc74b954bea0aa5a27 config: 93b411d8790c372028509fc186c01b8a34ec8cd5
export: 26b31fcb1ebef52108b7df136973ebf35a4ddc5b export: 3823627c4a11aab9dc12d92537080eeddffceb34

View File

@@ -49,7 +49,6 @@
#include "mozilla/Unused.h" #include "mozilla/Unused.h"
#include "mozilla/Telemetry.h" #include "mozilla/Telemetry.h"
#include "mozilla/dom/IOUtils.h"
#include "mozilla/dom/workerinternals/RuntimeService.h" #include "mozilla/dom/workerinternals/RuntimeService.h"
// Normally, the number of milliseconds that AsyncShutdown waits until // Normally, the number of milliseconds that AsyncShutdown waits until

View File

@@ -9,7 +9,6 @@
#include <cstdint> #include <cstdint>
#include "ErrorList.h" #include "ErrorList.h"
#include "TypedArray.h"
#include "js/ArrayBuffer.h" #include "js/ArrayBuffer.h"
#include "js/ColumnNumber.h" // JS::ColumnNumberOneOrigin #include "js/ColumnNumber.h" // JS::ColumnNumberOneOrigin
#include "js/JSON.h" #include "js/JSON.h"
@@ -96,10 +95,13 @@
} \ } \
} while (0) } while (0)
using namespace mozilla::dom;
static constexpr auto SHUTDOWN_ERROR = static constexpr auto SHUTDOWN_ERROR =
"IOUtils: Shutting down and refusing additional I/O tasks"_ns; "IOUtils: Shutting down and refusing additional I/O tasks"_ns;
namespace mozilla::dom { namespace mozilla {
// static helper functions // static helper functions
@@ -158,7 +160,7 @@ static nsCString FormatErrorMessage(nsresult aError,
[[nodiscard]] inline bool ToJSValue( [[nodiscard]] inline bool ToJSValue(
JSContext* aCx, const IOUtils::InternalFileInfo& aInternalFileInfo, JSContext* aCx, const IOUtils::InternalFileInfo& aInternalFileInfo,
JS::MutableHandle<JS::Value> aValue) { JS::MutableHandle<JS::Value> aValue) {
FileInfo info; dom::FileInfo info;
info.mPath.Construct(aInternalFileInfo.mPath); info.mPath.Construct(aInternalFileInfo.mPath);
info.mType.Construct(aInternalFileInfo.mType); info.mType.Construct(aInternalFileInfo.mType);
info.mSize.Construct(aInternalFileInfo.mSize); info.mSize.Construct(aInternalFileInfo.mSize);
@@ -331,8 +333,8 @@ void IOUtils::DispatchAndResolve(IOUtils::EventQueue* aQueue, Promise* aPromise,
if (!NS_IsMainThread()) { if (!NS_IsMainThread()) {
// We need to manually keep the worker alive until the promise returned by // We need to manually keep the worker alive until the promise returned by
// Dispatch() resolves or rejects. // Dispatch() resolves or rejects.
workerRef = StrongWorkerRef::CreateForcibly(GetCurrentThreadWorkerPrivate(), workerRef = StrongWorkerRef::CreateForcibly(
__func__); GetCurrentThreadWorkerPrivate(), __func__);
} }
if (RefPtr<IOPromise<OkT>> p = aQueue->Dispatch<OkT, Fn>(std::move(aFunc))) { if (RefPtr<IOPromise<OkT>> p = aQueue->Dispatch<OkT, Fn>(std::move(aFunc))) {
@@ -1884,16 +1886,16 @@ Result<IOUtils::InternalFileInfo, IOUtils::IOError> IOUtils::StatSync(
} }
// Now we can populate the info object by querying the file. // Now we can populate the info object by querying the file.
info.mType = FileType::Regular; info.mType = dom::FileType::Regular;
if (!isRegular) { if (!isRegular) {
bool isDir = false; bool isDir = false;
IOUTILS_TRY_WITH_CONTEXT(aFile->IsDirectory(&isDir), "Could not stat `%s'", IOUTILS_TRY_WITH_CONTEXT(aFile->IsDirectory(&isDir), "Could not stat `%s'",
aFile->HumanReadablePath().get()); aFile->HumanReadablePath().get());
info.mType = isDir ? FileType::Directory : FileType::Other; info.mType = isDir ? dom::FileType::Directory : dom::FileType::Other;
} }
int64_t size = -1; int64_t size = -1;
if (info.mType == FileType::Regular) { if (info.mType == dom::FileType::Regular) {
IOUTILS_TRY_WITH_CONTEXT(aFile->GetFileSize(&size), "Could not stat `%s'", IOUTILS_TRY_WITH_CONTEXT(aFile->GetFileSize(&size), "Could not stat `%s'",
aFile->HumanReadablePath().get()); aFile->HumanReadablePath().get());
} }
@@ -2099,6 +2101,8 @@ Result<nsString, IOUtils::IOError> IOUtils::CreateUniqueSync(
/* static */ /* static */
Result<nsCString, IOUtils::IOError> IOUtils::ComputeHexDigestSync( Result<nsCString, IOUtils::IOError> IOUtils::ComputeHexDigestSync(
nsIFile* aFile, const HashAlgorithm aAlgorithm) { nsIFile* aFile, const HashAlgorithm aAlgorithm) {
using HashAlgorithm = HashAlgorithm;
static constexpr size_t BUFFER_SIZE = 8192; static constexpr size_t BUFFER_SIZE = 8192;
SECOidTag alg; SECOidTag alg;
@@ -3093,7 +3097,7 @@ uint32_t IOUtils::LaunchProcess(GlobalObject& aGlobal,
} }
#endif // XP_UNIX #endif // XP_UNIX
} // namespace mozilla::dom } // namespace mozilla
#undef REJECT_IF_INIT_PATH_FAILED #undef REJECT_IF_INIT_PATH_FAILED
#undef IOUTILS_TRY_WITH_CONTEXT #undef IOUTILS_TRY_WITH_CONTEXT

View File

@@ -51,8 +51,6 @@ class PR_CloseDelete {
void operator()(PRFileDesc* aPtr) const { PR_Close(aPtr); } void operator()(PRFileDesc* aPtr) const { PR_Close(aPtr); }
}; };
namespace dom {
/** /**
* Implementation for the Web IDL interface at dom/chrome-webidl/IOUtils.webidl. * Implementation for the Web IDL interface at dom/chrome-webidl/IOUtils.webidl.
* Methods of this class must only be called from the parent process. * Methods of this class must only be called from the parent process.
@@ -72,71 +70,67 @@ class IOUtils final {
using PhaseArray = EnumeratedArray<IOUtils::ShutdownPhase, T, using PhaseArray = EnumeratedArray<IOUtils::ShutdownPhase, T,
size_t(IOUtils::ShutdownPhase::Count)>; size_t(IOUtils::ShutdownPhase::Count)>;
static already_AddRefed<Promise> Read(GlobalObject& aGlobal, static already_AddRefed<dom::Promise> Read(dom::GlobalObject& aGlobal,
const nsAString& aPath,
const ReadOptions& aOptions,
ErrorResult& aError);
static already_AddRefed<Promise> ReadUTF8(GlobalObject& aGlobal,
const nsAString& aPath,
const ReadUTF8Options& aOptions,
ErrorResult& aError);
static already_AddRefed<Promise> ReadJSON(GlobalObject& aGlobal,
const nsAString& aPath,
const ReadUTF8Options& aOptions,
ErrorResult& aError);
static already_AddRefed<Promise> Write(GlobalObject& aGlobal,
const nsAString& aPath,
const Uint8Array& aData,
const WriteOptions& aOptions,
ErrorResult& aError);
static already_AddRefed<Promise> WriteUTF8(GlobalObject& aGlobal,
const nsAString& aPath, const nsAString& aPath,
const nsACString& aString, const dom::ReadOptions& aOptions,
const WriteOptions& aOptions,
ErrorResult& aError); ErrorResult& aError);
static already_AddRefed<Promise> WriteJSON(GlobalObject& aGlobal, static already_AddRefed<dom::Promise> ReadUTF8(
const nsAString& aPath, dom::GlobalObject& aGlobal, const nsAString& aPath,
JS::Handle<JS::Value> aValue, const dom::ReadUTF8Options& aOptions, ErrorResult& aError);
const WriteOptions& aOptions,
static already_AddRefed<dom::Promise> ReadJSON(
dom::GlobalObject& aGlobal, const nsAString& aPath,
const dom::ReadUTF8Options& aOptions, ErrorResult& aError);
static already_AddRefed<dom::Promise> Write(dom::GlobalObject& aGlobal,
const nsAString& aPath,
const dom::Uint8Array& aData,
const dom::WriteOptions& aOptions,
ErrorResult& aError);
static already_AddRefed<dom::Promise> WriteUTF8(
dom::GlobalObject& aGlobal, const nsAString& aPath,
const nsACString& aString, const dom::WriteOptions& aOptions,
ErrorResult& aError);
static already_AddRefed<dom::Promise> WriteJSON(
dom::GlobalObject& aGlobal, const nsAString& aPath,
JS::Handle<JS::Value> aValue, const dom::WriteOptions& aOptions,
ErrorResult& aError);
static already_AddRefed<dom::Promise> Move(dom::GlobalObject& aGlobal,
const nsAString& aSourcePath,
const nsAString& aDestPath,
const dom::MoveOptions& aOptions,
ErrorResult& aError); ErrorResult& aError);
static already_AddRefed<Promise> Move(GlobalObject& aGlobal, static already_AddRefed<dom::Promise> Remove(
const nsAString& aSourcePath, dom::GlobalObject& aGlobal, const nsAString& aPath,
const nsAString& aDestPath, const dom::RemoveOptions& aOptions, ErrorResult& aError);
const MoveOptions& aOptions,
ErrorResult& aError);
static already_AddRefed<Promise> Remove(GlobalObject& aGlobal, static already_AddRefed<dom::Promise> MakeDirectory(
const nsAString& aPath, dom::GlobalObject& aGlobal, const nsAString& aPath,
const RemoveOptions& aOptions, const dom::MakeDirectoryOptions& aOptions, ErrorResult& aError);
ErrorResult& aError);
static already_AddRefed<Promise> MakeDirectory( static already_AddRefed<dom::Promise> Stat(dom::GlobalObject& aGlobal,
GlobalObject& aGlobal, const nsAString& aPath, const nsAString& aPath,
const MakeDirectoryOptions& aOptions, ErrorResult& aError); ErrorResult& aError);
static already_AddRefed<Promise> Stat(GlobalObject& aGlobal, static already_AddRefed<dom::Promise> Copy(dom::GlobalObject& aGlobal,
const nsAString& aPath, const nsAString& aSourcePath,
ErrorResult& aError); const nsAString& aDestPath,
const dom::CopyOptions& aOptions,
ErrorResult& aError);
static already_AddRefed<Promise> Copy(GlobalObject& aGlobal, static already_AddRefed<dom::Promise> SetAccessTime(
const nsAString& aSourcePath, dom::GlobalObject& aGlobal, const nsAString& aPath,
const nsAString& aDestPath, const dom::Optional<int64_t>& aAccess, ErrorResult& aError);
const CopyOptions& aOptions,
ErrorResult& aError);
static already_AddRefed<Promise> SetAccessTime( static already_AddRefed<dom::Promise> SetModificationTime(
GlobalObject& aGlobal, const nsAString& aPath, dom::GlobalObject& aGlobal, const nsAString& aPath,
const Optional<int64_t>& aAccess, ErrorResult& aError); const dom::Optional<int64_t>& aModification, ErrorResult& aError);
static already_AddRefed<Promise> SetModificationTime(
GlobalObject& aGlobal, const nsAString& aPath,
const Optional<int64_t>& aModification, ErrorResult& aError);
private: private:
using SetTimeFn = decltype(&nsIFile::SetLastAccessedTime); using SetTimeFn = decltype(&nsIFile::SetLastAccessedTime);
@@ -144,109 +138,101 @@ class IOUtils final {
static_assert( static_assert(
std::is_same_v<SetTimeFn, decltype(&nsIFile::SetLastModifiedTime)>); std::is_same_v<SetTimeFn, decltype(&nsIFile::SetLastModifiedTime)>);
static already_AddRefed<Promise> SetTime(GlobalObject& aGlobal, static already_AddRefed<dom::Promise> SetTime(
const nsAString& aPath, dom::GlobalObject& aGlobal, const nsAString& aPath,
const Optional<int64_t>& aNewTime, const dom::Optional<int64_t>& aNewTime, SetTimeFn aSetTimeFn,
SetTimeFn aSetTimeFn, const char* const aTimeKind, ErrorResult& aError);
const char* const aTimeKind,
ErrorResult& aError);
public: public:
static already_AddRefed<Promise> HasChildren( static already_AddRefed<dom::Promise> HasChildren(
GlobalObject& aGlobal, const nsAString& aPath, dom::GlobalObject& aGlobal, const nsAString& aPath,
const HasChildrenOptions& aOptions, ErrorResult& aError); const dom::HasChildrenOptions& aOptions, ErrorResult& aError);
static already_AddRefed<Promise> GetChildren( static already_AddRefed<dom::Promise> GetChildren(
GlobalObject& aGlobal, const nsAString& aPath, dom::GlobalObject& aGlobal, const nsAString& aPath,
const GetChildrenOptions& aOptions, ErrorResult& aError); const dom::GetChildrenOptions& aOptions, ErrorResult& aError);
static already_AddRefed<Promise> SetPermissions(GlobalObject& aGlobal, static already_AddRefed<dom::Promise> SetPermissions(
const nsAString& aPath, dom::GlobalObject& aGlobal, const nsAString& aPath, uint32_t aPermissions,
uint32_t aPermissions, const bool aHonorUmask, ErrorResult& aError);
const bool aHonorUmask,
ErrorResult& aError);
static already_AddRefed<Promise> Exists(GlobalObject& aGlobal, static already_AddRefed<dom::Promise> Exists(dom::GlobalObject& aGlobal,
const nsAString& aPath, const nsAString& aPath,
ErrorResult& aError); ErrorResult& aError);
static already_AddRefed<Promise> CreateUniqueFile(GlobalObject& aGlobal, static already_AddRefed<dom::Promise> CreateUniqueFile(
const nsAString& aParent, dom::GlobalObject& aGlobal, const nsAString& aParent,
const nsAString& aPrefix, const nsAString& aPrefix, const uint32_t aPermissions,
const uint32_t aPermissions, ErrorResult& aError);
ErrorResult& aError); static already_AddRefed<dom::Promise> CreateUniqueDirectory(
static already_AddRefed<Promise> CreateUniqueDirectory( dom::GlobalObject& aGlobal, const nsAString& aParent,
GlobalObject& aGlobal, const nsAString& aParent, const nsAString& aPrefix, const nsAString& aPrefix, const uint32_t aPermissions,
const uint32_t aPermissions, ErrorResult& aError); ErrorResult& aError);
private: private:
/** /**
* A helper method for CreateUniqueFile and CreateUniqueDirectory. * A helper method for CreateUniqueFile and CreateUniqueDirectory.
*/ */
static already_AddRefed<Promise> CreateUnique(GlobalObject& aGlobal, static already_AddRefed<dom::Promise> CreateUnique(
const nsAString& aParent, dom::GlobalObject& aGlobal, const nsAString& aParent,
const nsAString& aPrefix, const nsAString& aPrefix, const uint32_t aFileType,
const uint32_t aFileType, const uint32_t aPermissions, ErrorResult& aError);
const uint32_t aPermissions,
ErrorResult& aError);
public: public:
static already_AddRefed<Promise> ComputeHexDigest( static already_AddRefed<dom::Promise> ComputeHexDigest(
GlobalObject& aGlobal, const nsAString& aPath, dom::GlobalObject& aGlobal, const nsAString& aPath,
const HashAlgorithm aAlgorithm, ErrorResult& aError); const dom::HashAlgorithm aAlgorithm, ErrorResult& aError);
#if defined(XP_WIN) #if defined(XP_WIN)
static already_AddRefed<Promise> GetWindowsAttributes(GlobalObject& aGlobal, static already_AddRefed<dom::Promise> GetWindowsAttributes(
const nsAString& aPath, dom::GlobalObject& aGlobal, const nsAString& aPath, ErrorResult& aError);
ErrorResult& aError);
static already_AddRefed<Promise> SetWindowsAttributes( static already_AddRefed<dom::Promise> SetWindowsAttributes(
GlobalObject& aGlobal, const nsAString& aPath, dom::GlobalObject& aGlobal, const nsAString& aPath,
const mozilla::dom::WindowsFileAttributes& aAttrs, ErrorResult& aError); const mozilla::dom::WindowsFileAttributes& aAttrs, ErrorResult& aError);
#elif defined(XP_MACOSX) #elif defined(XP_MACOSX)
static already_AddRefed<Promise> HasMacXAttr(GlobalObject& aGlobal, static already_AddRefed<dom::Promise> HasMacXAttr(dom::GlobalObject& aGlobal,
const nsAString& aPath, const nsAString& aPath,
const nsACString& aAttr, const nsACString& aAttr,
ErrorResult& aError); ErrorResult& aError);
static already_AddRefed<Promise> GetMacXAttr(GlobalObject& aGlobal, static already_AddRefed<dom::Promise> GetMacXAttr(dom::GlobalObject& aGlobal,
const nsAString& aPath, const nsAString& aPath,
const nsACString& aAttr, const nsACString& aAttr,
ErrorResult& aError); ErrorResult& aError);
static already_AddRefed<Promise> SetMacXAttr(GlobalObject& aGlobal, static already_AddRefed<dom::Promise> SetMacXAttr(
const nsAString& aPath, dom::GlobalObject& aGlobal, const nsAString& aPath,
const nsACString& aAttr, const nsACString& aAttr, const dom::Uint8Array& aValue,
const Uint8Array& aValue, ErrorResult& aError);
ErrorResult& aError); static already_AddRefed<dom::Promise> DelMacXAttr(dom::GlobalObject& aGlobal,
static already_AddRefed<Promise> DelMacXAttr(GlobalObject& aGlobal, const nsAString& aPath,
const nsAString& aPath, const nsACString& aAttr,
const nsACString& aAttr, ErrorResult& aError);
ErrorResult& aError);
#endif #endif
#ifdef XP_UNIX #ifdef XP_UNIX
using UnixString = OwningUTF8StringOrUint8Array; using UnixString = dom::OwningUTF8StringOrUint8Array;
static uint32_t LaunchProcess(GlobalObject& aGlobal, static uint32_t LaunchProcess(dom::GlobalObject& aGlobal,
const Sequence<UnixString>& aArgv, const dom::Sequence<UnixString>& aArgv,
const LaunchOptions& aOptions, const dom::LaunchOptions& aOptions,
ErrorResult& aRv); ErrorResult& aRv);
#endif #endif
static already_AddRefed<Promise> GetFile( static already_AddRefed<dom::Promise> GetFile(
GlobalObject& aGlobal, const Sequence<nsString>& aComponents, dom::GlobalObject& aGlobal, const dom::Sequence<nsString>& aComponents,
ErrorResult& aError); ErrorResult& aError);
static already_AddRefed<Promise> GetDirectory( static already_AddRefed<dom::Promise> GetDirectory(
GlobalObject& aGlobal, const Sequence<nsString>& aComponents, dom::GlobalObject& aGlobal, const dom::Sequence<nsString>& aComponents,
ErrorResult& aError); ErrorResult& aError);
static void GetProfileBeforeChange(GlobalObject& aGlobal, static void GetProfileBeforeChange(dom::GlobalObject& aGlobal,
JS::MutableHandle<JS::Value>, JS::MutableHandle<JS::Value>,
ErrorResult& aRv); ErrorResult& aRv);
static void GetSendTelemetry(GlobalObject& aGlobal, static void GetSendTelemetry(dom::GlobalObject& aGlobal,
JS::MutableHandle<JS::Value>, ErrorResult& aRv); JS::MutableHandle<JS::Value>, ErrorResult& aRv);
static RefPtr<SyncReadFile> OpenFileForSyncReading(GlobalObject& aGlobal, static RefPtr<SyncReadFile> OpenFileForSyncReading(dom::GlobalObject& aGlobal,
const nsAString& aPath, const nsAString& aPath,
ErrorResult& aRv); ErrorResult& aRv);
@@ -255,7 +241,7 @@ class IOUtils final {
/** /**
* The kind of buffer to allocate. * The kind of buffer to allocate.
* *
* This controls what kind of JS object (a JSString or a Uint8Array) is * This controls what kind of JS object (a JSString or a dom::Uint8Array) is
* returned by |ToJSValue()|. * returned by |ToJSValue()|.
*/ */
enum class BufferKind { enum class BufferKind {
@@ -277,9 +263,8 @@ class IOUtils final {
class State; class State;
template <typename Fn> template <typename Fn>
static already_AddRefed<Promise> WithPromiseAndState(GlobalObject& aGlobal, static already_AddRefed<dom::Promise> WithPromiseAndState(
ErrorResult& aError, dom::GlobalObject& aGlobal, ErrorResult& aError, Fn aFn);
Fn aFn);
/** /**
* Dispatch a task on the event queue and resolve or reject the associated * Dispatch a task on the event queue and resolve or reject the associated
@@ -293,16 +278,16 @@ class IOUtils final {
* @param aFunc The task to run. * @param aFunc The task to run.
*/ */
template <typename OkT, typename Fn> template <typename OkT, typename Fn>
static void DispatchAndResolve(EventQueue* aQueue, Promise* aPromise, static void DispatchAndResolve(EventQueue* aQueue, dom::Promise* aPromise,
Fn aFunc); Fn aFunc);
/** /**
* Creates a new JS Promise. * Creates a new JS dom::Promise.
* *
* @return The new promise, or |nullptr| on failure. * @return The new promise, or |nullptr| on failure.
*/ */
static already_AddRefed<Promise> CreateJSPromise(GlobalObject& aGlobal, static already_AddRefed<dom::Promise> CreateJSPromise(
ErrorResult& aError); dom::GlobalObject& aGlobal, ErrorResult& aError);
// Allow conversion of |InternalFileInfo| with |ToJSValue|. // Allow conversion of |InternalFileInfo| with |ToJSValue|.
friend bool ToJSValue(JSContext* aCx, friend bool ToJSValue(JSContext* aCx,
@@ -539,7 +524,7 @@ class IOUtils final {
* @return The hash of the file, as a hex digest. * @return The hash of the file, as a hex digest.
*/ */
static Result<nsCString, IOError> ComputeHexDigestSync( static Result<nsCString, IOError> ComputeHexDigestSync(
nsIFile* aFile, const HashAlgorithm aAlgorithm); nsIFile* aFile, const dom::HashAlgorithm aAlgorithm);
#if defined(XP_WIN) #if defined(XP_WIN)
/** /**
@@ -573,7 +558,7 @@ class IOUtils final {
const nsCString& aAttr); const nsCString& aAttr);
#endif #endif
static void GetShutdownClient(GlobalObject& aGlobal, static void GetShutdownClient(dom::GlobalObject& aGlobal,
JS::MutableHandle<JS::Value> aClient, JS::MutableHandle<JS::Value> aClient,
ErrorResult& aRv, const ShutdownPhase aPhase); ErrorResult& aRv, const ShutdownPhase aPhase);
@@ -727,7 +712,7 @@ class IOUtils::IOError {
*/ */
struct IOUtils::InternalFileInfo { struct IOUtils::InternalFileInfo {
nsString mPath; nsString mPath;
FileType mType = FileType::Other; dom::FileType mType = dom::FileType::Other;
uint64_t mSize = 0; uint64_t mSize = 0;
Maybe<PRTime> mCreationTime; // In ms since epoch. Maybe<PRTime> mCreationTime; // In ms since epoch.
PRTime mLastAccessed = 0; // In ms since epoch. PRTime mLastAccessed = 0; // In ms since epoch.
@@ -746,12 +731,12 @@ struct IOUtils::InternalFileInfo {
struct IOUtils::InternalWriteOpts { struct IOUtils::InternalWriteOpts {
RefPtr<nsIFile> mBackupFile; RefPtr<nsIFile> mBackupFile;
RefPtr<nsIFile> mTmpFile; RefPtr<nsIFile> mTmpFile;
WriteMode mMode; dom::WriteMode mMode;
bool mFlush = false; bool mFlush = false;
bool mCompress = false; bool mCompress = false;
static Result<InternalWriteOpts, IOUtils::IOError> FromBinding( static Result<InternalWriteOpts, IOUtils::IOError> FromBinding(
const WriteOptions& aOptions); const dom::WriteOptions& aOptions);
}; };
/** /**
@@ -938,7 +923,7 @@ class SyncReadFile : public nsISupports, public nsWrapperCache {
JS::Handle<JSObject*> aGivenProto) override; JS::Handle<JSObject*> aGivenProto) override;
int64_t Size() const { return mSize; } int64_t Size() const { return mSize; }
void ReadBytesInto(const Uint8Array&, const int64_t, ErrorResult& aRv); void ReadBytesInto(const dom::Uint8Array&, const int64_t, ErrorResult& aRv);
void Close(); void Close();
private: private:
@@ -949,7 +934,6 @@ class SyncReadFile : public nsISupports, public nsWrapperCache {
int64_t mSize = 0; int64_t mSize = 0;
}; };
} // namespace dom
} // namespace mozilla } // namespace mozilla
#endif #endif

View File

@@ -31,7 +31,9 @@
#include "nsURLHelper.h" #include "nsURLHelper.h"
#include "xpcpublic.h" #include "xpcpublic.h"
namespace mozilla::dom { using namespace mozilla::dom;
namespace mozilla {
static constexpr auto ERROR_EMPTY_PATH = static constexpr auto ERROR_EMPTY_PATH =
"PathUtils does not support empty paths"_ns; "PathUtils does not support empty paths"_ns;
@@ -632,4 +634,4 @@ nsresult PathUtils::DirectoryCache::PopulateDirectoriesImpl(
return NS_OK; return NS_OK;
} }
} // namespace mozilla::dom } // namespace mozilla

View File

@@ -23,8 +23,6 @@
namespace mozilla { namespace mozilla {
class ErrorResult; class ErrorResult;
namespace dom {
class PathUtils final { class PathUtils final {
public: public:
/** /**
@@ -41,14 +39,15 @@ class PathUtils final {
*/ */
static nsresult InitFileWithPath(nsIFile* aFile, const nsAString& aPath); static nsresult InitFileWithPath(nsIFile* aFile, const nsAString& aPath);
static void Filename(const GlobalObject&, const nsAString& aPath, static void Filename(const dom::GlobalObject&, const nsAString& aPath,
nsString& aResult, ErrorResult& aErr); nsString& aResult, ErrorResult& aErr);
static void Parent(const GlobalObject&, const nsAString& aPath, static void Parent(const dom::GlobalObject&, const nsAString& aPath,
const int32_t aDepth, nsString& aResult, const int32_t aDepth, nsString& aResult,
ErrorResult& aErr); ErrorResult& aErr);
static void Join(const GlobalObject&, const Sequence<nsString>& aComponents, static void Join(const dom::GlobalObject&,
const dom::Sequence<nsString>& aComponents,
nsString& aResult, ErrorResult& aErr); nsString& aResult, ErrorResult& aErr);
/** /**
@@ -65,45 +64,47 @@ class PathUtils final {
static already_AddRefed<nsIFile> Join(const Span<const nsString>& aComponents, static already_AddRefed<nsIFile> Join(const Span<const nsString>& aComponents,
ErrorResult& aErr); ErrorResult& aErr);
static void JoinRelative(const GlobalObject&, const nsAString& aBasePath, static void JoinRelative(const dom::GlobalObject&, const nsAString& aBasePath,
const nsAString& aRelativePath, nsString& aResult, const nsAString& aRelativePath, nsString& aResult,
ErrorResult& aErr); ErrorResult& aErr);
static void ToExtendedWindowsPath(const GlobalObject&, const nsAString& aPath, static void ToExtendedWindowsPath(const dom::GlobalObject&,
nsString& aResult, ErrorResult& aErr); const nsAString& aPath, nsString& aResult,
static void Normalize(const GlobalObject&, const nsAString& aPath,
nsString& aResult, ErrorResult& aErr);
static void Split(const GlobalObject&, const nsAString& aPath,
nsTArray<nsString>& aResult, ErrorResult& aErr);
static void SplitRelative(const GlobalObject& aGlobal, const nsAString& aPath,
const SplitRelativeOptions& aOptions,
nsTArray<nsString>& aResult, ErrorResult& aErr);
static void ToFileURI(const GlobalObject&, const nsAString& aPath,
nsCString& aResult, ErrorResult& aErr);
static bool IsAbsolute(const GlobalObject&, const nsAString& aPath);
static void GetProfileDirSync(const GlobalObject&, nsString& aResult,
ErrorResult& aErr);
static void GetLocalProfileDirSync(const GlobalObject&, nsString& aResult,
ErrorResult& aErr);
static void GetTempDirSync(const GlobalObject&, nsString& aResult,
ErrorResult& aErr);
static void GetXulLibraryPathSync(const GlobalObject&, nsString& aResult,
ErrorResult& aErr); ErrorResult& aErr);
static already_AddRefed<Promise> GetProfileDirAsync( static void Normalize(const dom::GlobalObject&, const nsAString& aPath,
const GlobalObject& aGlobal, ErrorResult& aErr); nsString& aResult, ErrorResult& aErr);
static already_AddRefed<Promise> GetLocalProfileDirAsync(
const GlobalObject& aGlobal, ErrorResult& aErr); static void Split(const dom::GlobalObject&, const nsAString& aPath,
static already_AddRefed<Promise> GetTempDirAsync(const GlobalObject& aGlobal, nsTArray<nsString>& aResult, ErrorResult& aErr);
ErrorResult& aErr);
static already_AddRefed<Promise> GetXulLibraryPathAsync( static void SplitRelative(const dom::GlobalObject& aGlobal,
const GlobalObject& aGlobal, ErrorResult& aErr); const nsAString& aPath,
const dom::SplitRelativeOptions& aOptions,
nsTArray<nsString>& aResult, ErrorResult& aErr);
static void ToFileURI(const dom::GlobalObject&, const nsAString& aPath,
nsCString& aResult, ErrorResult& aErr);
static bool IsAbsolute(const dom::GlobalObject&, const nsAString& aPath);
static void GetProfileDirSync(const dom::GlobalObject&, nsString& aResult,
ErrorResult& aErr);
static void GetLocalProfileDirSync(const dom::GlobalObject&,
nsString& aResult, ErrorResult& aErr);
static void GetTempDirSync(const dom::GlobalObject&, nsString& aResult,
ErrorResult& aErr);
static void GetXulLibraryPathSync(const dom::GlobalObject&, nsString& aResult,
ErrorResult& aErr);
static already_AddRefed<dom::Promise> GetProfileDirAsync(
const dom::GlobalObject& aGlobal, ErrorResult& aErr);
static already_AddRefed<dom::Promise> GetLocalProfileDirAsync(
const dom::GlobalObject& aGlobal, ErrorResult& aErr);
static already_AddRefed<dom::Promise> GetTempDirAsync(
const dom::GlobalObject& aGlobal, ErrorResult& aErr);
static already_AddRefed<dom::Promise> GetXulLibraryPathAsync(
const dom::GlobalObject& aGlobal, ErrorResult& aErr);
private: private:
class DirectoryCache; class DirectoryCache;
@@ -175,9 +176,9 @@ class PathUtils::DirectoryCache final {
* *
* @return A promise that resolves to the path of the requested directory. * @return A promise that resolves to the path of the requested directory.
*/ */
already_AddRefed<Promise> GetDirectoryAsync(const GlobalObject& aGlobalObject, already_AddRefed<dom::Promise> GetDirectoryAsync(
ErrorResult& aErr, const dom::GlobalObject& aGlobalObject, ErrorResult& aErr,
const Directory aRequestedDir); const Directory aRequestedDir);
private: private:
using PopulateDirectoriesPromise = MozPromise<Ok, nsresult, false>; using PopulateDirectoriesPromise = MozPromise<Ok, nsresult, false>;
@@ -238,7 +239,8 @@ class PathUtils::DirectoryCache final {
* @param aPromise The JS promise to resolve. * @param aPromise The JS promise to resolve.
* @param aRequestedDir The requested directory cache entry. * @param aRequestedDir The requested directory cache entry.
*/ */
void ResolveWithDirectory(Promise* aPromise, const Directory aRequestedDir); void ResolveWithDirectory(dom::Promise* aPromise,
const Directory aRequestedDir);
template <typename T> template <typename T>
using DirectoryArray = using DirectoryArray =
@@ -255,7 +257,6 @@ class PathUtils::DirectoryCache final {
}; };
}; };
} // namespace dom
} // namespace mozilla } // namespace mozilla
#endif #endif

24
xpcom/ioutils/moz.build Normal file
View File

@@ -0,0 +1,24 @@
# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
# vim: set filetype=python:
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
with Files("**/*"):
BUG_COMPONENT = ("Toolkit", "IOUtils and PathUtils")
EXPORTS.mozilla += [
"IOUtils.h",
"PathUtils.h",
]
UNIFIED_SOURCES += [
"IOUtils.cpp",
"PathUtils.cpp",
]
MOCHITEST_CHROME_MANIFESTS += ["tests/chrome.toml"]
FINAL_LIBRARY = "xul"
include("/ipc/chromium/chromium-config.mozbuild")

View File

@@ -37,3 +37,8 @@ run-if = ["os == 'mac'"]
run-if = ["os == 'win'"] run-if = ["os == 'win'"]
["test_ioutils_worker.xhtml"] ["test_ioutils_worker.xhtml"]
["test_pathutils.html"]
["test_pathutils_worker.xhtml"]
support-files = ["pathutils_worker.js"]

View File

@@ -1,5 +1,7 @@
// Utility functions. // Utility functions.
/* eslint-env mozilla/simpletest */
Uint8Array.prototype.equals = function equals(other) { Uint8Array.prototype.equals = function equals(other) {
if (this.byteLength !== other.byteLength) { if (this.byteLength !== other.byteLength) {
return false; return false;

View File

@@ -1,4 +1,3 @@
<!-- Any copyright is dedicated to the Public Domain. <!-- Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ --> - http://creativecommons.org/publicdomain/zero/1.0/ -->
<!DOCTYPE HTML> <!DOCTYPE HTML>

View File

@@ -27,6 +27,7 @@ DIRS += [
"system", "system",
"../chrome", "../chrome",
"build", "build",
"ioutils",
] ]
if CONFIG["OS_ARCH"] == "WINNT" and CONFIG["MOZ_DEBUG"]: if CONFIG["OS_ARCH"] == "WINNT" and CONFIG["MOZ_DEBUG"]: