1. 序論
◎非規範的この文書は、[ ~file~system~API用の基礎的な基盤 ]を定義する。 加えて、[ ~web~siteが~file~system~directoryへの~accessを取得する ]ことを[ その前に利用者が~access用の~promptを経る ]ことなくアリにする~APIを定義する。 これは、 ~web~siteが~dataを[ 利用者が保存する~locationを選び取る前に,~diskへ保存する ]ことが求まれる利用事例を可能化する — そのような~file用に[ 異なる~APIを伴う,完全に異なる~storageの仕組み ]を利用するよう~web~siteに強制することなく。 そのための入口は、 `navigator.storage.getDirectory()@#dom-storagemanager-getdirectory$c ~methodである。 ◎ This document defines fundamental infrastructure for file system APIs. In addition, it defines an API that makes it possible for websites to get access to a file system directory without having to first prompt the user for access. This enables use cases where a website wants to save data to disk before a user has picked a location to save to, without forcing the website to use a completely different storage mechanism with a different API for such files. The entry point for this is the navigator.storage.getDirectory() method.
【この訳に特有な表記規約】
◎表記記号`~NUL~byte@ は、 値 0x00 をとる`~byte$である。
2. ~fileと~directory
2.1. 概念
`~file~system~entry@ は、[ `~file~entry$fs/`~directory~entry$fs ]の総称である。 ◎ A file system entry is either a file entry or a directory entry.
各`~file~system~entry$には、 2 つの~algo `~query~access@fE , `要請~access@fE が結付けられる。 いずれも、 所与の %~mode ~IN { `read^l, `readwrite^l } に対し, `~file~system~access結果$を返す — 他が指定されない限り、 結果の[ `許可~状態$fsAは `denied$l, `~error名$fsAは 空~文字列 ]になる。 ◎ Each file system entry has an associated query access algorithm, which takes "read" or "readwrite" mode and returns a file system access result. Unless specified otherwise it returns a file system access result with a permission state of "denied" and with an error name of the empty string. ◎ Each file system entry has an associated request access algorithm, which takes "read" or "readwrite" mode and returns a file system access result. Unless specified otherwise it returns a file system access result with a permission state of "denied" and with an error name of the empty string.
`~file~system~access結果@ は、 ~file~systemに対する[ `~query~access$fE/`要請~access$fE ]の結果を~capsule化する`構造体$であり、 次に挙げる`~item$sctからなる: ◎ A file system access result is a struct encapsulating the result of querying or requesting access to the file system. It has the following items:
- `許可~状態@fsA ⇒ `PermissionState$I 値 ◎ permission state • A PermissionState
-
`~error名@fsA ⇒ `文字列$ — それは、 `許可~状態$fsAに応じて:
- `granted$l の場合、 空~文字列になるモノトスル。
- 他の場合、 `DOMException^I 用の`名前~表t@~WEBIDL#dfn-error-names-table$に~listされた`名前$eXになるモノトスル。 この場合、 ほとんどの事例では, "`NotAllowedError$E" になるベキであることが期待される。
この仕様に依存している仕様は、 この~APIを`強力な特能$と見なし得る。 他の`強力な特能$においては, `許可~要請~algo@~PERMISSION-REQUEST#permission-request-algorithm$は例外を投出し得るが、 それとは違って,`~entry$fsの[ `~query~access$fE/`要請~access$fE ]~algoには投出することは許容されない — それらは、 `~file~system~queue$上で`並列的$に走らす必要があるので。 代わりに,~call元には、[ これらの~algoが空~文字列~以外の`~error名$fsAを返した場合 ]には[ 適切に`~promiseを却下する$ための`~storage~taskを~queueする$ ]ことが期待される。 ◎ Dependent specifications may consider this API a powerful feature. However, unlike other powerful features whose permission request algorithm may throw, file system entry's query access and request access algorithms must run in parallel on the file system queue and are therefore not allowed to throw. Instead, the caller is expected to queue a storage task to reject, as appropriate, should these algorithms return an error name other than the empty string.
注記: この仕様のみを実装し,この仕様に依存する他の仕様 【例: `File System Access@https://wicg.github.io/file-system-access/$cite 】 を実装しない実装は、[ `~query~access$fE/`要請~access$fE ]を~~特に実装する必要はない。 ◎ Note: Implementations that only implement this specification and not dependent specifications do not need to bother implementing file system entry's query access and request access.
~access検査~algoたちを `FileSystemHandle$I に結付けられるようにする。 ◎ Make access check algorithms associated with a FileSystemHandle.
各`~file~system~entry$には、 `文字列$をとる `名前@fE も結付けられる。 ◎ Each file system entry has an associated name (a string).
所与の`文字列$ %文字列 が `妥当な~file名@ であるとは、 ~AND↓ を満たすことをいう: ◎ A valid file name is a string\
- %文字列 ~NIN { 空~文字列, `.^l, `..^l } ◎ that is not an empty string, is not equal to "." or "..",\
- %文字列 を成す どの文字も次を満たす ⇒ [ `/^l でない ]~AND[ 下層の~platform上で~path分離子として利用される文字でない ] ◎ and does not contain '/' or any other character used as path separator on the underlying platform.
注記: すなわち、 ~file名における `\^l は — ~Windows上では許容されないが — 他の~OSでは許容されるかもしれない。 加えて,下層の~file~systemには、 許容されない名前に関して,他にも制約があるかもしれない — なので、 ある文字列が単に`妥当な~file名$であるだけでは,それを名前に伴う[ ~file/~directory ]を作成することに成功する保証は無い。 ◎ Note: This means that '\' is not allowed in names on Windows, but might be allowed on other operating systems. Additionally underlying file systems might have further restrictions on what names are or aren’t allowed, so a string merely being a valid file name is not a guarantee that creating a file or directory with that name will succeed.
~file名に対し,[ この~APIを利用するときには決して許容されない,規範的な制約 ]を更に設けることを考慮するべきである — 下層の~file~systemにまるごと委ねるのではなく。 ◎ We should consider having further normative restrictions on file names that will never be allowed using this API, rather than leaving it entirely up to underlying file systems.
各 `~file~entry@fs には、 次に挙げるものも結付けられる: ◎ A file entry additionally consists of\
- `~binary~data@fE ⇒ `~byte列$ ◎ binary data (a byte sequence),\
- `改変~時刻印@fE ⇒ `~Unix~Epoch$からの~milli秒数を表現している整数 ◎ a modification timestamp (a number representing the number of milliseconds since the Unix Epoch),\
- `~lock@fE ⇒ 次に挙げるいずれか ⇒# `未獲^i, `排他的に獲された^i, `共用として獲された^i ◎ a lock (a string that may exclusively be "open", "taken-exclusive" or "taken-shared")\
- `共用~lock数@fE ⇒ 所与の時点に獲された共用~lockたちの個数を表現している整数 【初期~時は 0 とする。】 ◎ and a shared lock count (a number representing the number shared locks that are taken at a given point in time).
~UAには、 `~file~system~queue@ が結付けられる — それは、 【初期~時は】 `新たな並列~queueを開始-$した結果とする。 この~queueは、 すべての~file~system演算~用に利用されることになる。 ◎ A user agent has an associated file system queue which is the result of starting a new parallel queue. This queue is to be used for all file system operations.
`~lockを獲する@ ときは、 所与の ( `~file~entry$fs %~file, %値 ~IN { `排他的^i, `共用^i } ) に対し:
-
~IF[ %値 ~EQ `排他的^i ]:
- ~IF[ %~file の`~lock$fE ~NEQ `未獲^i ] ⇒ ~RET `失敗^i
- %~file の`~lock$fE ~SET `排他的に獲された^i
-
~ELSE ( %値 ~EQ `共用^i ):
- ~IF[ %~file の`~lock$fE ~EQ `排他的に獲された^i ] ⇒ ~RET `失敗^i
- %~file の`共用~lock数$fE ~INCBY 1
- %~file の`~lock$fE ~SET `共用として獲された^i
- ~RET `成功^i
注記: この手続きは、 `~file~system~queue$上で走らす必要がある。
◎ To take a lock with a value of "exclusive" or "shared" on a given file entry file: • Let lock be the file’s lock. • Let count be the file’s shared lock count. • If value is "exclusive": •• If lock is "open": ••• Set lock to "taken-exclusive". ••• Return "success". • If value is "shared": •• If lock is "open": ••• Set lock to "taken-shared". ••• Set count to 1. ••• Return "success". •• Otherwise, if lock is "taken-shared": ••• Increase count by 1. ••• Return "success". • Return "failure". ◎ Note: These steps have to be run on the file system queue.`~lockを解放する@ ときは、 所与の ( `~file~entry$fs %~file ) に対し:
-
~IF[ %~file の`~lock$fE ~EQ `共用として獲された^i ]:
- %~file の`共用~lock数$fE ~DECBY 1
- ~IF[ %~file の`共用~lock数$fE ~NEQ 0 ] ⇒ ~RET
- %~file の`~lock$fE ~SET `未獲^i
注記: この手続きは、 `~file~system~queue$上で走らす必要がある。
◎ To release a lock on a given file entry file: • Let lock be the file’s associated lock. • Let count be the file’s shared lock count. • If lock is "taken-shared": •• Decrease count by 1. •• If count is 0, set lock to "open". • Otherwise, set lock to "open". ◎ Note: These steps have to be run on the file system queue.注記: ~lockは、 ~fileに対する同時並行な改変を防止する助けになる。 `FileSystemWritableFileStream$I は `共用^i ~lockを要求する一方で、 `FileSystemSyncAccessHandle$I は `排他的^i ~lockを要求する。 ◎ Note: Locks help prevent concurrent modifications to a file. A FileSystemWritableFileStream requires a shared lock, while a FileSystemSyncAccessHandle requires an exclusive one.
各 `~directory~entry@fs には、 次に挙げるものも結付けられる: ◎ A directory entry additionally consists of\
- `子~群@fE ⇒ `~file~system~entry$たちが成す`有順序~集合$ ◎ a set of children, which are themselves file system entries. Each member is either a file entry or a directory entry.
所与の`~file~system~entry$ %~entry の `親@fE は、 `~directory~entry$fsのうち[ %~entry ~IN その`子~群$fE ]を満たすものは[ 在るならばそれ/ 無いならば ~NULL ]である — そのような~directory~entryは、 在っても 1 個に限られるベキである。 ◎ A file system entry entry should be contained in the children of at most one directory entry, and that directory entry is also known as entry’s parent. A file system entry's parent is null if no such directory entry exists.
注記: 複数個の`~file~system~entry$が,~disk上の同じ[ ~file/~directory ]を表現することもある — その事例でも、[ 両~entryの`親$fEが異なる/ 一方の`親$fEだけ ~NULL になる ]ことはアリである。 ◎ Note: Two different file system entries can represent the same file or directory on disk, in which case it is possible for both entries to have a different parent, or for one entry to have a parent while the other entry does not have a parent.
`~file~system~entry$は,~host~OSの局所~file~system上の~fileにより~backされ得る (が,そうする~~義務はない)ので、 ~entryの[ `~binary~data$fE, `改変~時刻印$fE, `子~群$fE ]は[ この仕様の外側にある~appにより改変される ]こともアリである。 [ 外部からの変更が,この仕様により定義される~data構造において正確に どう反映されるか ]および[ ここに定義される~data構造に為された変更が,外部にどう反映されるか ]は、 個々の~UA実装に委ねられる。 ◎ File system entries can (but don’t have to) be backed by files on the host operating system’s local file system, so it is possible for the binary data, modification timestamp, and children of entries to be modified by applications outside of this specification. Exactly how external changes are reflected in the data structures defined by this specification, as well as how changes made to the data structures defined here are reflected externally is left up to individual user-agent implementations.
( `~file~system~entry$ %a, `~file~system~entry$ %b ) が `同一-~entry@ であるとは、 次を満たすことをいう ⇒ [ %a ~EQ %b ]~OR[ %a, %b は、 局所~file~system上の同じ[ ~file/~directory ]より~backされている ] ◎ A file system entry a is the same entry as a file system entry b if a is equal to b, or if a and b are backed by the same file or directory on the local file system.
`~locatorを根に相対的に解決する@ ときは、 所与の ( `~file~system~locator$ %子, `~directory~locator$ %根 ) に対し: ◎ To resolve a file system locator child relative to a directory locator root:
- %~promise ~LET `新たな~promise$ ◎ Let result be a new promise.
-
`~file~system~queue$に次の`手続きを~enqueueする$ ⇒ `~promiseを解決する$( %~promise, 次の手続きを走らせた結果 ) ◎ Enqueue the following steps to the file system queue:
手続きは: ◎ ↓
- ~IF[ %子 の`~locator$fsHの`根$lC ~NEQ %根 の`~locator$fsHの`根$lC ] ⇒ ~RET ~NULL ◎ If child’s locator's root is not root’s locator's root, resolve result with null, and abort these steps.
- %子~path ~LET %子 の`~locator$fsHの`~path$lC ◎ Let childPath be child’s locator's path.
- %根~path ~LET %根 の`~locator$fsHの`~path$lC ◎ Let rootPath be root’s locator's path.
- ~IF[ ( %子~path, %根~path ) は`同一-~path$である ] ⇒ ~RET « » ◎ If childPath is the same path as rootPath, resolve result with « », and abort these steps.
- ~IF[ %根~path の`~size$ ~GT %子~path の`~size$ ] ⇒ ~RET ~NULL ◎ If rootPath’s size is greater than childPath’s size, resolve result with null, and abort these steps.
-
%根~path の`~index群$を成す ~EACH( %~index ) に対し ⇒ ~IF[ %根~path[ %~index ] ~NEQ %子~path[ %~index ] ] ⇒ ~RET ~NULL ◎ For each index of rootPath’s indices: • If rootPath.\[[index]] is not childPath.\[[index]], then resolve result with null, and abort these steps.
- %相対~path ~LET « » ◎ Let relativePath be « ».
- `範囲$ { %根~path の`~size$ 〜 %根~path の`~size$ ~MINUS 1 } を成す ~EACH( %~index ) に対し ⇒ %相対~path に %子~path[ %~index ] を`付加する$ ◎ For each index of the range from rootPath’s size to rootPath’s size, exclusive, append childPath.\[[index]] to relativePath.
- ~RET %相対~path ◎ Resolve result with relativePath.
- ~RET %~promise ◎ Return result.
`~file~system~locator@ は、 `~file~system~entry$の~locationになり得るものを表現する。 `~file~system~locator$は[ `~file~locator$ / `~directory~locator$ ]の総称である。 ◎ A file system locator represents a potential location of a file system entry. A file system locator is either a file locator or a directory locator.
各`~file~system~locator$には、 次に挙げるものが結付けられる: ◎ Each file system locator has an associated\
- `~path@lC ⇒ ある`~file~system~path$ ◎ path (a file system path),\
- `種類@lC ⇒ ある `FileSystemHandleKind$I ◎ a kind (a FileSystemHandleKind),\
- `根@lC ⇒ ある`~file~system根$ ◎ and a root (a file system root).
各~locatorに`~storage~bucket$を与えることを考慮する。 ◎ Consider giving each locator a storage bucket.
`~file~system~locator$は、 その`種類$lCに応じて,[ `file$l ならば `~file~locator@ / `directory$l ならば `~directory~locator@ ]に大別される。 ◎ A file locator is a file system locator whose kind is "file". A directory locator is a file system locator whose kind is "directory".
`~file~system根@ は、 `実装定義$な不透明な値をとる`文字列$である。 ◎ A file system root is an opaque string whose value is implementation-defined.
`~file~system~locator$を`~locateした結果@#locating-an-entry$が概念的に[ `~bucket~file~system$の根~directoryから相対的な~path `data/drafts/example.txt^c ]に存在する`~file~entry$fsになる場合、 当の~locatorの: ◎ For a file system locator locator whichs locates to a file entry entry that conceptually exists at the path data/drafts/example.txt relative to the root directory of a bucket file system,\
- `種類$lC は、 `file$l になっているはずである。 ◎ locator’s kind has to be "file",\
- `~path$lC は、 « `data^l, `drafts^l, `example.txt^l » になっているはずである。 ◎ locator’s path has to be « "data", "drafts", "example.txt" »,\
- `根$lC は、 関連な情報として,`~storage~bucket$や~disk~driveなどを識別するものを含むかもしれない。 ◎ and locator’s root might include relevant identifying information such as the storage bucket and the disk drive.
( `~file~system~locator$ %a, `~file~system~locator$ %b ) が `同一-~locator@ であるとは、 次を満たすことをいう ⇒ [ %a の`種類$lC ~EQ %b の`種類$lC ]~AND[ %a の`根$lC ~EQ %b の`根$lC ]~AND[ ( %a の`~path$lC, %b の`~path$lC ) は`同一-~path$である ] ◎ A file system locator a is the same locator as a file system locator b if a’s kind is b’s kind, a’s root is b’s root, and a’s path is the same path as b’s path.
`~entryを~locateする@ ~algoは、 所与の ( `~file~system~locator$ %~locator ) に対し,`実装定義$な手続きを走らす — その結果 %~entry が以下に挙げる拘束を固守するような: ◎ The locate an entry algorithm given a file system locator locator runs an implementation-defined series of steps adhering to these constraints:
- [ %~entry ~EQ ~NULL ]~OR[ %~entry は %~locator に応じて次を満たす ] ⇒# `~file~locator$である場合,`~file~entry$fsである/ `~directory~locator$である場合,`~directory~entry$fsである ◎ If locator is a file locator, they return a file entry or null. ◎ If locator is a directory locator, they return a directory entry or null.
-
[ %~entry ~NEQ ~NULL 【この場合を指して, “%~locator は~locatable” と称される】 ]ならば, %~entry は次を満たす: ◎ If these steps return a non-null entry, then:
- 走らせた中間的な~file~system演算は無い限りにおいて, 次が満たされる ⇒ %~locator ~EQ `~locatorを取得する$( %~entry ) ◎ Getting the locator with entry returns locator, provided no intermediate file system operations were run.
- %~entry の`名前$fE ~EQ %~locator の`~path$lCを成す最後の`~item$ ◎ entry’s name is the last item of locator’s path.
`~locatorを取得する@ ~algoは、 所与の ( `~file~system~entry$ %~entry ) に対し,`実装定義$な手続きを走らす — その結果 %~locator が以下に挙げる拘束を固守するような: ◎ The get the locator algorithm given file system entry entry runs an implementation-defined series of steps adhering to these constraints:
- %~locator は %~entry に応じて次を満たす ⇒# `~file~entry$fsである場合,`~file~locator$である/ `~directory~entry$fsである場合,`~directory~locator$である ◎ If entry is a file entry, they return a file locator. ◎ If entry is a directory entry, they return a directory locator.
-
%~locator は次を満たす: ◎ If these steps return locator, then:
- 走らせた中間的な~file~system演算は無い限りにおいて, 次が満たされる ⇒ %~entry ~EQ `~entryを~locateする$( %~locator ) ◎ Locating an entry with locator returns entry, provided no intermediate file system operations were run.
- %~entry の`名前$fE ~EQ %~locator の`~path$lCを成す最後の`~item$ ◎ entry’s name is the last item of locator’s path.
`~file~system~path@ は、 `文字列$たちが成す空でない`~list$である。 これは、[ ~disk上/~memory内 ]の本物の~locationに対応付けられる~virtualな~pathになることも, 局所~file~system上の ある~pathに直に対応することも, ~disk上の どの~fileにも対応しないこともある。 対応する`~file~system~entry$の実際の物理的な~locationは`実装定義$とする。 ◎ A file system path is a list of one or more strings. This may be a virtual path that is mapped to real location on disk or in memory, may correspond directly to a path on the local file system, or may not correspond to any file on disk at all. The actual physical location of the corresponding file system entry is implementation-defined.
~path « `data^l, `drafts^l, `example.txt^l » に対し、 名前 `example.txt^l を伴う~fileが~disk上のどこかに存在することは期待されていない。 ◎ Let path be the list « "data", "drafts", "example.txt" ». There is no expectation that a file named example.txt exists anywhere on disk.
( `~file~system~path$ %a, `~file~system~path$ %b ) が `同一-~path@ であるとは、 次を満たすことをいう ⇒ [ %a の`~size$ ~EQ %b の`~size$ ]~AND[ %a の`~index群$を成す各 %~index に対し, %a[ %~index ] ~EQ %b[ %~index ] ] ◎ A file system path a is the same path as a file system path b if a’s size is the same as b’s size and for each index of a’s indices a.\[[index]] is b.\[[index]].
`~file~system~locator$の内容 — その`~path$lCを含む — は、 それ全体が~web~site~processと共有されることは期待されていない。 `~file~system~path$は、 当の~web~siteには未知な成分を包含するかもしれない — 当の`~file~system~locator$が後で,ある親`~directory~locator$に`相対的に解決され@#locator-resolve$ない限り。 ◎ The contents of a file system locator, including its path, are not expected to be shared in their entirety with the website process. The file system path might contain components which are not known to the website unless the file system locator is later resolved relative to a parent directory locator.
2.2. `FileSystemHandle^I ~interface
enum `FileSystemHandleKind@I { `file@l, `directory@l, }; [`Exposed$=(Window,Worker), `SecureContext$, `Serializable$] interface `FileSystemHandle@I { readonly attribute `FileSystemHandleKind$I `kind$m; readonly attribute `USVString$ `name$m; `Promise$<`boolean$> `isSameEntry$m(`FileSystemHandle$I %other); };
各 `FileSystemHandle$I ~objには `~locator@fsH が結付けられる — それは、 ある`~file~system~locator$をとる。 ◎ A FileSystemHandle object is associated with a locator (a file system locator).
注記: 複数個の `FileSystemHandle$I ~objは、 互いに`同一-~locator$になる`~file~system~locator$を有し得る。 ◎ Note: Multiple FileSystemHandle objects can have the same file system locator.
所与の `FileSystemHandle$I %~handle が `ある~bucket~file~system内に在る@ とは、 次が満たされることをいう ⇒ %~handle の`~locator$fsHの`~path$lC[ 0 ] ~EQ 空~文字列 ◎ A FileSystemHandle is in a bucket file system if the first item of its locator's path is the empty string.
注記: これは少々不思議に見えるが、 ちゃんと働く — ~locatorのうち,その`~path$lCが空~文字列を`包含する@~INFRA#list-contain$ものは、 `~bucket~file~system$の根~directoryに限られるので。 `getDirectory()$m を見よ。 `~path$lCを成す他のすべての`~item$は、 `妥当な~file名$になる。 ◎ Note: This is a bit magical, but it works since only the root directory of a bucket file system can have a path which contains an empty string. See getDirectory(). All other items of a path will be a valid file name.
各~locatorに`~storage~bucket$を与えることにより, この状況を改善することを考慮する。 ◎ Consider improving this situation by giving each locator a storage bucket.
`FileSystemHandle$I ~objは`直列化-可能$である: ◎ FileSystemHandle objects are serializable objects.
-
その`直列化~手続き$は、 所与の ( %値, %直列形, %~storage用か ) に対し: ◎ Their serialization steps, given value, serialized and forStorage are:
- %直列形 .`Origin^sl ~SET %値 に`関連な設定群~obj$の`生成元$enV ◎ Set serialized.[[Origin]] to value’s relevant settings object's origin.
- %直列形 .`Locator^sl ~SET %値 の`~locator$fsH ◎ Set serialized.[[Locator]] to value’s locator.
-
その`逆直列化~手続き$は、 所与の ( %直列形, %値 ) に対し: ◎ Their deserialization steps, given serialized and value are:
- ~IF[ ( %直列形 . `Origin^sl, %値 に`関連な設定群~obj$の`生成元$enV ) は`同一-生成元$でない ] ⇒ ~THROW `DataCloneError$E ◎ If serialized.[[Origin]] is not same origin with value’s relevant settings object's origin, then throw a "DataCloneError" DOMException.
- %値 の`~locator$fsH ~SET %直列形 .`Locator^sl ◎ Set value’s locator to serialized.[[Locator]].
- %handle . `kind$m
- %handle に応じて ⇒# `FileSystemFileHandle$I であるならば `file$l を返す/ `FileSystemDirectoryHandle$I であるならば `directory$l を返す ◎ Returns "file" if handle is a FileSystemFileHandle, or "directory" if handle is a FileSystemDirectoryHandle.
- これを利用すれば、 ある~directoryの内容~越しに反復するとき,~fileと~directoryを判別できる。 ◎ This can be used to distinguish files from directories when iterating over the contents of a directory.
- %handle . `name$m
- %handle の`~locator$fsHの`~path$lCを成す最後の~path成分を返す。 ◎ Returns the last path component of handle’s locator's path.
`kind@m 取得子~手続きは ⇒ ~RET コレの`~locator$fsHの`種類$lC ◎ The kind getter steps are to return this's locator's kind.
`name@m 取得子~手続きは ⇒ ~RET コレの`~locator$fsHの`~path$lCを成す最後の`~item$ ◎ The name getter steps are to return the last item (a string) of this's locator's path.
`isSameEntry()^m ~method
- %same = await %handle1 . `isSameEntry$m( %handle2 )
- [ %handle1, %handle2 ]が同じ[ ~file/~directory ]を表現するならば ~T を返す。 ◎ Returns true if handle1 and handle2 represent the same file or directory.
`isSameEntry(other)@m ~method手続きは: ◎ The isSameEntry(other) method steps are:
- %~realm ~LET コレに`関連な~realm$ ◎ Let realm be this's relevant Realm.
- %p ~LET %~realm に属する`新たな~promise$ ◎ Let p be a new promise in realm.
-
`~file~system~queue$に次の`手続きを~enqueueする$: ◎ Enqueue the following steps to the file system queue:
- %結果 ~LET ~IS[ ( コレの`~locator$fsH, %other の`~locator$fsH ) は`同一-~locator$である ]
- `~promiseを解決する$( %p, %結果 )
- ~RET %p ◎ Return p.
2.3. `FileSystemFileHandle^I ~interface
dictionary `FileSystemCreateWritableOptions@I { `boolean$ `keepExistingData@mb = false; }; [`Exposed$=(Window,Worker), `SecureContext$, `Serializable$] interface `FileSystemFileHandle@I : `FileSystemHandle$I { `Promise$<`File$I> `getFile$m(); `Promise$<`FileSystemWritableFileStream$I> `createWritable$m(optional `FileSystemCreateWritableOptions$I %options = {}); [`Exposed$=DedicatedWorker] `Promise$<`FileSystemSyncAccessHandle$I> `createSyncAccessHandle$m(); };
注記: `FileSystemFileHandle$I に結付けられた`~locator$fsHの`種類$lCは `file$l になる。 ◎ Note: A FileSystemFileHandle's associated locator's kind is "file".
`子~file~handleを作成する@ ときは、 所与の ( `~directory~locator$ %親~locator, 文字列 %名前, `~realm$ %~realm ) に対し:
- %子~path ~LET %親~locator の`~path$lCを`~cloneする$
- %子~path に %名前 を`付加する$
- ~RET `~file~handleを作成する$( %親~locator の`根$lCの複製, %子~path, %~realm )
`~file~handleを作成する@ ときは、 所与の ( `~file~system根$ %根, `~file~system~path$ %~path, `~realm$ %~realm ) に対し: ◎ To create a new FileSystemFileHandle given a file system root root and a file system path path in a Realm realm:
- ~RET %~realm に属する`新たな$ `FileSystemFileHandle$I — その ⇒ `~locator$fsH ~SET 新たな`~file~system~locator$ — その ⇒# `種類$lC ~SET `file$l, `根$lC ~SET %根, `~path$lC ~SET %~path ◎ Let handle be a new FileSystemFileHandle in realm. ◎ Set handle’s locator to a file system locator whose kind is "file", root is root, and path is path. ◎ Return handle.
`FileSystemFileHandle$I ~objは`直列化-可能$である。 その[ `直列化~手続き$, `逆直列化~手続き$ ]は、 `FileSystemHandle$I 用のそれらと同じとする。 ◎ FileSystemFileHandle objects are serializable objects. Their serialization steps and deserialization steps are the same as those for FileSystemHandle.
`getFile()^m ~method
- %file = await %fileHandle . `getFile()$m
- [[ %handle の`~locator$fsHにより`~locatable$な`~file~entry$fs ]の~disk上の状態 ]を表現している `File$I を返す。 この~methodが~callされた後に~disk上の~fileが[ 変更された/除去された ]場合、 返される `File$I ~objは,もはや可読にならなくなる見込みが高い。 ◎ Returns a File representing the state on disk of the file entry locatable by handle’s locator. If the file on disk changes or is removed after this method is called, the returned File object will likely be no longer readable.
`getFile()@m ~method手続きは: ◎ The getFile() method steps are:
- %~promise ~LET `新たな~promise$ ◎ Let result be a new promise.
- %~locator ~LET コレの`~locator$fsH ◎ Let locator be this's locator.
- %大域~obj ~LET コレに`関連な大域~obj$ ◎ Let global be this's relevant global object.
-
`~file~system~queue$に次の`手続きを~enqueueする$: ◎ Enqueue the following steps to the file system queue:
- %~entry ~LET `~entryを~locateする$( %~locator ) ◎ Let entry be the result of locating an entry given locator.
- %~access結果 ~LET %~entry の`~query~access$fE( `read^l ) ◎ Let accessResult be the result of running entry’s query access given "read".
-
`~storage~taskを~queueする$( %大域~obj, 次の手続き ) ◎ Queue a storage task with global to\
手続きは: ◎ run these steps:
- ~IF[ %~access結果 の`許可~状態$fsA ~NEQ `granted$l ] ⇒# `~promiseを却下する$( %~promise, %~access結果 の`~error名$fsAを`名前$eXに伴う例外 ); ~RET ◎ If accessResult’s permission state is not "granted", reject result with a DOMException of accessResult’s error name and abort these steps.
- ~IF[ %~entry ~EQ ~NULL ] ⇒# `~promiseを却下する$( %~promise, `NotFoundError$E 例外 ); ~RET ◎ If entry is null, reject result with a "NotFoundError" DOMException and abort these steps.
- ~Assert: %~entry は`~file~entry$fsである。 ◎ Assert: entry is a file entry.
-
%file ~LET 新たな `File$I — その ⇒# `~snapshot状態$ ~SET %~entry の現在の状態, `~byte列~data$ ~SET %~entry の`~binary~data$fEの複製, `name$mF ~SET %~entry の`名前$fE, `lastModified$mF ~SET %~entry の`改変~時刻印$fE, `type$mF ~SET `実装定義$な値(例えば %~entry の`名前$fEや~file拡張子に基づく) ◎ Let f be a new File. ◎ Set f’s snapshot state to the current state of entry. ◎ Set f’s underlying byte sequence to a copy of entry’s binary data. ◎ Set f’s name to entry’s name. ◎ Set f’s lastModified to entry’s modification timestamp. ◎ Set f’s type to an implementation-defined value, based on for example entry’s name or its file extension.
[ 読取る/~snapshotする ]ときの挙動は、 `FILE-API$r 仕様にて もっと良く指定される必要がある — 今の所、 これは,ぼやかされている。 ◎ The reading and snapshotting behavior needs to be better specified in the [FILE-API] spec, for now this is kind of hand-wavy.
- `~promiseを解決する$( %~promise, %file ) ◎ Resolve result with f.
- ~RET %~promise ◎ Return result.
`createWritable()^m ~method
- %stream = await %fileHandle . `createWritable()$m
- %stream = await %fileHandle . `createWritable$m({ `keepExistingData$mb: true/false })
- [ %fileHandle の`~locator$fsHにより`~locatable$な`~file~entry$fs ] %~file~entry へ書込むために利用できる `FileSystemWritableFileStream$I を返す。 %stream を通して為された変更は、 当の~streamが~closeされるまでは, %~file~entry 内に反映されない。 ~UAは、 部分的な書込nが起こらないことを確保するよう試行する — すなわち,当の~fileは、 次のいずれかを包含することになる ⇒# その旧-内容/ %stream が~closeされるまで %stream を通して書込まれたすべての~data ◎ Returns a FileSystemWritableFileStream that can be used to write to the file. Any changes made through stream won’t be reflected in the file entry locatable by fileHandle’s locator until the stream has been closed. User agents try to ensure that no partial writes happen, i.e. the file will either contain its old contents or it will contain whatever data was written through stream up until the stream has been closed.
- これは、 概して,次により実装される ⇒ ~dataを一時的な~fileへ書込んで、 %stream 【!the writable filestream】が~closeされたときに限り, %~file~entry を一時的な~fileで置換する。 ◎ This is typically implemented by writing data to a temporary file, and only replacing the file entry locatable by fileHandle’s locator with the temporary file when the writable filestream is closed.
- この一時的な~fileは、 開始-時は, `keepExistingData$mb に応じて[ ~T ならば既存の~fileの複製/ ~F ならば空 ]になる。 ◎ If keepExistingData is false or not specified, the temporary file starts out empty, otherwise the existing file is first copied to this temporary file.
- `FileSystemWritableFileStream$I を作成するとき、 %~file~entry に対する共用`~lockを獲する$。 これは、 当の~streamが~closeされるまで, %~file~entry 用の `FileSystemSyncAccessHandle$I の作成を防止する。 ◎ Creating a FileSystemWritableFileStream takes a shared lock on the file entry locatable with fileHandle’s locator. This prevents the creation of FileSystemSyncAccessHandles for the entry, until the stream is closed.
`createWritable()^m 用の “`inPlace^en” ~mode周りの論点, それに対し欲されるものは、 `WICG/file-system-access 課題 #67@https://github.com/WICG/file-system-access/issues/67$ を見よ (この~modeの下では、 変更は,当の書込器へ書込まれるに伴い実際の下層~fileに書込まれることになる — 例えば 巨大な~fileや~databaseの様なものに対する `in-place^en な改変を~supportするために)。 これは、 ~Chromeにおいては現時点では実装されてない。 その実装には,[ ~malware検査を走らすこと ]と[ 既存の巨大な~fileに対する `in-place^en な改変を~web~siteが高速に為せるようにすること ]が欲されているが、 現時点では,これらをどう組合せるか解明する所で阻まれている。 `in-place^en な書込nは、 `FileSystemSyncAccessHandle$I ~interfaceを介して[ `~bucket~file~system$内の~file ]用に可用になる。 ◎ See WICG/file-system-access issue #67 for discussion around and desire for a "inPlace" mode for createWritable (where changes will be written to the actual underlying file as they are written to the writer, for example to support in-place modification of large files or things like databases). This is not currently implemented in Chrome. Implementing this is currently blocked on figuring out how to combine the desire to run malware checks with the desire to let websites make fast in-place modifications to existing large files. In-place writes are available for files in a bucket file system via the FileSystemSyncAccessHandle interface.
`createWritable(options)@m ~method手続きは: ◎ The createWritable(options) method steps are:
- %~promise ~LET `新たな~promise$ ◎ Let result be a new promise.
- %~locator ~LET コレの`~locator$fsH ◎ Let locator be this's locator.
- %~realm ~LET コレに`関連な~realm$ ◎ Let realm be this's relevant Realm.
- %大域~obj ~LET コレに`関連な大域~obj$ ◎ Let global be this's relevant global object.
-
`~file~system~queue$に次の`手続きを~enqueueする$: ◎ Enqueue the following steps to the file system queue:
- %~entry ~LET `~entryを~locateする$( %~locator ) ◎ Let entry be the result of locating an entry given locator.
- %~access結果 ~LET %~entry の`要請~access$fE( `readwrite^l ) ◎ Let accessResult be the result of running entry’s request access given "readwrite".
-
~IF[ %~access結果 の`許可~状態$fsA ~NEQ `granted$l ] ⇒# `~storage~taskを~queueする$( %大域~obj, 次の手続き ); ~RET
手続きは ⇒ `~promiseを却下する$( %~promise, %~access結果 の`~error名$fsAを`名前$eXに伴う例外 )
◎ If accessResult’s permission state is not "granted", queue a storage task with global to reject result with a DOMException of accessResult’s error name and abort these steps. -
~IF[ %~entry ~EQ ~NULL ] ⇒# `~storage~taskを~queueする$( %大域~obj, 次の手続き ); ~RET
手続きは ⇒ `~promiseを却下する$( %~promise, `NotFoundError$E 例外 )
◎ If entry is null, queue a storage task with global to reject result with a "NotFoundError" DOMException and abort these steps. - ~Assert: %~entry は`~file~entry$fsである。 ◎ Assert: entry is a file entry.
- %~lock結果 ~LET `~lockを獲する$( %~entry, `共用^i ) ◎ Let lockResult be the result of taking a lock with "shared" on entry.
-
`~storage~taskを~queueする$( %大域~obj, 次の手続き ) ◎ Queue a storage task with global to\
手続きは: ◎ run these steps:
- ~IF[ %~lock結果 ~EQ `失敗^i ] ⇒# `~promiseを却下する$( %~promise, `NoModificationAllowedError$E 例外 ); ~RET ◎ If lockResult is "failure", reject result with a "NoModificationAllowedError" DOMException and abort these steps.
- %~stream ~LET `FileSystemWritableFileStream$I を`作成する$FSWFS( %~entry, %~realm ) ◎ Let stream be the result of creating a new FileSystemWritableFileStream for entry in realm.
- ~IF[ %options[ "`keepExistingData$mb" ] ~EQ ~T ] ⇒ %~stream の `buffer$sl ~SET %~entry の`~binary~data$fEの複製 ◎ If options["keepExistingData"] is true: • Set stream’s [[buffer]] to a copy of entry’s binary data.
- `~promiseを解決する$( %~promise, %~stream ) ◎ Resolve result with stream.
- ~RET %~promise ◎ Return result.
`createSyncAccessHandle()^m ~method
- %handle = await %fileHandle . `createSyncAccessHandle$m()
- ~file[ から読取る/へ書込む ]ために利用できる `FileSystemSyncAccessHandle$I を返す。 %handle を通して為された変更は、 即時には,[ %fileHandle の`~locator$fsHにより`~locatable$な`~file~entry$fs ]内に反映されるかもしれない。 %handle を書出す( `flush()$mS する)ことで、 この~file内に変更が反映されることを確保できる。 ◎ Returns a FileSystemSyncAccessHandle that can be used to read from/write to the file. Changes made through handle might be immediately reflected in the file entry locatable by fileHandle’s locator. To ensure the changes are reflected in this file, the handle can be flushed.
- `FileSystemSyncAccessHandle$I を作成すると、[ %fileHandle の`~locator$fsHにより`~locatable$な`~file~entry$fs ]に対する排他的な`~lockを獲する$。 これは、 当の~access~handleが~closeされるまで,当の~entry用の[ `FileSystemSyncAccessHandle$I / `FileSystemWritableFileStream$I ]の更なる作成を防止する。 ◎ Creating a FileSystemSyncAccessHandle takes an exclusive lock on the file entry locatable with fileHandle’s locator. This prevents the creation of further FileSystemSyncAccessHandles or FileSystemWritableFileStreams for the entry, until the access handle is closed.
- 返される `FileSystemSyncAccessHandle$I は、 同期的な~methodを提供する。 これは、 非同期的な演算に高い~overheadがつきまとう文脈(例:~WebAssembly)において, より高い処理能を許容する。 ◎ The returned FileSystemSyncAccessHandle offers synchronous methods. This allows for higher performance on contexts where asynchronous operations come with high overhead, e.g., WebAssembly.
- 当面の間は、 この~methodが成功するのは, %fileHandle が `ある~bucket~file~system内に在る$ときに限られる。 ◎ For the time being, this method will only succeed when the fileHandle is in a bucket file system.
`createSyncAccessHandle()@m ~method手続きは: ◎ The createSyncAccessHandle() method steps are:
- %~promise ~LET `新たな~promise$ ◎ Let result be a new promise.
- %~locator ~LET コレの`~locator$fsH ◎ Let locator be this's locator.
- %~realm ~LET コレに`関連な~realm$ ◎ Let realm be this's relevant Realm.
- %大域~obj ~LET コレに`関連な大域~obj$ ◎ Let global be this's relevant global object.
- %~bucket~file~system内に在るか ~LET ~IS[ コレは`ある~bucket~file~system内に在る$ ] ◎ Let isInABucketFileSystem be true if this is in a bucket file system; otherwise false.
-
`~file~system~queue$に次の`手続きを~enqueueする$: ◎ Enqueue the following steps to the file system queue:
- %~entry ~LET `~entryを~locateする$( %~locator ) ◎ Let entry be the result of locating an entry given locator.
- %~access結果 ~LET %~entry の`要請~access$fE( `readwrite^l ) ◎ Let accessResult be the result of running entry’s request access given "readwrite".
-
~IF[ %~access結果 の`許可~状態$fsA ~NEQ `granted$l ] ⇒# `~storage~taskを~queueする$( %大域~obj, 次の手続き ); ~RET
手続きは ⇒ `~promiseを却下する$( %~promise, %~access結果 の`~error名$fsAを`名前$eXに伴う例外 )
◎ If accessResult’s permission state is not "granted", queue a storage task with global to reject result with a DOMException of accessResult’s error name and abort these steps. -
~IF[ %~bucket~file~system内に在るか ~EQ ~F ] ⇒# `~storage~taskを~queueする$( %大域~obj, 次の手続き ); ~RET
手続きは ⇒ `~promiseを却下する$( %~promise, `InvalidStateError$E 例外 )
◎ If isInABucketFileSystem is false, queue a storage task with global to reject result with an "InvalidStateError" DOMException and abort these steps. -
~IF[ %~entry ~EQ ~NULL ] ⇒# `~storage~taskを~queueする$( %大域~obj, 次の手続き ); ~RET
手続きは ⇒ `~promiseを却下する$( %~promise, `NotFoundError$E 例外 )
◎ If entry is null, queue a storage task with global to reject result with a "NotFoundError" DOMException and abort these steps. - ~Assert: %~entry は`~file~entry$fsである。 ◎ Assert: entry is a file entry.
- %~lock結果 ~LET `~lockを獲する$( %~entry, `排他的^i ) ◎ Let lockResult be the result of taking a lock with "exclusive" on entry.
-
`~storage~taskを~queueする$( %大域~obj, 次の手続き ) ◎ Queue a storage task with global to\
手続きは: ◎ run these steps:
- ~IF[ %~lock結果 ~EQ `失敗^i ] ⇒# `~promiseを却下する$( %~promise, `NoModificationAllowedError$E 例外 ); ~RET ◎ If lockResult is "failure", reject result with a "NoModificationAllowedError" DOMException and abort these steps.
- %~handle ~LET %~realm に属する`新たな$ `FileSystemSyncAccessHandle$I 【!#create-a-new-filesystemsyncaccesshandle】 — その ⇒# `file$slS ~SET %~entry `state$slS ~SET `open^l ◎ Let handle be the result of creating a new FileSystemSyncAccessHandle for entry in realm.
- `~promiseを解決する$( %~promise, %~handle ) ◎ Resolve result with handle.
- ~RET %~promise ◎ Return result.
2.4. `FileSystemDirectoryHandle^I ~interface
dictionary `FileSystemGetFileOptions@I { `boolean$ `create@mb = false; }; dictionary `FileSystemGetDirectoryOptions@I { `boolean$ `~create0@mb = false; }; dictionary `FileSystemRemoveOptions@I { `boolean$ `recursive@mb = false; }; [`Exposed$=(Window,Worker), `SecureContext$, `Serializable$] interface `FileSystemDirectoryHandle@I : `FileSystemHandle$I { async iterable<`USVString$, `FileSystemHandle$I>; `Promise$<`FileSystemFileHandle$I> `getFileHandle$m(`USVString$ %name, optional `FileSystemGetFileOptions$I %options = {}); `Promise$<`FileSystemDirectoryHandle$I> `getDirectoryHandle$m(`USVString$ %name, optional `FileSystemGetDirectoryOptions$I %options = {}); `Promise$<`undefined$> `removeEntry$m(`USVString$ %name, optional `FileSystemRemoveOptions$I %options = {}); `Promise$<`sequence$<`USVString$>?> `resolve$m(`FileSystemHandle$I %possibleDescendant); };
注記: `FileSystemDirectoryHandle$I に結付けられた`~locator$fsHの`種類$lCは、 `directory$l になる。 ◎ Note: A FileSystemDirectoryHandle's associated locator's kind is "directory".
`子~directory~handleを作成する@ ときは、 所与の ( `~directory~locator$ %親~locator, 文字列 %名前, `~realm$ %~realm ) に対し:
- %子~path ~LET %親~locator の`~path$lCを`~cloneする$
- %子~path に %名前 を`付加する$
- ~RET `~directory~handleを作成する$( %親~locator の`根$lCの複製, %子~path, %~realm )
`~directory~handleを作成する@ ときは、 所与の ( `~file~system根$ %根, `~file~system~path$ %~path, `~realm$ %~realm ) に対し: ◎ To create a new FileSystemDirectoryHandle given a file system root root and a file system path path in a Realm realm:
- %~handle ~LET %~realm に属する`新たな$ `FileSystemDirectoryHandle$I ◎ Let handle be a new FileSystemDirectoryHandle in realm.
- %~handle の`~locator$fsH ~SET 新たな`~file~system~locator$ — その ⇒# `種類$lC ~SET `directory$l, `根$lC ~SET %根, `~path$lC ~SET %~path ◎ Set handle’s locator to a file system locator whose kind is "directory", root is root, and path is path.
- ~RET %~handle ◎ Return handle.
`FileSystemDirectoryHandle$I ~objは`直列化-可能$である。 その[ `直列化~手続き$, `逆直列化~手続き$ ]は、 `FileSystemHandle$I のそれらと同じとする。 ◎ FileSystemDirectoryHandle objects are serializable objects. Their serialization steps and deserialization steps are the same as those for FileSystemHandle.
2.4.1. ~directory反復
- for await (let [%name, %handle] of %directoryHandle) {}
- for await (let [%name, %handle] of %directoryHandle . entries()) {}
- for await (let %handle of %directoryHandle . values()) {}
- for await (let %name of %directoryHandle . keys()) {}
- ~entryのうち,その親は[ %directoryHandle の`~locator$fsHにより`~locatable$な`~directory~entry$fs ]であるものすべてを反復する。 反復の進捗-中に[ 作成された/削除された ]~entryは、 含まれるかもしれないし含まれないかもしれない — どちらになるかは,保証されない。 ◎ Iterates over all entries whose parent is the directory entry locatable by directoryHandle’s locator. Entries that are created or deleted while the iteration is in progress might or might not be included. No guarantees are given either way.
将来には、 当の`非同期に可反復な宣言$に引数を追加することが求まれるかもしれない — 例えば、 再帰的な反復を~supportするため。 ◎ In the future we might want to add arguments to the async iterable declaration to support for example recursive iteration.
`FileSystemDirectoryHandle$I %~handle 用の`非同期~反復子の初期化~手続き$は: ◎ The asynchronous iterator initialization steps for a FileSystemDirectoryHandle handle and its async iterator iterator are:
- %~handle の非同期c反復子の `過去の結果@ ~SET 新たな`有順序~集合$ ◎ Set iterator’s past results to an empty set.
`FileSystemDirectoryHandle$I %~handle 用の`次回の反復~結果を取得する$ ~algoは 【!and its async iterator iterator】: ◎ To get the next iteration result for a FileSystemDirectoryHandle handle and its async iterator iterator:
- %~promise ~LET `新たな~promise$ ◎ Let promise be a new promise.
-
`~file~system~queue$に次の`手続きを~enqueueする$: ◎ Enqueue the following steps to the file system queue:
- %~directory ~LET `~entryを~locateする$( %~handle の`~locator$fsH ) ◎ Let directory be the result of locating an entry given handle’s locator.
- %~access結果 ~LET %~directory の`~query~access$fE( `read^l ) ◎ Let accessResult be the result of running directory’s query access given "read".
-
`~storage~taskを~queueする$( %~handle に`関連な大域~obj$, 次の手続き ) ◎ Queue a storage task with handle’s relevant global object to\
手続きは: ◎ run these steps:
- ~IF[ %~access結果 の`許可~状態$fsA ~NEQ `granted$l ] ⇒# `~promiseを却下する$( %~promise, %~access結果 の`~error名$fsAを`名前$eXに伴う例外 ); ~RET ◎ If accessResult’s permission state is not "granted", reject promise with a DOMException of accessResult’s error name and abort these steps.:
- ~IF[ %~directory ~EQ ~NULL ] ⇒# `~promiseを却下する$( %~promise, `NotFoundError$E 例外 ); ~RET ◎ If directory is null, reject result with a "NotFoundError" DOMException and abort these steps.
- ~Assert: %~directory は`~directory~entry$fsである ◎ Assert: directory is a directory entry.
-
%子 ~LET %~directory の`子~群$fEを成す`~file~system~entry$のうち[ その`名前$fE ~NIN %~handle の非同期c反復子の`過去の結果$ ]を満たすものは[ 在るならば,それらのうちいずれか / 無いならば ~NULL ] ◎ Let child be a file system entry in directory’s children, such that child’s name is not contained in iterator’s past results, or null if no such entry exists.
注記: これは、 【`子~群$fEに対する】 反復~順序について意図的に ごく曖昧である。 反復~順序に対し供される保証は、 ~platformや~file~systemに応じて異なり,[ すべての~platformで効率的に実装することがアリになる ]ことが求まれる。 そのようなわけで、 反復される【!in which elements are returned】正確な順序に関する保証は与えられない。 ◎ Note: This is intentionally very vague about the iteration order. Different platforms and file systems provide different guarantees about iteration order, and we want it to be possible to efficiently implement this on all platforms. As such no guarantees are given about the exact order in which elements are returned.
-
~IF[ %子 ~EQ ~NULL ]:
- `~promiseを解決する$( %~promise )
- ~RET
- %~handle の非同期c反復子の`過去の結果$に %子 の`名前$fEを`付加する$set ◎ Append child’s name to iterator’s past results.
-
%結果 ~LET %子 に応じて: ◎ ↓
- `~file~entry$fsである ⇒ `子~file~handleを作成する$( %~handle の`~locator$fsH, %子 の`名前$fE, %~handle に`関連な~realm$ ) ◎ If child is a file entry: • Let result be the result of creating a child FileSystemFileHandle with handle’s locator and child’s name in handle’s relevant Realm.
- `~directory~entry$fsである ⇒ `子~directory~handleを作成する$( %~handle の`~locator$fsH, %子 の`名前$fE, %~handle に`関連な~realm$ ) ◎ Otherwise: • Let result be the result of creating a child FileSystemDirectoryHandle with handle’s locator and child’s name in handle’s relevant Realm.
- `~promiseを解決する$( %~promise, ( %子 の`名前$fE, %結果 ) ) ◎ Resolve promise with (child’s name, result).
- ~RET %~promise ◎ Return promise.
`getFileHandle()^m ~method
- %fileHandle = await %directoryHandle . `getFileHandle(name)$m
- %fileHandle = await %directoryHandle . `getFileHandle$m(%name, { `create$mb: false })
- [ %directoryHandle の`~locator$fsHにより`~locatable$な`~directory~entry$fs ]内の[ %name を名前に伴う~file ]用の~handleを返す。 そのような~fileが存在しない場合、 ~promiseは却下される。 ◎ Returns a handle for a file named name in the directory entry locatable by directoryHandle’s locator. If no such file exists, this rejects.
- %fileHandle = await %directoryHandle . `getFileHandle$m(%name, { `create$mb: true })
-
[ %directoryHandle の`~locator$fsHにより`~locatable$な`~directory~entry$fs ]内の[ %name を名前に伴う~file ]用の~handleを返す。 そのような~fileが存在しない場合、 新たな~fileが作成される — 作成できなかった場合、 ~promiseは却下される。 作成が失敗し得る原因として,次が挙げられる: ◎ Returns a handle for a file named name in the directory entry locatable by directoryHandle’s locator. If no such file exists, this creates a new file. If no file with named name can be created this rejects. Creation can fail\
- 同じ名前を伴う~directoryがすでに在る ◎ because there already is a directory with the same name,\
- 当の名前は[ 下層の~file~systemの~file名においては~supportされない文字 ]を利用している ◎ because the name uses characters that aren’t supported in file names on the underlying file system,\
- ~UAは~securityの理由から当の~fileの作成を許容しないものと裁定した ◎ or because the user agent for security reasons decided not to allow creation of the file.
- この演算は、 対象の~fileが存在していても,書込n許可を要求する。 この~handleが書込n許可をまだ得ていない場合、 利用者に~promptを示す結果にもなり得る。 書込n許可を必要することなく,既存の~fileを取得するためには、 `create$mb を ~F にして【!with { create: false }】, この~methodを~callすること。 ◎ This operation requires write permission, even if the file being returned already exists. If this handle doesn’t already have write permission, this could result in a prompt being shown to the user. To get an existing file without needing write permission, call this method with { create: false }.
`getFileHandle(name, options)@m ~method手続きは: ◎ The getFileHandle(name, options) method steps are:
- %~promise ~LET `新たな~promise$ ◎ Let result be a new promise.
- %~realm ~LET コレに`関連な~realm$ ◎ Let realm be this's relevant Realm.
- %~locator ~LET コレの`~locator$fsH ◎ Let locator be this's locator.
- %大域~obj ~LET コレに`関連な大域~obj$ ◎ Let global be this's relevant global object.
-
`~file~system~queue$に次の`手続きを~enqueueする$: ◎ Enqueue the following steps to the file system queue:
-
~IF[ %name は`妥当な~file名$でない ] ⇒# `~storage~taskを~queueする$( %大域~obj, 次の手続き ); ~RET
手続きは ⇒ `~promiseを却下する$( %~promise, `TypeError$E )
◎ If name is not a valid file name, queue a storage task with global to reject result with a TypeError and abort these steps. - %~entry ~LET `~entryを~locateする$( %~locator ) ◎ Let entry be the result of locating an entry given locator.
- %~access結果 ~LET %options[ "`create$mb" ] に応じて ⇒# ~T ならば %~entry の`要請~access$fE( `readwrite^l ) / ~F ならば %~entry の`要請~access$fE( `read^l ) ◎ If options["create"] is true: • Let accessResult be the result of running entry’s request access given "readwrite". ◎ Otherwise: • Let accessResult be the result of running entry’s query access given "read".
-
`~storage~taskを~queueする$( %大域~obj, 次の手続き ) ◎ Queue a storage task with global to\
手続きは: ◎ run these steps:
- ~IF[ %~access結果 の`許可~状態$fsA ~NEQ `granted$l ] ⇒# `~promiseを却下する$( %~promise, %~access結果 の`~error名$fsAを`名前$eXに伴う例外 ); ~RET ◎ If accessResult’s permission state is not "granted", reject result with a DOMException of accessResult’s error name and abort these steps.
- ~IF[ %~entry ~EQ ~NULL ] ⇒# `~promiseを却下する$( %~promise, `NotFoundError$E 例外 ); ~RET ◎ If entry is null, reject result with a "NotFoundError" DOMException and abort these steps.
- ~Assert: %~entry は`~directory~entry$fsである。 ◎ Assert: entry is a directory entry.
- %~file~entry ~LET ε ◎ ↓
-
%~entry の`子~群$fEを成す ~EACH( %子 ) に対し:
- ~IF[ %子 の`名前$fE ~NEQ %name ] ⇒ ~CONTINUE
- ~IF[ %子 は`~directory~entry$fsである ] ⇒# `~promiseを却下する$( %~promise, `TypeMismatchError$E 例外 ); ~RET
- %~file~entry ~SET %子
- ~BREAK
-
~IF[ %~file~entry ~EQ ε ]: ◎ ↑
- ~IF[ %options[ "`create$mb" ] ~EQ ~F ] ⇒# `~promiseを却下する$( %~promise, `NotFoundError$E 例外 ); ~RET ◎ If options["create"] is false: • Reject result with a "NotFoundError" DOMException and abort these steps.
- %~file~entry ~LET 新たな`~file~entry$fs — その ⇒# `~query~access$fE ~SET %~entry の`~query~access$fE, `要請~access$fE ~SET %~entry の`要請~access$fE, `名前$fE ~SET %name `~binary~data$fE ~SET 空な`~byte列$ `改変~時刻印$fE ~SET 現在の時刻 ◎ Let child be a new file entry whose query access and request access algorithms are those of entry. ◎ Set child’s name to name. ◎ Set child’s binary data to an empty byte sequence. ◎ Set child’s modification timestamp to the current time.
-
下層の~file~system内で %~entry の子として %~file~entry を作成するよう試みる — 例外が投出された場合、 ~catchして ⇒ `~promiseを却下する$( %~promise, その例外 ) ◎ ↓ Append child to entry’s children. ◎ If creating child in the underlying file system throws an exception, reject result with that exception and abort these steps.
これが投出し得る例外として何がアリか,もっと良く指定する。 ◎ Better specify what possible exceptions this could throw.
- %~entry の`子~群$fEに %~file~entry を`付加する$set ◎ ↑
- %~handle ~LET `子~file~handleを作成する$( %~locator, %name【!%~file~entry の`名前$fE】, %~realm ) ◎ Resolve result with the result of creating a child FileSystemFileHandle with locator and child’s name in realm.
- `~promiseを解決する$( %~promise, %~handle ) ◎ ↑
-
- ~RET %~promise ◎ Return result.
`getDirectoryHandle()^m ~method
- %subdirHandle = await %directoryHandle . `getDirectoryHandle(name)$m
- %subdirHandle = await %directoryHandle . `getDirectoryHandle$m(%name, { `~create0$mb: false })
- [ %directoryHandle の`~locator$fsHにより`~locatable$な`~directory~entry$fs ]内の[ %name を名前に伴う~directory ]用の~handleを返す。 そのような~directoryは存在しない場合、 ~promiseは却下される。 ◎ Returns a handle for a directory named name in the directory entry locatable by directoryHandle’s locator. If no such directory exists, this rejects.
- %subdirHandle = await %directoryHandle . `getDirectoryHandle$m(%name, { `~create0$mb: true })
-
[ %directoryHandle の`~locator$fsHにより`~locatable$な`~directory~entry$fs ]内の[ %name を名前に伴う~directory ]用の~handleを返す。 そのような~directoryは存在しない場合、 新たな~directoryが作成される — 作成できなかった場合、 ~promiseは却下される。 作成が失敗し得る原因として,次が挙げられる: ◎ Returns a handle for a directory named name in the directory entry locatable by directoryHandle’s locator . If no such directory exists, this creates a new directory. If creating the directory failed, this rejects. Creation can fail\
- 同じ名前を伴う~fileがすでに在る ◎ because there already is a file with the same name,\
- 当の名前は[ 下層の~file~systemの~file名においては~supportされない文字 ]を利用している ◎ or because the name uses characters that aren’t supported in file names on the underlying file system.
- この演算は、 対象の~directoryがすでに存在する場合でも,書込n許可を要求する。 この~handleが書込n許可をまだ得ていない場合、 利用者に~promptを示す結果にもなり得る。 書込n許可を必要とすることなく 既存の~directoryを取得するためには、 `~create0$mb を ~F にして【!with { create: false }】, この~methodを~callすること。 ◎ This operation requires write permission, even if the directory being returned already exists. If this handle doesn’t already have write permission, this could result in a prompt being shown to the user. To get an existing directory without needing write permission, call this method with { create: false }.
`getDirectoryHandle(name, options)@m ~method手続きは: ◎ The getDirectoryHandle(name, options) method steps are:
- %~promise ~LET `新たな~promise$ ◎ Let result be a new promise.
- %~realm ~LET コレに`関連な~realm$ ◎ Let realm be this's relevant Realm.
- %~locator ~LET コレの`~locator$fsH ◎ Let locator be this's locator.
- %大域~obj ~LET コレに`関連な大域~obj$ ◎ Let global be this's relevant global object.
-
`~file~system~queue$に次の`手続きを~enqueueする$: ◎ Enqueue the following steps to the file system queue:
-
~IF[ %name は`妥当な~file名$でない ] ⇒# `~storage~taskを~queueする$( %大域~obj, 次の手続き ); ~RET
手続きは ⇒ `~promiseを却下する$( %~promise, `TypeError$E )
◎ If name is not a valid file name, queue a storage task with global to reject result with a TypeError and abort these steps. - %~entry ~LET `~entryを~locateする$( %~locator ) ◎ Let entry be the result of locating an entry given locator.
- %~access結果 ~LET %options[ "`~create0$mb" ] に応じて ⇒# ~T ならば %~entry の`要請~access$fE( `readwrite^l ) / ~F ならば %~entry の`要請~access$fE( `read^l ) ◎ If options["create"] is true: • Let accessResult be the result of running entry’s request access given "readwrite". ◎ Otherwise: • Let accessResult be the result of running entry’s query access given "read".
-
`~storage~taskを~queueする$( %大域~obj, 次の手続き ) ◎ Queue a storage task with global to\
手続きは: ◎ run these steps:
- ~IF[ %~access結果 の`許可~状態$fsA ~NEQ `granted$l ] ⇒# `~promiseを却下する$( %~promise, %~access結果 の`~error名$fsAを`名前$eXに伴う例外 ); ~RET ◎ If accessResult’s permission state is not "granted", reject result with a DOMException of accessResult’s error name and abort these steps.
- ~IF[ %~entry ~EQ ~NULL ] ⇒# `~promiseを却下する$( %~promise, `NotFoundError$E 例外 ); ~RET ◎ If entry is null, reject result with a "NotFoundError" DOMException and abort these steps.
- ~Assert: %~entry は`~directory~entry$fsである。 ◎ Assert: entry is a directory entry.
- %~directory~entry ~LET ε ◎ ↓
-
%~entry の`子~群$fEを成す ~EACH( %子 ) に対し:
- ~IF[ %子 の`名前$fE ~NEQ %name ] ⇒ ~CONTINUE
- ~IF[ %子 は`~file~entry$fsである ] ⇒# `~promiseを却下する$( %~promise, `TypeMismatchError$E 例外 ); ~RET
- %~directory~entry ~SET %子
- ~BREAK
-
~IF[ %~directory~entry ~EQ ε ]: ◎ ↑
- ~IF[ %options[ "`~create0$mb" ] ~EQ ~F ] ⇒# `~promiseを却下する$( %~promise, `NotFoundError$E 例外 ); ~RET ◎ If options["create"] is false: • Reject result with a "NotFoundError" DOMException and abort these steps.
- %~directory~entry ~LET 新たな`~directory~entry$fs — その ⇒# `~query~access$fE ~SET %~entry の`~query~access$fE, `要請~access$fE ~SET %~entry の`要請~access$fE, `名前$fE ~SET %name, `子~群$fE ~SET 新たな`有順序~集合$ ◎ Let child be a new directory entry whose query access and request access algorithms are those of entry. ◎ Set child’s name to name. ◎ Set child’s children to an empty set.
-
下層の~file~system内で %~entry の子として %~directory~entry を作成するよう試みる — 例外が投出された場合、 ~catchして ⇒ `~promiseを却下する$( %~promise, その例外 ) ◎ ↓ Append child to entry’s children. ◎ If creating child in the underlying file system throws an exception, reject result with that exception and abort these steps.
これが投出し得る例外として何がアリか,もっと良く指定する。 ◎ Better specify what possible exceptions this could throw.
- %~entry の`子~群$fEに %~directory~entry を`付加する$set ◎ ↑
- %~handle ~LET `子~directory~handleを作成する$( %~locator, %name【! %~directory~entry の`名前$fE】, %~realm ) ◎ Resolve result with the result of creating a child FileSystemDirectoryHandle with locator and child’s name in realm.
- `~promiseを解決する$( %~promise, %~handle ) ◎ ↑
-
- ~RET %~promise ◎ Return result.
`removeEntry()^m ~method
- await %directoryHandle . `removeEntry(name)$m
- await %directoryHandle . `removeEntry$m(%name, { `recursive$mb: false })
- [ %directoryHandle の`~locator$fsHにより`~locatable$な`~directory~entry$fs ]内の[ %name を名前に伴う[ ~file / 空な~directory ]]を削除しようと試みる。 ◎ If the directory entry locatable by directoryHandle’s locator contains a file named name, or an empty directory named name, this will attempt to delete that file or directory.
- 存在しない[ ~file/~directory ]を削除しようと試みることは、 成功と見なされる。 一方で,空でない~directoryを削除しようと試みた場合、 ~promiseは却下される。 ◎ Attempting to delete a file or directory that does not exist is considered success, while attempting to delete a non-empty directory will result in a promise rejection.
- await %directoryHandle . `removeEntry$m(%name, { `recursive$mb: true })
- [ %directoryHandle の`~locator$fsHにより`~locatable$な`~directory~entry$fs ]内の[ %name を名前に伴う`~file~system~entry$ ]を除去する。 その~entryは~directoryである場合、 その内容も再帰的に削除されることになる。 ◎ Removes the file system entry named name in the directory entry locatable by directoryHandle’s locator. If that entry is a directory, its contents will also be deleted recursively.
- 存在しない[ ~file/~directory ]を削除しようと試みることは、 成功と見なされる。 ◎ Attempting to delete a file or directory that does not exist is considered success.
`removeEntry(name, options)@m ~method手続きは: ◎ The removeEntry(name, options) method steps are:
- %~promise ~LET `新たな~promise$ ◎ Let result be a new promise.
- %~locator ~LET コレの`~locator$fsH ◎ Let locator be this's locator.
- %大域~obj ~LET コレに`関連な大域~obj$ ◎ Let global be this's relevant global object.
-
`~file~system~queue$に次の`手続きを~enqueueする$: ◎ Enqueue the following steps to the file system queue:
-
~IF[ %name は`妥当な~file名$でない ] ⇒# `~storage~taskを~queueする$( %大域~obj, 次の手続き ); ~RET
手続きは ⇒ `~promiseを却下する$( %~promise, `TypeError$E )
◎ If name is not a valid file name, queue a storage task with global to reject result with a TypeError and abort these steps. - %~entry ~LET `~entryを~locateする$( %~locator ) ◎ Let entry be the result of locating an entry given locator.
- %~access結果 ~LET %~entry の`要請~access$fE( `readwrite^l ) ◎ Let accessResult be the result of running entry’s request access given "readwrite".
-
`~storage~taskを~queueする$( %大域~obj, 次の手続き ) ◎ Queue a storage task with global to\
手続きは: ◎ run these steps:
- ~IF[ %~access結果 の`許可~状態$fsA ~NEQ `granted$l ] ⇒# `~promiseを却下する$( %~promise, %~access結果 の`~error名$fsAを`名前$eXに伴う例外 ); ~RET ◎ If accessResult’s permission state is not "granted", reject result with a DOMException of accessResult’s error name and abort these steps.
- ~IF[ %~entry ~EQ ~NULL ] ⇒# `~promiseを却下する$( %~promise, `NotFoundError$E 例外 ); ~RET ◎ If entry is null, reject result with a "NotFoundError" DOMException and abort these steps.
- ~Assert: %~entry は`~directory~entry$fsである。 ◎ Assert: entry is a directory entry.
-
%~entry の`子~群$fEを成す ~EACH( %子 ) に対し: ◎ For each child of entry’s children:
- ~IF[ %子 の`名前$fE ~NEQ %name ] ⇒ ~CONTINUE ◎ If child’s name equals name:
- ~IF[ %子 は`~directory~entry$fsである ]~AND[ %子 の`子~群$fEは`空$でない ]~AND[ %options[ "`recursive$mb" ] ~EQ ~F ] ⇒# `~promiseを却下する$( %~promise, `InvalidModificationError$E 例外 ); ~RET ◎ If child is a directory entry: • If child’s children is not empty and options["recursive"] is false: •• Reject result with an "InvalidModificationError" DOMException and abort these steps.
-
下層の~file~system内で %~entry の子 %子 を除去するよう試みる — 例外が投出された場合、 ~catchして ⇒ `~promiseを却下する$( %~promise, その例外 ) ◎ Remove child from entry’s children. ◎ If removing child in the underlying file system throws an exception, reject result with that exception and abort these steps.
注記: [ `recursive$mb ~EQ ~T ]の場合、 除去は~~途中で失敗し得る — 一部の[ ~file/~directory ]だけ除去され,他は残されるかもしれない。 ◎ Note: If recursive is true, the removal can fail non-atomically. Some files or directories might have been removed while other files or directories still exist.
これが投出し得る例外として何がアリか,もっと良く指定する。 ◎ Better specify what possible exceptions this could throw.
- %~entry の`子~群$fEから %子 を`除去する$ ◎ ↑
- `~promiseを解決する$( %~promise ) ◎ Resolve result with undefined.
- ~RET 【この段は、この訳による補完。】
- `~promiseを却下する$( %~promise, `NotFoundError$E 例外 ) ◎ Reject result with a "NotFoundError" DOMException.
-
- ~RET %~promise ◎ Return result.
`resolve()^m ~method
- %path = await %directory . `resolve$m( %child )
- %child と %directory は等しい【`同一-~path$である】場合、 %path は空な配列になる。 ◎ If child is equal to directory, path will be an empty array.
- %child は %directory の【!直な】子である場合、 %path は %child の名前のみを包含している配列になる。 ◎ If child is a direct child of directory, path will be an array containing child’s name.
- %child は %directory の【子ではないが】子孫である場合、 %path は[ %directory から %child までの合間にある各~directoryの名前, および最後の要素として %child の名前 ]を包含している配列になる。 例えば、 %directory は `/home/user/project^c を表現していて, %child は `/home/user/project/foo/bar^c を表現している場合、 « `foo^l, `bar^l » が返される。 ◎ If child is a descendant of directory, path will be an array containing the names of all the intermediate directories and child’s name as last element. For example if directory represents /home/user/project and child represents /home/user/project/foo/bar, this will return ['foo', 'bar'].
- 他の場合 ( %child と %directory は無関係である)、 %path は ~NULL になる。 ◎ Otherwise (directory and child are not related), path will be null.
/* ここまでに妥当な~directory~handleが取得されたと見做す。 ◎ Assume we at some point got a valid directory handle. */ const %dir_ref = %current_project_dir; if (!%dir_ref) return; /* ~file参照を取得する: ◎ Now get a file reference: */ const %file_ref = await %dir_ref.getFileHandle(filename, { create: true }); /* %dir_ref の内側に %file_ref が存在するか否か検査する: ◎ Check if file_ref exists inside dir_ref: */ const %relative_path = await %dir_ref.resolve(%file_ref); if (%relative_path === null) { /* %dir_ref の内側でない ◎ Not inside dir_ref. */ } else { /* %relative_path は、 名前たちが成す配列であり,相対~pathを与えている。 ◎ relative_path is an array of names, giving the relative path */ /* %dir_ref から %file_ref までにより表現される~file: ◎ from dir_ref to the file that is represented by file_ref: */ assert %relative_path.pop() === %file_ref.name; let %entry = %dir_ref; for (const %name of %relative_path) { %entry = await %entry.getDirectory(%name); } %entry = await %entry.getFile(%file_ref.name); /* %entry は、 今や,~disk上の %file_ref と同じ~fileを表現することになる。 ◎ Now |entry| will represent the same file on disk as |file_ref|. */ assert await %entry.isSameEntry(%file_ref) === true; }
`resolve(possibleDescendant)@m ~method手続きは ⇒ ~RET `~locatorを根に相対的に解決する$( %possibleDescendant, コレの`~locator$fsH ) ◎ The resolve(possibleDescendant) method steps are to return the result of resolving possibleDescendant’s locator relative to this's locator.
2.5. `FileSystemWritableFileStream^I ~interface
enum `WriteCommandType@I { `write@l, `seek@l, `truncate@l, }; dictionary `WriteParams@I { required `WriteCommandType$I `type@mb; `unsigned long long$? `size@mb; `unsigned long long$? `position@mb; (`BufferSource$I or `Blob$I or `USVString$)? `data@mb; }; typedef (`BufferSource$I or `Blob$I or `USVString$ or `WriteParams$I) `FileSystemWriteChunkType@I; [`Exposed$=(Window,Worker), `SecureContext$] interface `FileSystemWritableFileStream@I : `WritableStream$I { `Promise$<`undefined$> `write$m(`FileSystemWriteChunkType$I %data); `Promise$<`undefined$> `seek$m(`unsigned long long$ %position); `Promise$<`undefined$> `truncate$m(`unsigned long long$ %size); };
各 `FileSystemWritableFileStream$I ~objには、 次に挙げるものが結付けられる ◎ ↓
- `file@sl ⇒ ある`~file~entry$fs 【作成-時に設定される。】 ◎ A FileSystemWritableFileStream has an associated [[file]] (a file entry).
-
`buffer@sl ⇒ `~byte列$ — 初期~時は空とする。 ◎ A FileSystemWritableFileStream has an associated [[buffer]] (a byte sequence). It is initially empty.
注記: この~bufferは,任意に巨大になり得るので、 実装は,[ この~bufferを~memory内に保たない代わりに, この~buffer用に一時的な~fileを利用する ]ようになるものと期待される。 `buffer^sl へのすべての~accessは~promiseを返す[ ~method/~algo ]内で行われるので、 実装は,それに対する演算を — それが同期cに見える場合でも — 非同期cな演算として実装できる。 ◎ Note: This buffer can get arbitrarily large, so it is expected that implementations will not keep this in memory, but instead use a temporary file for this. All access to [[buffer]] is done in promise returning methods and algorithms, so even though operations on it seem sync, implementations can implement them async.
- `seekOffset@sl ⇒ 整数 — 初期~時は 0 とする。 ◎ A FileSystemWritableFileStream has an associated [[seekOffset]] (a number). It is initially 0.
注記: `FileSystemWritableFileStream$I ~objは, `WritableStream$I ~objであるが、 ~disk上の単独の~fileに対し演算する便利~methodを追加的に伴う。 ◎ A FileSystemWritableFileStream object is a WritableStream object with additional convenience methods, which operates on a single file on disk.
作成に際しては、 ある`下層~sink$が作成され,当の~streamは利用-可能になる。 当の~stream上で実行される演算は,すべて~queue可能になり、 `生産器$は,`背圧$に応答-可能になる。 ◎ Upon creation, an underlying sink will have been created and the stream will be usable. All operations executed on the stream are queuable and producers will be able to respond to backpressure.
`下層~sink$の書込n~method — したがって, `WritableStreamDefaultWriter$I の `write()@~STREAMS#default-writer-write$m ~method — は、 入力として[ ~byte列に類する~data/ `WriteParams$I ]を受容する。 ◎ The underlying sink’s write method, and therefore WritableStreamDefaultWriter’s write() method, will accept byte-like data or WriteParams as input.
`FileSystemWritableFileStream$I は、 ~file位置~cursorを有する — それは、 当の~fileの先頭からの~byte数による~offsetであり, 0 に初期化される。 この位置は、[ `write()$m を利用しているとき / `WritableStreamDefaultWriter$I の `write()@~STREAMS#default-writer-write$m ~method を通して `WritableStream$I の能力を利用することにより ],当の~stream~objを通して書込まれた~byte数に基づいて先へ進むことになる。 ◎ The FileSystemWritableFileStream has a file position cursor initialized at byte offset 0 from the top of the file. When using write() or by using WritableStream capabilities through the WritableStreamDefaultWriter’s write() method, this position will be advanced based on the number of bytes written through the stream object.
類似に, `ReadableStream$I を `FileSystemWritableFileStream$I ~objの中へ~pipeしたときは、 この位置は,当の~streamを通して渡された~byte数で更新される。 ◎ Similarly, when piping a ReadableStream into a FileSystemWritableFileStream object, this position is updated with the number of bytes that passed through the stream.
`getWriter()$m は、 `WritableStreamDefaultWriter$I の~instanceを返す。 ◎ getWriter() returns an instance of WritableStreamDefaultWriter.
`FileSystemWritableFileStream$I を `作成する@FSWFS ときは、 所与の ( `~file~entry$fs %~file, `~realm$ %~realm ) に対し: ◎ To create a new FileSystemWritableFileStream given a file entry file in a Realm realm:
- %~stream ~LET %~realm に属する`新たな$ `FileSystemWritableFileStream$I — その ⇒ `file$sl ~SET %~file ◎ Let stream be a new FileSystemWritableFileStream in realm. ◎ Set stream’s [[file]] to file.
-
%~stream を`設定しておく$WS — 次を与える下で: ◎ ↓↓
- `書込n~algo^i ~SET 所与の ( %~chunk ) に対し,次を走らす手続き ⇒ ~RET `~chunkを書込む$( %~stream, %~chunk ) ◎ Let writeAlgorithm be an algorithm which takes a chunk argument and returns the result of running the write a chunk algorithm with stream and chunk.
-
`~close~algo^i ~SET 次の手続き: ◎ Let closeAlgorithm be these steps:
- %~close結果 ~LET `新たな~promise$ ◎ Let closeResult be a new promise.
-
`~file~system~queue$に次の`手続きを~enqueueする$: ◎ Enqueue the following steps to the file system queue:
- %~access結果 ~LET %~file の`~query~access$fE( `readwrite^l ) ◎ Let accessResult be the result of running file’s query access given "readwrite".
-
`~storage~taskを~queueする$( %~file に`関連な大域~obj$, 次の手続き ) ◎ Queue a storage task with file’s relevant global object to run these steps:
手続きは: ◎ run these steps:
-
~IF[ %~access結果 の`許可~状態$fsA ~NEQ `granted$l ]:
- %~access結果 の`~error名$fsAを`名前$eXに伴う例外で %~close結果 を却下する
- ~RET
-
`実装定義$な[ ~malware走査, 安全な閲覧 ]用の検査を走らす ◎ Run implementation-defined malware scans and safe browsing checks.\
~IF[ これらの検査に失敗した ] ⇒# `~promiseを却下する$( %~close結果, `AbortError$E 例外 ); ~RET ◎ If these checks fail, reject closeResult with an "AbortError" DOMException and abort these steps.
-
%~stream の `file$sl の`~binary~data$fE ~SET %~stream の `buffer$sl ◎ Set stream’s [[file]]'s binary data to stream’s [[buffer]].\
例外が投出された場合、 ~catchして ⇒# `~promiseを却下する$( %~close結果, その例外 ); ~RET ◎ If that throws an exception, reject closeResult with that exception and abort these steps.
注記: これは、 書込まれている~disk上の当の~fileの内容を不可分的に更新することが期待される。 ◎ Note: It is expected that this atomically updates the contents of the file on disk being written to.
-
`~file~system~queue$に次の`手続きを~enqueueする$: ◎ Enqueue the following steps to the file system queue:
- `~lockを解放する$( %~stream の `file$sl ) ◎ Release the lock on stream’s [[file]].
-
`~storage~taskを~queueする$( %~file に`関連な大域~obj$, 次の手続き )
手続きは ⇒ `~promiseを解決する$( %~close結果 )
◎ Queue a storage task with file’s relevant global object to resolve closeResult with undefined.
-
- ~RET %~close結果 ◎ Return closeResult.
-
`中止-~algo^i ~SET 次の手続き: ◎ Let abortAlgorithm be these steps:
- `~file~system~queue$に次の`手続きを~enqueueする$ ⇒ `~lockを解放する$( %~stream の`file$sl ) ◎ Enqueue this step to the file system queue: • Release the lock on stream’s [[file]].
- `限界水位^i ~SET 1 ◎ Let highWaterMark be 1.
- `~size~algo^i ~SET 次の手続き ⇒ ~RET 1 ◎ Let sizeAlgorithm be an algorithm that returns 1.
- ~RET %~stream ◎ ↑↑ Set up stream with writeAlgorithm set to writeAlgorithm, closeAlgorithm set to closeAlgorithm, abortAlgorithm set to abortAlgorithm, highWaterMark set to highWaterMark, and sizeAlgorithm set to sizeAlgorithm. ◎ Return stream.
`~chunkを書込む@ ときは、 所与の ( `FileSystemWritableFileStream$I %~stream, %~chunk ) に対し,次の手続きを走らす: ◎ The write a chunk algorithm, given a FileSystemWritableFileStream stream and chunk, runs these steps:
【 この~algoは、 %~stream を`作成する$FSWFS間に %~stream を`設定しておく$WSための引数として利用される — `FileSystemWritableFileStream$I の各~methodは、 それを介して この~algoを呼出すことになる。 】
-
%入力 ~LET `~IDL値に変換する$( %~chunk, `FileSystemWriteChunkType$I ) ◎ Let input be the result of converting chunk to a FileSystemWriteChunkType.\
例外が投出された場合、 ~catchして ⇒ ~RET `却下される~promise$( その例外 ) ◎ If this throws an exception, then return a promise rejected with that exception.
-
( %~command, %~data, %位置, %~size ) ~LET %入力 に応じて:
- `WriteParams$I であるならば ⇒ ( %入力[ "`type$mb" ], %入力[ "`data$mb" ], %入力[ "`position$mb" ], %入力[ "`size$mb" ] )
- ~ELSE_ ⇒ ( `write$l, %入力, ε, ε )
- %~promise ~LET `新たな~promise$ ◎ Let p be a new promise.
-
`~file~system~queue$に次の`手続きを~enqueueする$: ◎ Enqueue the following steps to the file system queue:
- %~access結果 ~LET %~stream の `file$sl の`~query~access$fE( `readwrite^l ) ◎ Let accessResult be the result of running stream’s [[file]]'s query access given "readwrite".
-
`~storage~taskを~queueする$( %~stream に`関連な大域~obj$, 次の手続き ) ◎ Queue a storage task with stream’s relevant global object to run these steps:
手続きは: ◎ run these steps:
- ~IF[ %~access結果 の`許可~状態$fsA ~NEQ `granted$l ] ⇒# `~promiseを却下する$( %~promise, %~access結果 の`~error名$fsAを`名前$eXに伴う例外 ); ~RET ◎ If accessResult’s permission state is not "granted", reject p with a DOMException of accessResult’s error name and abort these steps.
-
~IF[ %~command ~EQ `write$l ]: ◎ ↑↑ Let command be input["type"] if input is a dictionary; otherwise "write". ◎ If command is "write":
- ~IF[ %入力 ~EQ `undefined^jv ]~OR[ %~data ~IN { ~NULL, ε } ] ⇒# `~promiseを却下する$( %~promise, `TypeError$E ); ~RET ◎ If input is undefined or input is a dictionary and input["data"] does not exist, reject p with a TypeError and abort these steps.
- %書込n位置 ~LET %~stream の `seekOffset$sl ◎ ↑↑ Let data be input["data"] if input is a dictionary; otherwise input. ◎ Let writePosition be stream’s [[seekOffset]].
- ~IF[ %位置 ~NIN { ~NULL, ε } ] ⇒ %書込n位置 ~SET %位置 ◎ If input is a dictionary and input["position"] exists, set writePosition to input["position"].
- %旧-~size ~LET %~stream の `buffer$sl の`長さ$byte ◎ Let oldSize be stream’s [[buffer]]'s length.
-
%~data~byte列 ~LET %~data の型に応じて: ◎ ↓
- `BufferSource$I である ⇒ %~data に`保持された~byte列の複製を取得する$ ◎ If data is a BufferSource, let dataBytes be a copy of data.
-
`Blob$I である ⇒ `読取n演算$( %~data 【, `BinaryString^i 】 ) ◎ Otherwise, if data is a Blob: • Let dataBytes be the result of performing the read operation on data.\
例外が投出された場合、 ~catchして ⇒# `~promiseを却下する$( %~promise, その例外 ); ~RET ◎ If this throws an exception, reject p with that exception and abort these steps.
- その他( `USVString^c である) ⇒ `~UTF-8符号化する$( %~data ) ◎ Otherwise: • Assert: data is a USVString. • Let dataBytes be the result of UTF-8 encoding data.
-
~IF[ %書込n位置 ~GT %旧-~size ] ⇒ %~stream の `buffer$sl の末尾に ( %書込n位置 ~MINUS %旧-~size ) 個の`~NUL~byte$を付加する ◎ If writePosition is larger than oldSize, append writePosition - oldSize 0x00 (NUL) bytes to the end of stream’s [[buffer]].
注記: 実装には[ ~file内容の末尾が~~実際に`~NUL~byte$たちで埋められた ]かのように挙動することが期待される。 それは、 これらの~byteが実際に~diskに書込まれ, ~disk空間を占める必要があることは意味しない。 ほとんどの~file~systemは、 代わりに,いわゆる疎な( `sparse^en )~fileを~supportする — そこでは、 これらの`~NUL~byte$は,実際の~disk空間を占めない。 ◎ Note: Implementations are expected to behave as if the skipped over file contents are indeed filled with NUL bytes. That doesn’t mean these bytes have to actually be written to disk and take up disk space. Instead most file systems support so called sparse files, where these NUL bytes don’t take up actual disk space.
- %頭部 ~LET %~stream の `buffer$sl 内の[ 先頭から %書込n位置 個の~byte ]が成す`~byte列$ ◎ Let head be a byte sequence containing the first writePosition bytes of stream’s[[buffer]].
- %尾部 ~LET 空な`~byte列$ ◎ Let tail be an empty byte sequence.
- ~IF[ %書込n位置 ~PLUS %~data の`長さ$byte ~LT %旧-~size ] ⇒ %尾部 ~SET %~stream の `buffer$sl 内の末尾から[ %旧-~size ~MINUS ( %書込n位置 ~PLUS %~data の`長さ$byte ) ]個の~byteたちが成す`~byte列$ ◎ If writePosition + data’s length is smaller than oldSize: • Let tail be a byte sequence containing the last oldSize - (writePosition + data’s length) bytes of stream’s [[buffer]].
-
%~stream の `buffer$sl ~SET 次を順に連結した結果 ⇒# %頭部, %~data, %尾部 ◎ Set stream’s [[buffer]] to the concatenation of head, data and tail.
~IF[ `buffer$sl を改変する演算は、 `~storage~quota$を超過することに因り失敗した ] ⇒# `~promiseを却下する$( %~promise, `QuotaExceededError$E 例外 ); ~RET( %~stream の `buffer$sl は改変されない。) ◎ If the operations modifying stream’s [[buffer]] in the previous steps failed due to exceeding the storage quota,\ reject p with a "QuotaExceededError" DOMException and\ abort these steps, leaving stream’s [[buffer]] unmodified.
注記: `~storage~quota$は、 `~bucket~file~system$に格納された~fileに限り適用される。 しかしながら,この演算は、 他の~fileに対しても失敗し得る — 例えば、 書込まれている~diskの~disk空間が尽きた場合に。 ◎ Note: Storage quota only applies to files stored in a bucket file system. However this operation could still fail for other files, for example if the disk being written to runs out of disk space.
- %~stream の `seekOffset$sl ~SET %書込n位置 ~PLUS %~data の`長さ$byte ◎ Set stream’s [[seekOffset]] to writePosition + data’s length.
- `~promiseを解決する$( %~promise ) ◎ Resolve p.
-
~ELIF[ %~command ~EQ `seek$l ]: ◎ Otherwise, if command is "seek":
- ~IF[ %位置【!chunk["position"]】 ~IN { ~NULL, ε } ] ⇒# `~promiseを却下する$( %~promise, `TypeError$E `TypeError$E ); ~RET ◎ ↑↑ Assert: chunk is a dictionary. ◎ If chunk["position"] does not exist, reject p with a TypeError and abort these steps.
- %~stream の `seekOffset$sl ~SET %位置【!chunk["position"]】 ◎ Set stream’s [[seekOffset]] to chunk["position"].
- `~promiseを解決する$( %~promise ) ◎ Resolve p.
-
~ELSE( %~command ~EQ `truncate$l ): ◎ Otherwise, if command is "truncate":
- ~IF[ %~size【!%~chunk["size"]】 ~IN { ~NULL, ε } ] ⇒# `~promiseを却下する$( %~promise, `TypeError$E ); ~RET ◎ ↑↑ Assert: chunk is a dictionary. ◎ If chunk["size"] does not exist, reject p with a TypeError and abort these steps.
- %新-~size ~LET %~size【!chunk["size"]】 ◎ Let newSize be chunk["size"].
- %旧-~size ~LET %~stream の `buffer$sl の`長さ$byte ◎ Let oldSize be stream’s [[buffer]]'s length.
-
~IF[ %新-~size ~GT %旧-~size ]: ◎ If newSize is larger than oldSize:
-
%~stream の `buffer$sl に[ ( %新-~size ~MINUS %旧-~size ) 個の`~NUL~byte$ ]が成す`~byte列$を付加する ◎ Set stream’s [[buffer]] to a byte sequence formed by concating stream’s [[buffer]] with a byte sequence containing newSize-oldSize 0x00 bytes.
~IF[ `buffer$sl を改変する演算は、 `~storage~quota$を超過することに因り失敗した ] ⇒# `~promiseを却下する$( %~promise, `QuotaExceededError$E 例外 ); ~RET( %~stream の `buffer$sl は改変されない。) ◎ If the operation in the previous step failed due to exceeding the storage quota,\ reject p with a "QuotaExceededError" DOMException and\ abort these steps, leaving stream’s [[buffer]] unmodified.
注記: `~storage~quota$は、 `~bucket~file~system$に格納された~fileに限り適用される。 しかしながら,この演算は、 他の~fileに対しても失敗し得る — 例えば、 書込まれている~diskの~disk空間が尽きた場合に。 ◎ Note: Storage quota only applies to files stored in a bucket file system. However this operation could still fail for other files, for example if the disk being written to runs out of disk space.
-
- ~ELIF[ %新-~size ~LT %旧-~size ] ⇒ %~stream の `buffer$sl ~SET %~stream の `buffer$sl 内の[ 先頭から %新-~size 個の~byte ]が成す`~byte列$ ◎ Otherwise, if newSize is smaller than oldSize: ◎ Set stream’s [[buffer]] to a byte sequence containing the first newSize bytes in stream’s [[buffer]].
- ~IF[ %~stream .`seekOffset$sl ~GT %新-~size ] ⇒ %~stream .`seekOffset$sl ~SET %新-~size ◎ If stream’s [[seekOffset]] is bigger than newSize, set stream’s [[seekOffset]] to newSize.
- `~promiseを解決する$( %~promise ) ◎ Resolve p.
- ~RET %~promise ◎ Return p.
`write()^m ~method
- await %stream . `write(data)$m
- await %stream . `write$m({ `type$mb: `write$l, `data$mb: %data })
- %data の内容を[ %~stream に結付けられた~file ]の中へ現在の~file~cursorから書込む。 ◎ Writes the content of data into the file associated with stream at the current file cursor offset.
- 変更は、 当の~streamが~closeされるまでは, ~disk上の実際の~fileには書込まれない — 代わりに、 概して,一時的な~fileに書込まれる。 ◎ No changes are written to the actual file on disk until the stream has been closed. Changes are typically written to a temporary file instead.
- await %stream . `write$m({ `type$mb: `write$l, `position$mb: %position, `data$mb: %data })
- %data の内容を[ %~stream に結付けられた~file ]の中へ[ 先頭からの~byte数で %position の所 ]から書込む。 現在の~file~cursorは、 書込まれた~dataの末尾を指すよう更新される。 ◎ Writes the content of data into the file associated with stream at position bytes from the top of the file. Also updates the current file cursor offset to the end of the written data.
- 変更は、 当の~streamが~closeされるまでは, ~disk上の実際の~fileには書込まれない — 代わりに、 概して,一時的な~fileに書込まれる。 ◎ No changes are written to the actual file on disk until the stream has been closed. Changes are typically written to a temporary file instead.
- await %stream . `write$m({ `type$mb: `seek$l, `position$mb: %position })
- 現在の~file~cursorを先頭からの~byte数で %position に更新する。 ◎ Updates the current file cursor offset the position bytes from the top of the file.
- await %stream . `write$m({ `type$mb: `truncate$l, `size$mb: %size })
- [ %~stream に結付けられた~file ]を~byte数で %size になるよう~sizeし直す。 当の~fileの尾部は、[ %size ~GT 現在の~file~size ]の場合は`~NUL~byte$たちが詰込まれ, 他の場合は切落とされる。 ◎ Resizes the file associated with stream to be size bytes long. If size is larger than the current file size this pads the file with null bytes, otherwise it truncates the file.
- ~file~cursorは【!`truncate$l が~callされるとき更新される】、 %size より大きい場合は — 後続な書込nが~errorしないことを確保するため — %size に設定され,他の場合は変化しない。 ◎ The file cursor is updated when truncate is called. If the cursor is smaller than size, it remains unchanged. If the cursor is larger than size, it is set to size to ensure that subsequent writes do not error.
- 変更は、 当の~streamが~closeされるまでは, ~disk上の実際の~fileには書込まれない — 代わりに、 概して,一時的な~fileに書込まれる。 ◎ No changes are written to the actual file until on disk until the stream has been closed. Changes are typically written to a temporary file instead.
`write(data)@m ~method手続きは: ◎ The write(data) method steps are:
- %書込器 ~LET コレ用の`書込器を取得する$WS() ◎ Let writer be the result of getting a writer for this.
- %~promise ~LET %書込器 に`~chunkを書込む$WSW( %data ) ◎ Let result be the result of writing a chunk to writer given data.
- %書込器 を`解放する$WSW() ◎ Release writer.
- ~RET %~promise ◎ Return result.
`seek()^m ~method
- await %stream . `seek(position)$m
- 現在の~file~cursorを[ 当の~fileの先頭からの~byte数 ]で %position に更新する。 ◎ Updates the current file cursor offset the position bytes from the top of the file.
`seek(position)@m ~method手続きは: ◎ The seek(position) method steps are:
- %書込器 ~LET コレ用の`書込器を取得する$WS() ◎ Let writer be the result of getting a writer for this.
- %~promise ~LET %書込器 に`~chunkを書込む$WSW( «[ "`type$mb" → `seek$l, "`position$mb" → %position ]» ) ◎ Let result be the result of writing a chunk to writer given «[ "type" → "seek", "position" → position ]».
- %書込器 を`解放する$WSW ◎ Release writer.
- ~RET %~promise ◎ Return result.
`truncate()^m ~method
- await %stream . `truncate(size)$m
- [ %~stream に結付けられた~file ]を~byte数で %size になるよう~sizeし直す。 当の~fileの尾部は、[ %size ~GT 現在の~file~size ]場合は`~NUL~byte$たちが詰め込まれ, 他の場合は切落とされる。 ◎ Resizes the file associated with stream to be size bytes long. If size is larger than the current file size this pads the file with null bytes, otherwise it truncates the file.
- ~file~cursorは【!`truncate$l が~callされるとき更新される】、 %size より大きい場合は — 後続な書込nが~errorしないことを確保するため — %size に設定され,他の場合は変化しない。 ◎ The file cursor is updated when truncate is called. If the cursor is smaller than size, it remains unchanged. If the cursor is larger than size, it is set to size to ensure that subsequent writes do not error.
- 変更は、 当の~streamが~closeされるまでは, ~disk上の実際の~fileには書込まれない — 代わりに、 概して,一時的な~fileに書込まれる。 ◎ No changes are written to the actual file until on disk until the stream has been closed. Changes are typically written to a temporary file instead.
`truncate(size)@m ~method手続きは: ◎ The truncate(size) method steps are:
- %書込器 ~LET コレ用の`書込器を取得する$WS() ◎ Let writer be the result of getting a writer for this.
- %~promise ~LET %書込器 に`~chunkを書込む$WSW( «[ "`type$mb" → `truncate$l, "`size$mb" → %size ]» ) ◎ Let result be the result of writing a chunk to writer given «[ "type" → "truncate", "size" → size ]».
- %書込器 を`解放する$WSW ◎ Release writer.
- ~RET %~promise ◎ Return result.
2.6. `FileSystemSyncAccessHandle^I ~interface
dictionary `FileSystemReadWriteOptions@I { [`EnforceRange$] `unsigned long long$ `at@mb; }; [`Exposed$=DedicatedWorker, `SecureContext$] interface `FileSystemSyncAccessHandle@I { `unsigned long long$ `read$mS(`AllowSharedBufferSource$I %buffer, optional `FileSystemReadWriteOptions$I %options = {}); `unsigned long long$ `write$mS(`AllowSharedBufferSource$I %buffer, optional `FileSystemReadWriteOptions$I %options = {}); `undefined$ `truncate$mS([`EnforceRange$] `unsigned long long$ %newSize); `unsigned long long$ `getSize$mS(); `undefined$ `flush$mS(); `undefined$ `close$mS(); };
各 `FileSystemSyncAccessHandle$I には、 次に挙げるものが結付けられる: ◎ ↓
- `file@slS ⇒ ある`~file~entry$fs ◎ A FileSystemSyncAccessHandle has an associated [[file]] (a file entry).
- `state@slS ⇒ 文字列 ~IN { `open^l, `closed^l } ◎ A FileSystemSyncAccessHandle has an associated [[state]], a string that may exclusively be "open" or "closed".
`FileSystemSyncAccessHandle$I は、 単独の~fileに対し[ そこから読取る/ そこへ書込む/ その~sizeを得する/ その~sizeを変更する ]能力を備える~objである。 ◎ A FileSystemSyncAccessHandle is an object that is capable of reading from/writing to, as well as obtaining and changing the size of, a single file.
`FileSystemSyncAccessHandle$I は、 同期的な~methodを提供する。 これは、 非同期的な演算には高い~overheadがつきまとう文脈(例:~WebAssembly)において, より高い処理能を許容する。 ◎ A FileSystemSyncAccessHandle offers synchronous methods. This allows for higher performance on contexts where asynchronous operations come with high overhead, e.g., WebAssembly.
各 `FileSystemSyncAccessHandle$I は、 `~file位置~cursor@fsH ( `file position cursor^en )†を有する — それは、 ~fileの先頭からの~offset††を~byte数で表現する整数であり, 0 に初期化される。 ◎ A FileSystemSyncAccessHandle has a file position cursor initialized at byte offset 0 from the top of the file.
【† 略して “~file~cursor”, もっと略して “~cursor” とも称される。 】【†† ~offsetが[ ~byteを直に指す~index, ~byteと~byteの狭間を指す~index ]どちらを表すか述べられていない ( “~offset X から ~offset Y までを成す~byte列” の様な句の意味が不明瞭になる) — 一部の~algo内の記述は前者を示唆しているが、 この訳では後者を表すものと解釈して,その箇所の記述も改める。 】
`read()^m ~method
- %handle . `read$mS(%buffer)
- %handle . `read$mS(%buffer, { `at$mb })
- [ %~handle に結付けられた~file ]の内容を所与の~offsetから(省略可能) %buffer の中へ読取る。 ◎ Reads the contents of the file associated with handle into buffer, optionally at a given offset.
- ~file~cursorは、 【!`read()$mS が~callされたとき】 読取った最後の~byteの直後を指すよう更新される。 ◎ The file cursor is updated when read() is called to point to the byte after the last byte read.
外部から改変された~fileから読取るときに,~access~handleがどう反応するべきか指定する。 ◎ Specify how Access Handles should react when reading from a file that has been modified externally.
`read(buffer, options)@mS ~method手続きは: ◎ The read(buffer, FileSystemReadWriteOptions: options) method steps are:
- ~IF[ コレ の `state$slS ~EQ `closed^l ] ⇒ ~THROW `InvalidStateError$E ◎ If this's [[state]] is "closed", throw an "InvalidStateError" DOMException.
- %~buffer~size ~LET %buffer の`~byte長さ$BS ◎ Let bufferSize be buffer’s byte length.
- %~file内容 ~LET コレの `file$slS の`~binary~data$fE ◎ Let fileContents be this's [[file]]'s binary data.
- %~file~size ~LET %~file内容 の`長さ$byte ◎ Let fileSize be fileContents’s length.
- %読取n始端 ~LET %options[ "`at$mb" ] ◎ ↓
- ~IF[ %読取n始端 ~EQ ε ] ⇒ %読取n始端 ~SET コレの`~file位置~cursor$fsH ◎ Let readStart be options["at"] if options["at"] exists; otherwise this's file position cursor.
-
~IF[ 下層の~file~systemは、 ~byte数による~offset【!~file~offset】 %読取n始端 から読取ることを~supportしない ] ⇒ ~THROW `TypeError$E ◎ If the underlying file system does not support reading from a file offset of readStart, throw a TypeError.
【 主に~offsetが巨大過ぎる事例が念頭にあると思われるが、[ まったく~supportしない/ ~~不連続に~supportする(例:偶数のみ) ]ような事例も無いとは言い切れない。 】
-
~IF[ %読取n始端 ~GT %~file~size ]: ◎ If readStart is larger than fileSize:
- コレの`~file位置~cursor$fsH ~SET %~file~size ◎ Set this's file position cursor to fileSize.
- ~RET 0 ◎ Return 0.
- %読取n終端 ~LET %読取n始端 ~PLUS %~buffer~size【! ~MINUS 1】 ◎ Let readEnd be readStart + (bufferSize − 1).
- ~IF[ %読取n終端 ~GT %~file~size ] ⇒ %読取n終端 ~SET %~file~size ◎ If readEnd is larger than fileSize, set readEnd to fileSize.
-
%~byte列 ~LET %~file内容 の[ %読取n始端 から %読取n終端 まで ]を成す`~byte列$ ◎ Let bytes be a byte sequence containing the bytes from readStart to readEnd of fileContents. ◎ ↓ Let result be bytes’s length.
~IF[ %~file内容 から読取る演算は失敗した ]: ◎ If the operations reading from fileContents in the previous steps failed:
- ~IF[ 読取nは部分的であった ]~AND[ 読取った~byte数は既知である ] ⇒ %~byte列 ~SET 部分的に読取られた結果 ◎ If there were partial reads and the number of bytes that were read into bytes is known, set result to the number of read bytes.
-
~ELSE ⇒ ~RET 0 ◎ Otherwise set result to 0.
【 原文は,この事例でも以下を遂行しているが、 遂行-不能であろう。 】
- `配列~bufferの中へ~byte列を書込む$( %buffer の`下層~buffer$BS, %~byte列 ) ◎ Let arrayBuffer be buffer’s underlying buffer. ◎ Write bytes into arrayBuffer.
- %結果 ~LET %~byte列 の`長さ$byte ◎ ↑
- コレの`~file位置~cursor$fsH ~SET %読取n始端 ~PLUS %結果 ◎ Set this's file position cursor to readStart + result.
- ~RET %結果 ◎ Return result.
`write()^m ~method
- %handle . `write$mS(%buffer)
- %handle . `write$mS(%buffer, { `at$mb: %offset })
- %buffer の内容を[ %handle に結付けられた~file ]の中へ %offset (省略可能)から書込む — 書込まれた~byte数を返す。 書込まれた~byte数を検査することは、 ~errorや部分的な書込nを検出して取扱うことを~call元に許容する。 ◎ Writes the content of buffer into the file associated with handle, optionally at a given offset, and returns the number of written bytes. Checking the returned number of written bytes allows callers to detect and handle errors and partial writes.
- ~file~cursorは、 【!`write$l が~callされたとき】 最後の~byte書込まれた後の~byteを指すよう更新される。 ◎ The file cursor is updated when write is called to point to the byte after the last byte written.
`write(buffer, options)@mS ~method手続きは: ◎ The write(buffer, FileSystemReadWriteOptions: options) method steps are:
- ~IF[ コレ の `state$slS ~EQ `closed^l ] ⇒ ~THROW `InvalidStateError$E ◎ If this's [[state]] is "closed", throw an "InvalidStateError" DOMException.
- %書込n位置 ~LET %options[ "`at$mb" ] ◎ ↓
- ~IF[ %書込n位置 ~EQ ε ] ⇒ %書込n位置 ~SET コレの`~file位置~cursor$fsH ◎ Let writePosition be options["at"] if options["at"] exists; otherwise this's file position cursor.
-
~IF[ 下層の~file~systemは、 ~byte数による~offset 【!~file~offset】 %書込n位置 から書込むことを~supportしない ] ⇒ ~THROW `TypeError$E
【 主に~offsetが巨大過ぎる事例が念頭にあると思われるが、[ まったく~supportしない/ ~~不連続に~supportする(例:偶数のみ) ]ような事例も無いとは言い切れない。 】
◎ If the underlying file system does not support writing to a file offset of writePosition, throw a TypeError. - %~file内容 ~LET コレの `file$slS の`~binary~data$fEの複製 ◎ Let fileContents be a copy of this's [[file]]'s binary data.
- %旧-~size ~LET %~file内容 の`長さ$byte ◎ Let oldSize be fileContents’s length.
- %~buffer~size ~LET %buffer の`~byte長さ$BS ◎ Let bufferSize be buffer’s byte length.
-
~IF[ %書込n位置 ~GT %旧-~size ] ⇒ %~file内容 ~SET %~file内容 の末尾に ( %書込n位置 ~MINUS %旧-~size ) 個の`~NUL~byte$が成す`~byte列$を付加した結果 ◎ If writePosition is larger than oldSize, append writePosition − oldSize 0x00 (NUL) bytes to the end of fileContents.
注記: 実装には[ ~file内容の末尾が~~実際に`~NUL~byte$たちで埋められた ]かのように挙動することが期待される。 それは、 これらの~byteが実際に~diskに書込まれ, ~disk空間を占める必要があることは意味しない。 ほとんどの~file~systemは、 代わりに,いわゆる疎な( `sparse^en )~fileを~supportする — そこでは、 これらの`~NUL~byte$は,実際の~disk空間を占めない。 ◎ Note: Implementations are expected to behave as if the skipped over file contents are indeed filled with NUL bytes. That doesn’t mean these bytes have to actually be written to disk and take up disk space. Instead most file systems support so called sparse files, where these NUL bytes don’t take up actual disk space.
- %頭部 ~LET %~file内容 の[ 先頭から %書込n位置 個の~byte ]が成す`~byte列$ ◎ Let head be a byte sequence containing the first writePosition bytes of fileContents.
- %尾部 ~LET 空な`~byte列$ ◎ Let tail be an empty byte sequence.
- ~IF[ %書込n位置 ~PLUS %~buffer~size ~LT %旧-~size ] ⇒ %尾部 ~SET %~file内容 の末尾から[ ( %旧-~size ~MINUS ( %書込n位置 ~PLUS %~buffer~size ) ) 個の~byte ]が成す`~byte列$ ◎ If writePosition + bufferSize is smaller than oldSize: • Set tail to a byte sequence containing the last oldSize − (writePosition + bufferSize) bytes of fileContents.
- %新-~size ~LET %頭部 の`長さ$byte ~PLUS %~buffer~size ~PLUS %尾部 の`長さ$byte ◎ Let newSize be head’s length + bufferSize + tail’s length.
- ~IF[ ( %新-~size ~MINUS %旧-~size ) 個の~byteを追加すると可用な`~storage~quota$を超過する ] ⇒ ~THROW `QuotaExceededError$E ◎ If newSize − oldSize exceeds the available storage quota, throw a "QuotaExceededError" DOMException.
-
コレの `file$slS の`~binary~data$fE ~SET 次を順に連結した結果 ⇒# %頭部, %buffer の内容, %尾部 ◎ Set this's [[file]]'s binary data to the concatenation of head, the contents of buffer and tail.
注記: %buffer の内容に~accessするために利用される仕組みは、 敢えて曖昧にしてある。 実装は、 ( %buffer の複製を作成する代わりに) ~host~OSへ直な書込n~callを発行することにより, 処理能に注力することを選ぶ見込みが高い — それは、 書込n順序と部分的な書込nによる結果に対する詳細な指定を~~妨げている。 ◎ Note: The mechanism used to access buffer’s contents is left purposely vague. It is likely that implementations will choose to focus on performance by issuing direct write calls to the host operating system (instead of creating a copy of buffer), which prevents a detailed specification of the write order and the results of partial writes.
~IF[ `~binary~data$fEを改変する演算は失敗した ]: ◎ If the operations modifying the this’s[[file]]'s binary data in the previous steps failed:
-
~IF[ 書込nは部分的であった ]~AND[ %buffer から書込まれた~byte数は既知である ]: ◎ If there were partial writes and the number of bytes that were written from buffer is known:
- %書込まれた~byte数 ~LET %buffer から書込まれた~byte数 ◎ Let bytesWritten be the number of bytes that were written from buffer.
- コレの`~file位置~cursor$fsH ~SET %書込n位置 ~PLUS %書込まれた~byte数 ◎ Set this's file position cursor to writePosition + bytesWritten.
- ~RET %書込まれた~byte数 ◎ Return bytesWritten.
- ~THROW `InvalidStateError$E ◎ Otherwise throw an "InvalidStateError" DOMException.
-
- コレの`~file位置~cursor$fsH ~SET %書込n位置 ~PLUS %~buffer~size ◎ Set this's file position cursor to writePosition + bufferSize.
- ~RET %~buffer~size ◎ Return bufferSize.
`truncate()^m ~method
- %handle . `truncate(newSize)$mS
- [ %handle に結付けられた~file ]を~byte数で %newSize になるよう~sizeし直す。 当の~fileの尾部は、[ %newSize ~GT 現在の~file~size ]の場合は`~NUL~byte$たちが詰め込まれ, 他の場合は切落とされる。 ◎ Resizes the file associated with handle to be newSize bytes long. If newSize is larger than the current file size this pads the file with null bytes; otherwise it truncates the file.
- ~file~cursorは【!`truncate$l が~callされるとき更新される】、 %newSize より大きい場合は %newSize に設定され,他の場合は変化しない。 ◎ The file cursor is updated when truncate is called. If the cursor is smaller than newSize, it remains unchanged. If the cursor is larger than newSize, it is set to newSize.
`truncate(newSize)@mS ~method手続きは: ◎ The truncate(newSize) method steps are:
- ~IF[ コレ の `state$slS ~EQ `closed^l ] ⇒ ~THROW `InvalidStateError$E ◎ If this's [[state]] is "closed", throw an "InvalidStateError" DOMException.
- %~file内容 ~LET コレの `file$slS の`~binary~data$fEの複製 ◎ Let fileContents be a copy of this's [[file]]'s binary data.
- %旧-~size ~LET %~file内容 の`長さ$byte ◎ Let oldSize be the length of this's [[file]]'s binary data.
- ~IF[ 下層の~file~systemは、 ~fileの~sizeを %newSize に設定することを~supportしない ] ⇒ ~THROW `TypeError$E ◎ If the underlying file system does not support setting a file’s size to newSize, throw a TypeError.
-
~IF[ %newSize ~GT %旧-~size ]~AND[ ( %newSize ~MINUS %旧-~size ) 個の~byteを追加すると可用な`~storage~quota$を超過する ] ⇒ ~THROW `QuotaExceededError$E ◎ If newSize is larger than oldSize: • If newSize − oldSize exceeds the available storage quota, throw a "QuotaExceededError" DOMException.
-
~IF[ %newSize ~NEQ %旧-~size ]:
- ~IF[ %newSize ~GT %旧-~size ] ⇒ %~file内容 ~SET %~file内容 の末尾に ( %newSize ~MINUS %旧-~size ) 個の`~NUL~byte$が成す`~byte列$を付加した結果
- ~ELSE ⇒ %~file内容 ~SET %~file内容 の[ 先頭から %newSize 個の~byte ]が成す`~byte列$
-
コレの `file$slS の`~binary~data$fE ~SET %~file内容
~IF[ `~binary~data$fEを改変する演算は失敗した ] ⇒ ~THROW `InvalidStateError$E
- ~IF[ コレの`~file位置~cursor$fsH ~GT %newSize ] ⇒ コレの`~file位置~cursor$fsH ~SET %newSize ◎ If this's file position cursor is greater than newSize, then set file position cursor to newSize.
`getSize()^m ~method
- %handle . `getSize()$mS
- [ %handle に結付けられた~file ]の~sizeを~byte数で返す。 ◎ Returns the size of the file associated with handle in bytes.
`getSize()@mS ~method手続きは: ◎ The getSize() method steps are:
- ~IF[ コレの `state$slS ~EQ `closed^l ] ⇒ ~THROW `InvalidStateError$E ◎ If this's [[state]] is "closed", throw an "InvalidStateError" DOMException.
- ~RET コレの `file$slS の`~binary~data$fEの`長さ$byte ◎ Return this's [[file]]'s binary data's length.
`flush()^m ~method
- %handle . `flush()$mS
- [ %handle に結付けられた~file ]の内容が[ `write()$mS を通して行われたすべての改変 ]を包含することを確保する。 ◎ Ensures that the contents of the file associated with handle contain all the modifications done through write().
`flush()@mS ~method手続きは: ◎ The flush() method steps are:
- ~IF[ コレの `state$slS ~EQ `closed^l ] ⇒ ~THROW `InvalidStateError$E ◎ If this's [[state]] is "closed", throw an "InvalidStateError" DOMException.
-
[ ~cacheされた~fileの内容に対するすべての改変 ]を[ ~file~systemの下層の~storage装置 ]へ転送するよう試みる ◎ Attempt to transfer all cached modifications of the file’s content to the file system’s underlying storage device.
注記: これは、 書出し( `flushing^en )とも呼ばれる。 ~file~systemによっては、 これは,何もしないこともある — 書出n先の “~disk” が無い,~memory内の~file~systemなど。 ◎ Note: This is also known as flushing. This may be a no-op on some file systems, such as in-memory file systems, which do not have a "disk" to flush to.
`close()^m ~method
- %handle . `close()$mS
- 当の~access~handleを~closeする — 当の~handleは,すでに~closeされたならば何もしない。 これは、 %handle に結付けられた `file$slS に対する更なる演算を不能化して, それに対する`~lockを解放する$。 ◎ Closes the access handle or no-ops if the access handle is already closed. This disables any further operations on it and releases the lock on the [[file]] associated with handle.
`close()@mS ~method手続きは: ◎ The close() method steps are:
- ~IF[ コレ の `state$slS ~EQ `closed^l ] ⇒ ~RET ◎ If this's [[state]] is "closed", return.
- コレ の `state$slS ~SET `closed^l ◎ Set this's [[state]] to "closed".
- %~lockは解放されたか ~SET ~F ◎ Set lockReleased to false.
- %~file ~LET コレの `file$slS ◎ Let file be this's [[file]].
-
`~file~system~queue$に次の`手続きを~enqueueする$: ◎ Enqueue the following steps to the file system queue:
- `~lockを解放する$( %~file ) ◎ Release the lock on file.
- %~lockは解放されたか ~SET ~T ◎ Set lockReleased to true.
- 次が満たされるまで`静止する$ ⇒ %~lockは解放されたか ~EQ ~T ◎ Pause until lockReleased is true.
注記: この~methodは[ ~fileに対するすべての改変が下層の~storage装置~内に即時に反映される ]ことを保証しない。 この保証を要求する場合、 最初に `flush()$mS ~methodを~callすること。 ◎ Note: This method does not guarantee that all file modifications will be immediately reflected in the underlying storage device. Call the flush() method first if you require this guarantee.
3. ~bucket~file~systemへの~access法
`~bucket~file~system@ は、 次を満たす`~storage端点$である ⇒ [ `識別子$sE ~EQ `fileSystem^l ]~AND[ `種別~群$sEの`~size$ ~EQ 1 ]~AND[ `種別~群$sE[ 0 ] ~EQ `local^l ]~AND[ `~quota$sE ~EQ ~NULL ] ◎ The bucket file system is a storage endpoint whose identifier is "fileSystem", types are « "local" », and quota is null.
【そのような】~storage端点は、 ここではなく `storage$r 内に定義されるべきである。 そこにある~table 【`登録-済み~storage端点~群@~STORAGE#registered-storage-endpoints$】 の中へこれを併合する。 ◎ Storage endpoints should be defined in [storage] itself, rather than being defined here. So merge this into the table there.
注記: ~UAは、 概して[ この`~bucket~file~system$の内容を~disk上に持続する ]ことにより,これを実装することになるが、[ 当の内容が利用者から容易に~access可能になる ]ことは意図されない。 類似に,[ `~bucket~file~system$のいずれかの子【子孫】の名前に合致している名前 ]を伴う[ ~file/~directory ]が存在することは期待されない。 ◎ Note: While user agents will typically implement this by persisting the contents of a bucket file system to disk, it is not intended that the contents are easily user accessible. Similarly there is no expectation that files or directories with names matching the names of children of a bucket file system exist.
[`SecureContext$] partial interface `StorageManager$I { `Promise$<`FileSystemDirectoryHandle$I> `getDirectory$m(); };
- %directoryHandle = await navigator . storage . `getDirectory()$m
- `~bucket~file~system$の根~directoryを返す。 ◎ Returns the root directory of a bucket file system.
`getDirectory()@m ~method手続きは: ◎ The getDirectory() method steps are:
- %環境 ~LET `現在の設定群~obj$ ◎ Let environment be the current settings object.
- %~map ~LET `局所~storage瓶~mapを得する$( %環境, `fileSystem^l )
- ~IF[ %~map ~EQ `失敗^i ] ⇒ ~RET `却下される~promise$( `SecurityError$E 例外 ) ◎ Let map be the result of running obtain a local storage bottle map with environment and "fileSystem". If this returns failure, return a promise rejected with a "SecurityError" DOMException.
-
~IF[ %~map[ `root^l ] ~EQ ε ]: ◎ If map["root"] does not exist:
- %~access~algo ~LET 次の手続き ⇒ ~RET 新たな`~file~system~access結果$ — その ⇒# `許可~状態$fsA ~SET `granted$l, `~error名$fsA ~SET 空~文字列 ◎ ↓
- %~directory ~LET 新たな`~directory~entry$fs — その ⇒# `~query~access$fE ~SET %~access~algo, `要請~access$fE ~SET %~access~algo ◎ Let dir be a new directory entry whose query access and request access algorithms always return a file system access result with a permission state of "granted" and with an error name of the empty string.
- %~directory の`名前$fE ~SET 空~文字列 ◎ Set dir’s name to the empty string.
- %~directory の`子~群$fE ~SET 新たな`有順序~集合$ ◎ Set dir’s children to an empty set.
- %~map[ `root^l ] ~SET %~directory ◎ Set map["root"] to dir.
- %根 ~LET `実装定義$な不透明な`文字列$ ◎ Let root be an implementation-defined opaque string.
- %~path ~LET « 空~文字列 » ◎ Let path be « the empty string ».
-
%~handle ~LET `~directory~handleを作成する$( %根, %~path, `現在の~realm$ ) ◎ Let handle be the result of creating a new FileSystemDirectoryHandle. given root and path in the current realm.
注記: %根 は、 関連な情報として,`~storage~bucket$などを識別するものを含むかもしれない。 ◎ Note: root might include relevant identifying information such as the storage bucket.
- ~Assert: `~entryを~locateする$( %~handle の`~locator$fsH ) を遂行した結果は次を満たす ⇒ [ `~directory~entry$fsである ]~AND[ %~map[ `root^l ] と`同一-~entry$である ] ◎ Assert: locating an entry given handle’s locator returns a directory entry that is the same entry as map["root"].
- ~RET `解決される~promise$( %~handle ) ◎ Return a promise resolved with handle.
謝辞
次の方々からの~~貢献に感謝する:
`_acks1@