| // Copyright 2023 The IREE Authors |
| // |
| // Licensed under the Apache License v2.0 with LLVM Exceptions. |
| // See https://llvm.org/LICENSE.txt for license information. |
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| |
| #ifndef IREE_IO_STREAM_H_ |
| #define IREE_IO_STREAM_H_ |
| |
| #include <stdint.h> |
| |
| #include "iree/base/api.h" |
| #include "iree/base/internal/atomics.h" |
| |
| #ifdef __cplusplus |
| extern "C" { |
| #endif // __cplusplus |
| |
| //===----------------------------------------------------------------------===// |
| // iree_io_stream_t |
| //===----------------------------------------------------------------------===// |
| |
| // Stream position; absolute or relative based on how it's used. |
| typedef int64_t iree_io_stream_pos_t; |
| |
| // Bits defining which operations are allowed on a stream. |
| enum iree_io_stream_mode_bits_t { |
| // Allows operations that read from the stream. |
| IREE_IO_STREAM_MODE_READABLE = 1u << 0, |
| // Allows operations that write to the stream. |
| IREE_IO_STREAM_MODE_WRITABLE = 1u << 1, |
| // Allows the iree_io_stream_resize operation for extend/truncate. |
| IREE_IO_STREAM_MODE_RESIZABLE = 1u << 2, |
| // Allows the iree_io_stream_seek operation. |
| IREE_IO_STREAM_MODE_SEEKABLE = 1u << 3, |
| // Allows iree_io_stream_map_read/iree_io_stream_map_write operations. |
| IREE_IO_STREAM_MODE_MAPPABLE = 1u << 4, |
| }; |
| typedef uint32_t iree_io_stream_mode_t; |
| |
| typedef enum iree_io_stream_seek_mode_t { |
| // Like fseek(SEEK_SET): seek to an absolute offset in the stream. |
| // A value of 0 indicates start-of-stream and a value of the total stream |
| // length indicates end-of-stream. |
| IREE_IO_STREAM_SEEK_SET = 0, |
| // Like fseek(SEEK_CUR): seek is a relative offset from the current stream |
| // offset, positive or negative. A value of 0 indicates no change. |
| IREE_IO_STREAM_SEEK_FROM_CURRENT, |
| // Like fseek(SEEK_END): seek is a negative offset from the end of the stream. |
| // A value of 0 indicates end-of-stream (one byte past the end of the stream, |
| // with the offset equalling the total stream length). |
| // |
| // Example: |
| // 0123456789 |
| // ^^^ |
| // ||+- SEEK_FROM_END 0 |
| // |+-- SEEK_FROM_END -1 |
| // +--- SEEK_FROM_END -2 |
| IREE_IO_STREAM_SEEK_FROM_END, |
| } iree_io_stream_seek_mode_t; |
| |
| typedef struct iree_io_stream_t iree_io_stream_t; |
| |
| // Retains the given |stream| for the caller. |
| IREE_API_EXPORT void iree_io_stream_retain(iree_io_stream_t* stream); |
| |
| // Releases the given |stream| from the caller. |
| IREE_API_EXPORT void iree_io_stream_release(iree_io_stream_t* stream); |
| |
| // Returns the mode of the stream indicating what operations may be performed. |
| IREE_API_EXPORT iree_io_stream_mode_t |
| iree_io_stream_mode(const iree_io_stream_t* stream); |
| |
| // Returns the position of the stream relative to the stream base offset. |
| IREE_API_EXPORT iree_io_stream_pos_t |
| iree_io_stream_offset(iree_io_stream_t* stream); |
| |
| // Returns the total length of the stream in bytes ignoring the current offset. |
| IREE_API_EXPORT iree_io_stream_pos_t |
| iree_io_stream_length(iree_io_stream_t* stream); |
| |
| // Returns true if |stream| is positioned at the end of the stream. |
| // When at the end of stream reads will fail and writes will append. |
| IREE_API_EXPORT bool iree_io_stream_is_eos(iree_io_stream_t* stream); |
| |
| // Seeks within |stream| to |seek_offset| based on the given |seek_mode|. |
| // If IREE_IO_STREAM_MODE_SEEKABLE is not set then only forward relative seeks |
| // are supported. |
| IREE_API_EXPORT iree_status_t iree_io_stream_seek( |
| iree_io_stream_t* stream, iree_io_stream_seek_mode_t seek_mode, |
| iree_io_stream_pos_t seek_offset); |
| |
| // Seeks within |stream| to the next offset with the specified |alignment|. |
| // The alignment is expected to be a power-of-two value. |
| // No-op if the stream offset is already aligned. Valid even if |
| // IREE_IO_STREAM_MODE_SEEKABLE is not set as this only performs a forward |
| // relative seek. |
| IREE_API_EXPORT iree_status_t iree_io_stream_seek_to_alignment( |
| iree_io_stream_t* stream, iree_io_stream_pos_t alignment); |
| |
| // Reads up to |buffer_capacity| bytes from |stream| into |buffer|. |
| // Returns the total number of bytes read in the optional |out_buffer_length|, |
| // which may be less than the capacity if the end of stream is reached. If |
| // |out_buffer_length| is not provided the read will fail if enough bytes are |
| // not available. Requires the stream have IREE_IO_STREAM_MODE_READABLE. |
| IREE_API_EXPORT iree_status_t |
| iree_io_stream_read(iree_io_stream_t* stream, iree_host_size_t buffer_capacity, |
| void* buffer, iree_host_size_t* out_buffer_length); |
| |
| // Writes |buffer_length| bytes from |buffer| to |stream|. |
| // Requires the stream have IREE_IO_STREAM_MODE_WRITABLE. |
| IREE_API_EXPORT iree_status_t |
| iree_io_stream_write(iree_io_stream_t* stream, iree_host_size_t buffer_length, |
| const void* buffer); |
| |
| // Writes a single character/byte to the stream. |
| // Requires the stream have IREE_IO_STREAM_MODE_WRITABLE. |
| IREE_API_EXPORT iree_status_t |
| iree_io_stream_write_char(iree_io_stream_t* stream, char c); |
| |
| // Writes a string view to the stream (excluding NUL terminator). |
| // Requires the stream have IREE_IO_STREAM_MODE_WRITABLE. |
| IREE_API_EXPORT iree_status_t |
| iree_io_stream_write_string(iree_io_stream_t* stream, iree_string_view_t value); |
| |
| // Writes |count| elements of |pattern_length| with the given |pattern| value. |
| // Requires the stream have IREE_IO_STREAM_MODE_WRITABLE. |
| IREE_API_EXPORT iree_status_t |
| iree_io_stream_fill(iree_io_stream_t* stream, iree_io_stream_pos_t count, |
| const void* pattern, iree_host_size_t pattern_length); |
| |
| // Maps a span of |length| bytes for reading. The stream offset is advanced by |
| // |length| immediately and the caller can read the returned |out_span| contents |
| // prior to closing the file. |
| // Requires that IREE_IO_STREAM_MODE_READABLE and IREE_IO_STREAM_MODE_MAPPABLE |
| // are set. |
| IREE_API_EXPORT iree_status_t |
| iree_io_stream_map_read(iree_io_stream_t* stream, iree_host_size_t length, |
| iree_const_byte_span_t* out_span); |
| |
| // Maps a span of |length| bytes for writing. The stream offset is advanced by |
| // |length| immediately and the caller must fill the returned |out_span| with |
| // contents prior to closing the file. |
| // Requires that IREE_IO_STREAM_MODE_WRITABLE and IREE_IO_STREAM_MODE_MAPPABLE |
| // are set. |
| IREE_API_EXPORT iree_status_t |
| iree_io_stream_map_write(iree_io_stream_t* stream, iree_host_size_t length, |
| iree_byte_span_t* out_span); |
| |
| // Copies |length| bytes from |source_stream| to |target_stream|. |
| // Requires |source_stream| have IREE_IO_STREAM_MODE_READABLE and |
| // |target_stream| have IREE_IO_STREAM_MODE_WRITABLE. |
| IREE_API_EXPORT iree_status_t iree_io_stream_copy( |
| iree_io_stream_t* source_stream, iree_io_stream_t* target_stream, |
| iree_io_stream_pos_t length); |
| |
| //===----------------------------------------------------------------------===// |
| // Lifetime management utilities |
| //===----------------------------------------------------------------------===// |
| |
| typedef void(IREE_API_PTR* iree_io_stream_release_fn_t)( |
| void* user_data, iree_io_stream_t* stream); |
| |
| // A callback issued when a memory stream is released. |
| typedef struct { |
| // Callback function pointer. |
| iree_io_stream_release_fn_t fn; |
| // User data passed to the callback function. Unowned. |
| void* user_data; |
| } iree_io_stream_release_callback_t; |
| |
| // Returns a no-op file release callback that implies that no cleanup is |
| // required. |
| static inline iree_io_stream_release_callback_t |
| iree_io_stream_release_callback_null(void) { |
| iree_io_stream_release_callback_t callback = {NULL, NULL}; |
| return callback; |
| } |
| |
| //===----------------------------------------------------------------------===// |
| // iree_io_stream_t implementation details |
| //===----------------------------------------------------------------------===// |
| |
| typedef struct iree_io_stream_vtable_t { |
| void(IREE_API_PTR* destroy)(iree_io_stream_t* IREE_RESTRICT stream); |
| |
| iree_io_stream_pos_t(IREE_API_PTR* offset)(iree_io_stream_t* stream); |
| iree_io_stream_pos_t(IREE_API_PTR* length)(iree_io_stream_t* stream); |
| iree_status_t(IREE_API_PTR* seek)(iree_io_stream_t* stream, |
| iree_io_stream_seek_mode_t seek_mode, |
| iree_io_stream_pos_t seek_offset); |
| iree_status_t(IREE_API_PTR* read)(iree_io_stream_t* stream, |
| iree_host_size_t buffer_capacity, |
| void* buffer, |
| iree_host_size_t* out_buffer_length); |
| iree_status_t(IREE_API_PTR* write)(iree_io_stream_t* stream, |
| iree_host_size_t buffer_length, |
| const void* buffer); |
| iree_status_t(IREE_API_PTR* fill)(iree_io_stream_t* stream, |
| iree_io_stream_pos_t count, |
| const void* pattern, |
| iree_host_size_t pattern_length); |
| iree_status_t(IREE_API_PTR* map_read)(iree_io_stream_t* stream, |
| iree_host_size_t length, |
| iree_const_byte_span_t* out_span); |
| iree_status_t(IREE_API_PTR* map_write)(iree_io_stream_t* stream, |
| iree_host_size_t length, |
| iree_byte_span_t* out_span); |
| } iree_io_stream_vtable_t; |
| |
| struct iree_io_stream_t { |
| iree_atomic_ref_count_t ref_count; |
| const iree_io_stream_vtable_t* vtable; |
| iree_io_stream_mode_t mode; |
| }; |
| |
| IREE_API_EXPORT void iree_io_stream_destroy(iree_io_stream_t* stream); |
| |
| #ifdef __cplusplus |
| } // extern "C" |
| #endif // __cplusplus |
| |
| #endif // IREE_IO_STREAM_H_ |