libsdfio 1.0.0
Reader and writer for ISO 25178-71 SDF surface data files in C
Loading...
Searching...
No Matches
writer.h File Reference

Writer of a file or a stream. More...

#include <sdfio/header.h>
#include <sdfio/layout.h>
#include <sdfio/reader.h>
#include <sdfio/sdfio_export.h>
#include <sdfio/types.h>
#include <stddef.h>

Go to the source code of this file.

Typedefs

typedef struct sdfio_writer sdfio_writer
 Opaque handle of a writer.

Functions

sdfio_status sdfio_writer_create (const sdfio_allocator *allocator, sdfio_writer **writer)
 Creates a writer.
sdfio_status sdfio_writer_add_binary (sdfio_writer *writer)
 Adds the binary format to the formats that the writer writes.
sdfio_status sdfio_writer_add_ascii (sdfio_writer *writer)
 Adds the ASCII format to the formats that the writer writes.
sdfio_status sdfio_writer_set_buffer (sdfio_writer *writer, size_t size)
 Sets the size in bytes of the buffer between the writer and its stream.
sdfio_status sdfio_writer_set_chunk (sdfio_writer *writer, size_t count)
 Sets the number of values that the writer converts at a time.
sdfio_status sdfio_writer_set_time_zone (sdfio_writer *writer, const sdfio_time_zone *time_zone)
 Sets the conversion of the dates of ISO-1.0 files.
sdfio_status sdfio_writer_reset (sdfio_writer *writer)
 Returns a writer to the state new, so that it can create another file on a path or a stream.
void sdfio_writer_free (sdfio_writer *writer)
 Releases a writer.
sdfio_status sdfio_writer_estimate_size (const sdfio_writer *writer, const sdfio_header *header, size_t *size)
 Estimates the number of bytes that the writer writes for a header, without the trailer.
sdfio_status sdfio_create_stream (sdfio_writer *writer, const sdfio_stream *stream, const sdfio_header *header)
 Starts a file that the header describes, including the numbers of columns and rows.
sdfio_status sdfio_write_data (sdfio_writer *writer, const sdfio_layout *layout, const void *src, size_t rows)
 Writes the next rows of the data area.
sdfio_status sdfio_write_heights (sdfio_writer *writer, const sdfio_layout *layout, const void *src)
 Writes the whole data area from a matrix of heights in metres that lies in memory as the layout describes.
sdfio_status sdfio_write_trailer_field (sdfio_writer *writer, const char *name, const char *value)
 Writes a line field = value of the trailer, which ISO-2.0 expects.
sdfio_status sdfio_write_trailer_text (sdfio_writer *writer, const char *text, size_t size)
 Writes text to the trailer.
sdfio_status sdfio_copy_trailer (sdfio_reader *reader, sdfio_writer *writer)
 Copies the trailer of the file that a reader has opened to the file of a writer.
sdfio_status sdfio_end_file (sdfio_writer *writer)
 Ends the file: closes the trailer, the last record, flushes the stream and, for a file that sdfio_create_file() created, closes the file.
const char * sdfio_writer_error_message (const sdfio_writer *writer)
 Returns a description of the most recent failure of the writer, or an empty string if none occurred.

Detailed Description

Writer of a file or a stream.

Process
A writer writes one file at a time, from the start to the end:
  1. sdfio_writer_create() creates the writer.
  2. sdfio_writer_add_binary() and sdfio_writer_add_ascii() add the formats that it writes, at least one. sdfio_writer_set_buffer(), sdfio_writer_set_chunk() and sdfio_writer_set_time_zone() set the options.
  3. sdfio_create_file() or sdfio_create_stream() starts the file from a header. sdfio_writer_estimate_size() estimates the bytes to write.
  4. sdfio_write_heights() writes the whole data area, or sdfio_write_data() writes it in parts of one row or more, in the order of the file, until all rows of the header are written.
  5. sdfio_write_trailer_field(), sdfio_write_trailer_text() and sdfio_copy_trailer() write the trailer, which is optional.
  6. sdfio_end_file() ends the file, also if it has no trailer.
  7. sdfio_writer_free() releases the writer. sdfio_writer_reset() instead returns it to the state new, so that it can create another file.
