CX Framework
Cross-platform C utility framework
Loading...
Searching...
No Matches
streambuf.h
Go to the documentation of this file.
1
46
47#pragma once
48
49#include <cx/buffer/bufring.h>
50#include <cx/stype/stype.h>
51
52typedef struct StreamBuffer StreamBuffer;
53
54// Pull callback
55// sz is set to the maximum amount of data the may be written to buf.
56// The callback should fill buf with up to that amount and return the number
57// of bytes that were written.
58// The callback may return 0 if no data is currently available but will likely
59// be immediately called again, so a performing a blocking wait is advisable.
60//
61// If the callback needs to write an amount of data that is larger than the
62// space available as indicated by sz, it may instead call sbufPWrite with the
63// full amount (which will expand the buffer in the process) and return 0.
64//
65// If sz is 0, check if the consumer is finished and/or for error state.
66typedef size_t (*sbufPullCB)(_Pre_valid_ StreamBuffer* sb, _Out_writes_bytes_(sz) uint8* buf,
67 size_t sz, _Pre_opt_valid_ void* ctx);
68
69// Push callback
70// When this callback is used (in direct mode), the data is pushed once to the
71// callback and MUST all be written in one go or it will be lost.
72// If sz is 0, check if the producer is finished and/or for error state.
73typedef void (*sbufPushCB)(_Pre_valid_ StreamBuffer* sb, _In_reads_bytes_(sz) const uint8* buf,
74 size_t sz, _Pre_opt_valid_ void* ctx);
75
76// Send callback
77// This callback is used with sbufCSend. It may be called multiple times with varying
78// offsets. The offset passed is always from the start of the available bytes in the
79// buffer.
80// If this function returns true, the sent bytes will be consumed and removed from the
81// buffer. If it returns false, it behaves like the peek functions and does not remove
82// the bytes from the buffer.
83// If sz is 0, check if the producer is finished and/or for error state.
84typedef bool (*sbufSendCB)(_Pre_valid_ StreamBuffer* sb, _In_reads_bytes_(sz) const uint8* buf,
85 size_t off, size_t sz, _Pre_opt_valid_ void* ctx);
86
87// Notify callback
88// Notification to a consumer that data is available. The sbufC* functions may be
89// used to read all or part of the available data.
90// If sz is 0, check if the producer is finished and/or for error state.
91typedef void (*sbufNotifyCB)(_Pre_valid_ StreamBuffer* sb, size_t sz, _Pre_opt_valid_ void* ctx);
92
93// Cleanup callback
94// Called just before the structure is deallocated, should perform any needed
95// cleanup of the user-supplied ctx.
96typedef void (*sbufCleanupCB)(_Pre_opt_valid_ void* ctx);
97
112
114enum STREAM_BUFFER_FLAGS_ENUM {
115 SBUF_Push = 0x0001,
116 SBUF_Pull = 0x0002,
117 SBUF_Direct = 0x0010,
118 SBUF_Error = 0x0800,
119 SBUF_Producer_Registered = 0x1000,
120 SBUF_Consumer_Registered = 0x2000,
121 SBUF_Producer_Done = 0x4000,
122 SBUF_Consumer_Done = 0x8000,
123};
124
126typedef struct StreamBuffer {
127 BufRing buf;
128 size_t targetsz;
129
130 sbufPullCB producerPull;
131 sbufCleanupCB producerCleanup;
132 void* producerCtx;
133
134 sbufNotifyCB consumerNotify;
135 sbufPushCB consumerPush;
136 sbufCleanupCB consumerCleanup;
137 void* consumerCtx;
138
139 int refcount;
140 uint32 flags;
141} StreamBuffer;
143
160_Ret_valid_ StreamBuffer* sbufCreate(size_t targetsz);
161
170_At_(*sb, _Pre_maybenull_ _Post_null_) void sbufRelease(_Inout_ StreamBuffer** sb);
171
180void sbufError(_Inout_ StreamBuffer* sb);
181
188_meta_inline bool sbufIsPull(_In_ StreamBuffer* sb)
189{
190 return sb->flags & SBUF_Pull;
191}
192
199_meta_inline bool sbufIsPush(_In_ StreamBuffer* sb)
200{
201 return sb->flags & SBUF_Push;
202}
203
210_meta_inline bool sbufIsError(_In_ StreamBuffer* sb)
211{
212 return sb->flags & SBUF_Error;
213}
214
221_meta_inline bool sbufIsPFinished(_In_ StreamBuffer* sb)
222{
223 return (sb->flags & SBUF_Producer_Done) || sbufIsError(sb);
224}
225
234_meta_inline bool sbufIsCFinished(_In_ StreamBuffer* sb)
235{
236 return (sb->flags & SBUF_Consumer_Done) || sbufIsError(sb);
237}
238
240
246
259_Check_return_ bool sbufPRegisterPull(_Inout_ StreamBuffer* sb, _In_ sbufPullCB ppull,
260 _In_opt_ sbufCleanupCB pcleanup, _Inout_opt_ void* ctx);
261
273_Check_return_ bool sbufPRegisterPush(_Inout_ StreamBuffer* sb, _In_opt_ sbufCleanupCB pcleanup,
274 _Inout_opt_ void* ctx);
275
282size_t sbufPAvail(_In_ StreamBuffer* sb);
283
295bool sbufPWrite(_Inout_ StreamBuffer* sb, _In_reads_bytes_(sz) const uint8* buf, size_t sz);
296
304bool sbufPWriteStr(_Inout_ StreamBuffer* sb, _In_opt_ strref str);
305
315bool sbufPWriteLine(_Inout_ StreamBuffer* sb, _In_opt_ strref str);
316
325bool sbufPWriteEOL(_Inout_ StreamBuffer* sb);
326
335void sbufPFinish(_Pre_valid_ _Post_invalid_ StreamBuffer* sb);
336
338
344
355_Check_return_ bool sbufCRegisterPull(_Inout_ StreamBuffer* sb, _In_opt_ sbufCleanupCB ccleanup,
356 _Inout_opt_ void* ctx);
357
371_Check_return_ bool sbufCRegisterPush(_Inout_ StreamBuffer* sb, _In_ sbufNotifyCB cnotify,
372 _In_opt_ sbufCleanupCB ccleanup, _Inout_opt_ void* ctx);
373
387_Check_return_ bool sbufCRegisterPushDirect(_Inout_ StreamBuffer* sb, _In_ sbufPushCB cpush,
388 _In_opt_ sbufCleanupCB ccleanup, _Inout_opt_ void* ctx);
389
396size_t sbufCAvail(_Inout_ StreamBuffer* sb);
397
412_Success_(return) bool
413sbufCRead(_Inout_ StreamBuffer* sb, _Out_writes_bytes_to_(sz, *bytesread) uint8* buf, size_t sz,
414 _Out_ _Deref_out_range_(0, sz) size_t* bytesread);
415
431_Success_(return > 0) bool
432sbufCPeek(_Inout_ StreamBuffer* sb, _Out_writes_bytes_(sz) uint8* buf, size_t off, size_t sz);
433
444bool sbufCFeed(_Inout_ StreamBuffer* sb, size_t minsz);
445
462bool sbufCSend(_Inout_ StreamBuffer* sb, _In_ sbufSendCB func, size_t sz);
463
473bool sbufCSkip(_Inout_ StreamBuffer* sb, size_t bytes);
474
483void sbufCFinish(_Pre_valid_ _Post_invalid_ StreamBuffer* sb);
484
Ring buffer implementation for efficient streaming I/O.
bool sbufCRegisterPushDirect(StreamBuffer *sb, sbufPushCB cpush, sbufCleanupCB ccleanup, void *ctx)
bool sbufCSend(StreamBuffer *sb, sbufSendCB func, size_t sz)
bool sbufCFeed(StreamBuffer *sb, size_t minsz)
bool sbufCPeek(StreamBuffer *sb, uint8 *buf, size_t off, size_t sz)
size_t sbufCAvail(StreamBuffer *sb)
void sbufCFinish(StreamBuffer *sb)
bool sbufCSkip(StreamBuffer *sb, size_t bytes)
bool sbufCRegisterPush(StreamBuffer *sb, sbufNotifyCB cnotify, sbufCleanupCB ccleanup, void *ctx)
bool sbufCRegisterPull(StreamBuffer *sb, sbufCleanupCB ccleanup, void *ctx)
bool sbufCRead(StreamBuffer *sb, uint8 *buf, size_t sz, size_t *bytesread)
void sbufError(StreamBuffer *sb)
bool sbufIsPFinished(StreamBuffer *sb)
Definition streambuf.h:221
bool sbufIsPush(StreamBuffer *sb)
Definition streambuf.h:199
StreamBuffer * sbufCreate(size_t targetsz)
bool sbufIsCFinished(StreamBuffer *sb)
Definition streambuf.h:234
void sbufRelease(StreamBuffer **sb)
bool sbufIsPull(StreamBuffer *sb)
Definition streambuf.h:188
bool sbufIsError(StreamBuffer *sb)
Definition streambuf.h:210
bool sbufPRegisterPull(StreamBuffer *sb, sbufPullCB ppull, sbufCleanupCB pcleanup, void *ctx)
size_t sbufPAvail(StreamBuffer *sb)
bool sbufPWriteEOL(StreamBuffer *sb)
bool sbufPWriteStr(StreamBuffer *sb, strref str)
void sbufPFinish(StreamBuffer *sb)
bool sbufPWriteLine(StreamBuffer *sb, strref str)
bool sbufPRegisterPush(StreamBuffer *sb, sbufCleanupCB pcleanup, void *ctx)
bool sbufPWrite(StreamBuffer *sb, const uint8 *buf, size_t sz)
Runtime type system and type descriptor infrastructure.