Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -76,9 +76,9 @@ public void OdtTemplateProcessor_OttProducesOdt()
Assert.Equal("application/vnd.oasis.opendocument.text", verifier.ManifestRootMediaType);
}

// opendocument.md "Streams and Byte Arrays": bytes, and a write-only output stream (File.OpenWrite)
// opendocument.md "Streams and Byte Arrays": bytes, and an output stream opened with File.Create
[Fact]
public void OdtTemplateProcessor_BytesAndWriteOnlyOutputStream()
public void OdtTemplateProcessor_BytesAndOutputStream()
{
OdtTemplateProcessor processor = new OdtTemplateProcessor(Options());
string templatePath = Write("template.ott", SampleTemplate().AsTemplate().ToBytes());
Expand All @@ -88,7 +88,7 @@ public void OdtTemplateProcessor_BytesAndWriteOnlyOutputStream()

ProcessingResult streamResult;
using (FileStream templateStream = File.OpenRead(templatePath))
using (FileStream outputStream = File.OpenWrite(PathOf("output.odt")))
using (FileStream outputStream = File.Create(PathOf("output.odt")))
{
streamResult = processor.ProcessTemplate(templateStream, outputStream, SampleData());
}
Expand Down
15 changes: 10 additions & 5 deletions docs/for-developers/opendocument.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,15 +55,19 @@ ProcessingResult bytesResult = processor.ProcessTemplate(template, data, out byt

// Streams: the output stream only has to be writable.
using var templateStream = File.OpenRead("template.ott");
using var outputStream = File.OpenWrite("output.odt");
using var outputStream = File.Create("output.odt"); // creates or truncates the file
ProcessingResult streamResult = processor.ProcessTemplate(templateStream, outputStream, data);
```

The requirements are looser than for Word documents:

- The template stream must be readable. It does not have to be seekable.
- The output stream only has to be **writable** (`File.OpenWrite` works). The document is built in memory and written
in one go, and **only when processing succeeds**. On failure nothing is written.
- The output stream only has to be **writable**; it does not have to be readable or seekable. The document is built
in memory and written in one go, and **only when processing succeeds**. On failure nothing is written.
- To write a file, open it with **`File.Create`**, which creates the file or truncates an existing one.
`File.OpenWrite` does not truncate: it writes over an existing file from the start and keeps any bytes after the
new content, which leaves a corrupt ZIP file when the old file was longer. Templify cuts off seekable outputs after
the document (see [Memory Use](#memory-use)), but `File.Create` does not depend on that.

A template that is not an OpenDocument Text package is reported as a failed result, with an `ErrorMessage` that
names what was found. This covers a Word file, a spreadsheet, a flat `.fodt` file or a password-protected document.
Expand All @@ -81,8 +85,9 @@ these limits fails with an `ErrorMessage` such as `content.xml exceeds the maxim
are far below these limits. Treat templates from untrusted sources with care anyway: an entry that unpacks to a very
large size is not held in memory, but it still costs time to copy.

When the output stream is seekable (a file or a `MemoryStream`), it is cut off after the written document, so an
existing, longer file opened with `File.OpenWrite` does not keep bytes of its earlier content.
When the output stream is seekable (a file or a `MemoryStream`), it is cut off after the written document, so even
an existing, longer file opened with `File.OpenWrite` does not keep bytes of its earlier content. Prefer
`File.Create` anyway.

### Options

Expand Down
Loading