States
A writer is in one of five states. It is new until a file is created, then created. When all rows are written, the first call that writes the trailer moves it to trailer. sdfio_end_file() moves it to ended, from created if all rows are written, or from trailer. An error that loses the position in the stream moves it to failed: an error of the stream, of writing the header or of closing the file, and a height in sdfio_write_heights() that cannot be written.
  • Formats and options can be set in the state new only. The first creation that passes the checks of the header fixes them, also after sdfio_writer_reset().
  • The header is checked and copied when the file is created, so later changes of it have no effect. It is written with the first rows, because sdfio_write_heights() can still determine the z-scale.
  • A call that the state does not allow returns SDFIO_ERR_STATE, and an invalid argument returns SDFIO_ERR_ARGUMENT. Neither changes the state or the position in the file.
  • A creation that fails leaves the writer new, so it can create the file again.
  • A writer that is released before sdfio_end_file() leaves an incomplete file.

Function Documentation

◆ sdfio_copy_trailer()

sdfio_status sdfio_copy_trailer ( sdfio_reader * reader,
sdfio_writer * writer )

Copies the trailer of the file that a reader has opened to the file of a writer.

The rows of the data area that the reader has not read are read and discarded, and the writer must have written all of its rows. A program that saves a changed file as a new one reads the rows, writes the changed rows and then copies the trailer.

The function does not end the trailer, so fields of sdfio_write_trailer_field(), for instance a line that records the change, can follow the copy. sdfio_end_file() ends the file. The copy has the text that sdfio_read_trailer() returns, with the line ends that sdfio_write_trailer_text() writes. A file without a trailer copies nothing.

If a call fails, sdfio_writer_error_message() describes the failure, also when the reader failed.

Parameters
[in,out]readerThe reader that has opened a file.
[in,out]writerThe writer that has created a file.
Return values
SDFIO_ERR_ARGUMENTA pointer is null.
SDFIO_ERR_STATEThe reader has no file or failed, or the writer has no file, has not written all rows, or ended the file.
SDFIO_ERR_IOA stream failed.
SDFIO_ERR_FORMATThe file of the reader is damaged or truncated.

◆ sdfio_create_stream()

sdfio_status sdfio_create_stream ( sdfio_writer * writer,
const sdfio_stream * stream,
const sdfio_header * header )

Starts a file that the header describes, including the numbers of columns and rows.

The header is written together with the first rows of the data area. The creation date must be set; SDFIO_NO_TIME cannot be written. A file is written with the creation date as modification date if the header has none.

Parameters
[in,out]writerThe writer.
[in]streamThe stream; write is required. The structure is copied.
[in]headerThe description of the file.
Return values
SDFIO_ERR_ARGUMENTA pointer is null, or the header cannot be written: a data type that the revision does not permit, a scale that is not positive, a date that is not set, or a number of columns or rows that the header cannot represent.
SDFIO_ERR_RANGEThe time zone of the writer cannot convert a date. It is reported when the header is written, with the first rows.
SDFIO_ERR_STATEThe writer has created a file already.
SDFIO_ERR_UNSUPPORTEDThe format of the header has not been added to the writer.
SDFIO_ERR_MEMORYAn allocation failed.
Examples
write_memory.c.

◆ sdfio_end_file()

sdfio_status sdfio_end_file ( sdfio_writer * writer)

Ends the file: closes the trailer, the last record, flushes the stream and, for a file that sdfio_create_file() created, closes the file.

All rows of the data area must have been written. Without trailer lines there is no trailer. Nothing can be written after it.

Parameters
[in,out]writerThe writer.
Return values
SDFIO_ERR_STATENo file is created, rows are missing, the file is ended already, or an earlier error ended the writing.
SDFIO_ERR_IOThe stream failed.
Examples
custom_timezone.c, eigen.cpp, opencv.cpp, write_coded.c, write_heights.c, and write_memory.c.

◆ sdfio_write_data()

sdfio_status sdfio_write_data ( sdfio_writer * writer,
const sdfio_layout * layout,
const void * src,
size_t rows )

Writes the next rows of the data area.

src contains rows times header.columns coded values of header.data_type in the byte order of the machine, in the order of the file. The bad value is written unchanged.

The buffer lies in memory as the layout describes, whose type has to be the data type of the file, as for sdfio_read_data(). sdfio_layout_packed() describes coded values that follow each other.

The first row written is the first row stored in the file, the row with y = 0.

Parameters
[in,out]writerThe writer.
[in]layoutThe layout of the buffer.
[in]srcThe coded values to write.
rowsThe number of rows to write.
Return values
SDFIO_ERR_ARGUMENTA pointer is null, rows exceeds the rows remaining, the type of the layout is not the data type of the file, the strides are invalid, or the data type is an integer type and the z-scale is not set.
SDFIO_ERR_STATENo file is created, or an earlier error ended the writing.
SDFIO_ERR_IOThe stream failed.
Examples
write_coded.c.

