1 #ifndef AWS_IO_STREAM_H
2 #define AWS_IO_STREAM_H
3 
4 /**
5  * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
6  * SPDX-License-Identifier: Apache-2.0.
7  */
8 
9 #include <aws/io/io.h>
10 
11 struct aws_input_stream;
12 struct aws_byte_buf;
13 
14 /*
15  * For seek calls, where in the stream to seek from.
16  * CUR support can come later
17  * Intentionally mirror libc constants
18  */
19 enum aws_stream_seek_basis { AWS_SSB_BEGIN = 0, AWS_SSB_END = 2 };
20 
21 struct aws_stream_status {
22     bool is_end_of_stream;
23     bool is_valid;
24 };
25 
26 struct aws_input_stream_vtable {
27     int (*seek)(struct aws_input_stream *stream, int64_t offset, enum aws_stream_seek_basis basis);
28     /**
29      * Stream as much data as will fit into the destination buffer and update its length.
30      * The destination buffer's capacity MUST NOT be changed.
31      *
32      * Return AWS_OP_SUCCESS if the read is successful.
33      * If AWS_OP_ERR is returned, the stream is assumed to be invalid and any data written to the buffer is ignored.
34      *
35      * If no more data is currently available, or the end of the stream has been reached, simply return AWS_OP_SUCCESS
36      * without touching the destination buffer.
37      */
38     int (*read)(struct aws_input_stream *stream, struct aws_byte_buf *dest);
39     int (*get_status)(struct aws_input_stream *stream, struct aws_stream_status *status);
40     int (*get_length)(struct aws_input_stream *stream, int64_t *out_length);
41     void (*destroy)(struct aws_input_stream *stream);
42 };
43 
44 struct aws_input_stream {
45     struct aws_allocator *allocator;
46     void *impl;
47     struct aws_input_stream_vtable *vtable;
48 };
49 
50 AWS_EXTERN_C_BEGIN
51 
52 /*
53  * Seek to a position within a stream; analagous to fseek() and its relatives
54  */
55 AWS_IO_API int aws_input_stream_seek(struct aws_input_stream *stream, int64_t offset, enum aws_stream_seek_basis basis);
56 
57 /*
58  * Read data from a stream.  If data is available, will read up to the (capacity - len) open bytes
59  * in the destination buffer. If AWS_OP_ERR is returned, the destination buffer will be unchanged.
60  */
61 AWS_IO_API int aws_input_stream_read(struct aws_input_stream *stream, struct aws_byte_buf *dest);
62 
63 /*
64  * Queries miscellaneous properties of the stream
65  */
66 AWS_IO_API int aws_input_stream_get_status(struct aws_input_stream *stream, struct aws_stream_status *status);
67 
68 /*
69  * Returns the total stream length, if able, regardless of current stream position.  Under certain conditions,
70  * a valid stream may return an error instead when there is not a good answer (socket stream, for example).
71  *
72  */
73 AWS_IO_API int aws_input_stream_get_length(struct aws_input_stream *stream, int64_t *out_length);
74 
75 /*
76  * Tears down the stream
77  */
78 AWS_IO_API void aws_input_stream_destroy(struct aws_input_stream *stream);
79 
80 /*
81  * Creates a stream that operates on a range of bytes
82  */
83 AWS_IO_API struct aws_input_stream *aws_input_stream_new_from_cursor(
84     struct aws_allocator *allocator,
85     const struct aws_byte_cursor *cursor);
86 
87 /*
88  * Creates a stream that operates on a (not-yet-opened) file.
89  * Destruction closes the file.
90  */
91 AWS_IO_API struct aws_input_stream *aws_input_stream_new_from_file(
92     struct aws_allocator *allocator,
93     const char *file_name);
94 
95 /*
96  * Creates an input stream that reads from an already opened file.
97  * Destruction does not close the file.
98  */
99 AWS_IO_API struct aws_input_stream *aws_input_stream_new_from_open_file(struct aws_allocator *allocator, FILE *file);
100 
101 AWS_EXTERN_C_END
102 
103 #endif /* AWS_IO_STREAM_H */
104