Skip to content

Commit

Permalink
Support seeking past the end of a file.
Browse files Browse the repository at this point in the history
Rather than rejecting when trying to write past the end of a file this
changes the spec to require extending a file with 0 bytes instead.

This enables creating sparse files (very useful for certain file formats
such as disk images). Additionally this greatly simplifies saving content
to a file when the data to be written is received out of order (such as in
the case of bittorrent downloads). Without this functionality such a
application would have to manually make sure to resize the file either
ahead of time or when needed during writing.

Note that the behavior here would have already been possible by keeping
track of the file size, and inserting appropriate truncate() calls to
grow the file whenever trying to write past the end of a file. Not
requiring these explicit truncate calls simplifies code, and reduces the
chance of bugs in websites (accidentally shrinking files when they don't
need to, for example).

This fixes #262
  • Loading branch information
mkruisselbrink committed Jan 22, 2021
1 parent 65e990d commit 882219a
Showing 1 changed file with 7 additions and 6 deletions.
13 changes: 7 additions & 6 deletions index.bs
Expand Up @@ -976,12 +976,6 @@ runs these steps:
1. If |input| is a {{WriteParams}} and |input|.{{WriteParams/position}} is not `undefined`,
set |writePosition| to |input|.{{WriteParams/position}}.
1. Let |oldSize| be |stream|.[=[[buffer]]=]'s [=byte sequence/length=].
1. If |writePosition| is larger than |oldSize|,
[=/reject=] |p| with a {{InvalidStateError}} and abort.

Issue: Not clear if this should reject, and if it does, is this really the right error type?
Chrome's implementation is actually inconsistent about this rejecting or not.

1. If |data| is a {{BufferSource}},
let |dataBytes| be [=get a copy of the buffer source|a copy of=] |data|.
1. Else if |data| is a {{Blob}}:
Expand All @@ -991,6 +985,13 @@ runs these steps:
1. Else:
1. [=Assert=]: |data| is a {{USVString}}.
1. Let |dataBytes| be the result of [=UTF-8 encoding=] |data|.
1. If |writePosition| is larger than |oldSize|,
append |writePosition| - |oldSize| `0x00` (NUL) bytes to the end of |stream|.[=[[buffer]]=].

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.

1. Let |head| be a [=byte sequence=] containing the first |writePosition| bytes of |stream|.[=[[buffer]]=].
1. Let |tail| be an empty [=byte sequence=].
Expand Down

0 comments on commit 882219a

Please sign in to comment.