◆ sdfio_write_heights()

sdfio_status sdfio_write_heights ( sdfio_writer * writer,
const sdfio_layout * layout,
const void * src )

Writes the whole data area from a matrix of heights in metres that lies in memory as the layout describes.

sdfio_layout_packed() describes a plain array.

The layout is that of sdfio_read_heights(): the element (y, x) is at src + y * layout.row_stride + x * layout.element_stride, and the row y = 0 is the first row. For an integer data type with SDFIO_AUTO_Z_SCALE the z-scale is selected from the heights. NaN and infinity label points that are not measured. Call sdfio_end_file() afterwards.

Parameters
[in,out]writerThe writer.
[in]layoutThe layout of the buffer.
[in]srcThe heights.
Return values
SDFIO_ERR_ARGUMENTA pointer is null or the strides are invalid.
SDFIO_ERR_STATENo file is created, an earlier error ended the writing, or rows were written already.
SDFIO_ERR_RANGEA height does not fit the data type with the z-scale.
SDFIO_ERR_BAD_VALUEA height would be read as a point that is not measured.
SDFIO_ERR_IOThe stream failed.
Examples
custom_timezone.c, eigen.cpp, opencv.cpp, write_heights.c, and write_memory.c.

◆ sdfio_write_trailer_field()

sdfio_status sdfio_write_trailer_field ( sdfio_writer * writer,
const char * name,
const char * value )

Writes a line field = value of the trailer, which ISO-2.0 expects.

The line goes to the stream as it is given, so nothing is assembled in memory. All rows of the data area must have been written. The fields and the text of sdfio_write_trailer_text() can follow each other in any order. sdfio_end_file() ends the trailer.

The value is text. The caller formats numbers, for instance with snprintf() in the C locale, because a locale with a decimal comma would produce 20,5.

Parameters
[in,out]writerThe writer.
[in]nameThe field name: letters, digits and _.
[in]valueThe value: one line. The encoding is not checked; the standard asks for 7-bit ASCII.
Return values
SDFIO_ERR_ARGUMENTA pointer is null, the field name is empty or contains another character, or the value contains a CR or an LF.
SDFIO_ERR_STATENo file is created, rows are missing, the file is ended, or an earlier error ended the writing.
SDFIO_ERR_IOThe stream failed.
Examples
write_heights.c.

◆ sdfio_write_trailer_text()

sdfio_status sdfio_write_trailer_text ( sdfio_writer * writer,
const char * text,
size_t size )

Writes text to the trailer.

ISO-2.0 requires the trailer to consist of lines in the form of sdfio_write_trailer_field(); the form of the text is neither checked nor enforced. All rows must have been written. The text and the fields can follow each other in any order.

A call can write any part of the text: an open line continues with the next call. A field line ends the open line, and so does sdfio_end_file() in an ASCII file, before its closing line *. A binary file ends with the text as it is. Line ends, LF or CRLF, are written as CRLF in both formats. In an ASCII file a line that consists only of * ends the record, so the text must not contain one.

Parameters
[in,out]writerThe writer.
[in]textThe text.
sizeThe length of the text in bytes.
Return values
SDFIO_ERR_ARGUMENTtext is null and size is not 0.
SDFIO_ERR_STATENo file is created, rows are missing, the file is ended, or an earlier error ended the writing.
SDFIO_ERR_IOThe stream failed.

◆ sdfio_writer_add_ascii()

sdfio_status sdfio_writer_add_ascii ( sdfio_writer * writer)

Adds the ASCII format to the formats that the writer writes.

The rules of sdfio_writer_add_binary() apply.

Parameters
[in,out]writerThe writer.
Return values
SDFIO_ERR_ARGUMENTThe writer is null or has added the format already.
SDFIO_ERR_STATEA file creation was attempted earlier.

◆ sdfio_writer_add_binary()

sdfio_status sdfio_writer_add_binary ( sdfio_writer * writer)

Adds the binary format to the formats that the writer writes.

A writer needs at least one format before a file is created, and the format of the header of a file selects the one that writes it.

Like the other options of a writer, a format is added before the first attempt to create a file.

Parameters
[in,out]writerThe writer.
Return values
SDFIO_ERR_ARGUMENTThe writer is null or has added the format already.
SDFIO_ERR_STATEA file creation was attempted earlier.
Examples
custom_timezone.c, eigen.cpp, opencv.cpp, write_coded.c, write_heights.c, and write_memory.c.

◆ sdfio_writer_create()

sdfio_status sdfio_writer_create ( const sdfio_allocator * allocator,
sdfio_writer ** writer )

Creates a writer.

The writer writes nothing until a file is created.

Only the handle is allocated here. The formats are added with the sdfio_writer_add_* functions, the options are optional, and the buffers are allocated when a file is created. Release the writer with sdfio_writer_free().

Parameters
[in]allocatorThe allocator for all memory of the writer, for example sdfio_default_allocator(). The structure is copied, so it need not outlive the call. Both callbacks must be set.
[out]writerReceives the writer, or null if the call fails.
Return values
SDFIO_ERR_ARGUMENTA pointer is null, or the allocator lacks a callback.
SDFIO_ERR_MEMORYAn allocation failed.
Examples
custom_timezone.c, eigen.cpp, opencv.cpp, write_coded.c, write_heights.c, and write_memory.c.

◆ sdfio_writer_error_message()

const char * sdfio_writer_error_message ( const sdfio_writer * writer)

Returns a description of the most recent failure of the writer, or an empty string if none occurred.

The result is never null, and a string of the library, valid for the life of the program.

Parameters
[in]writerThe writer.
Examples
custom_timezone.c, eigen.cpp, opencv.cpp, write_coded.c, write_heights.c, and write_memory.c.

◆ sdfio_writer_estimate_size()

sdfio_status sdfio_writer_estimate_size ( const sdfio_writer * writer,
const sdfio_header * header,
size_t * size )

Estimates the number of bytes that the writer writes for a header, without the trailer.

For the binary format the result is exact; for the ASCII format it is not smaller, as it takes the longest text of every value.

Parameters
[in]writerThe writer.
[in]headerThe description of the file.
[out]sizeReceives the size.
Return values
SDFIO_ERR_ARGUMENTA pointer is null, or the header cannot be written.
SDFIO_ERR_RANGEThe size does not fit in size_t.
SDFIO_ERR_UNSUPPORTEDThe format of the header has not been added to the writer.
Examples
write_memory.c.

◆ sdfio_writer_free()

void sdfio_writer_free ( sdfio_writer * writer)

Releases a writer.

A file that sdfio_create_file() created and sdfio_end_file() did not end is closed in its incomplete state. A null pointer is ignored.

Parameters
[in,out]writerThe writer.
Examples
custom_timezone.c, eigen.cpp, opencv.cpp, write_coded.c, write_heights.c, and write_memory.c.

◆ sdfio_writer_reset()

sdfio_status sdfio_writer_reset ( sdfio_writer * writer)

Returns a writer to the state new, so that it can create another file on a path or a stream.

A file that sdfio_create_file() created and sdfio_end_file() did not end is closed in its incomplete state. The formats, the options and the buffers stay. The function works in every state, also after an error.

Parameters
[in,out]writerThe writer.
Return values
SDFIO_ERR_ARGUMENTThe writer is null.

◆ sdfio_writer_set_buffer()

sdfio_status sdfio_writer_set_buffer ( sdfio_writer * writer,
size_t size )

Sets the size in bytes of the buffer between the writer and its stream.

The default is 16384. A value below 64 is raised to 64. A smaller buffer causes more calls of the stream callbacks.

Parameters
[in,out]writerThe writer.
sizeThe size, not 0.
Return values
SDFIO_ERR_ARGUMENTThe writer is null or the size is 0.
SDFIO_ERR_STATEA file creation was attempted earlier.

◆ sdfio_writer_set_chunk()

sdfio_status sdfio_writer_set_chunk ( sdfio_writer * writer,
size_t count )

Sets the number of values that the writer converts at a time.

The default is

  1. The chunk occupies up to 8 bytes per value; a writer of the ASCII format occupies more.
Parameters
[in,out]writerThe writer.
countThe number of values, not 0 and not so large that the chunk cannot be counted in bytes.
Return values
SDFIO_ERR_ARGUMENTThe writer is null or the number is not valid.
SDFIO_ERR_STATEA file creation was attempted earlier.

◆ sdfio_writer_set_time_zone()

sdfio_status sdfio_writer_set_time_zone ( sdfio_writer * writer,
const sdfio_time_zone * time_zone )

Sets the conversion of the dates of ISO-1.0 files.

The structure is copied, so it need not outlive the call. Null selects no conversion, which is the default.

Parameters
[in,out]writerThe writer.
[in]time_zoneThe time zone, or null.
Return values
SDFIO_ERR_ARGUMENTThe writer is null.
SDFIO_ERR_STATEA file creation was attempted earlier.
Examples
custom_timezone.c, and write_heights.c.