FreeRDP
Loading...
Searching...
No Matches
include/winpr/stream.h
1/*
2 * WinPR: Windows Portable Runtime
3 * Stream Utils
4 *
5 * Copyright 2011 Vic Lee
6 * Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
7 * Copyright 2017 Armin Novak <armin.novak@thincast.com>
8 * Copyright 2017 Thincast Technologies GmbH
9 *
10 * Licensed under the Apache License, Version 2.0 (the "License");
11 * you may not use this file except in compliance with the License.
12 * You may obtain a copy of the License at
13 *
14 * http://www.apache.org/licenses/LICENSE-2.0
15 *
16 * Unless required by applicable law or agreed to in writing, software
17 * distributed under the License is distributed on an "AS IS" BASIS,
18 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19 * See the License for the specific language governing permissions and
20 * limitations under the License.
21 */
22
23#ifndef WINPR_UTILS_STREAM_H
24#define WINPR_UTILS_STREAM_H
25
26#include <winpr/winpr.h>
27#include <winpr/wtypes.h>
28#include <winpr/endian.h>
29#include <winpr/synch.h>
30#include <winpr/assert.h>
31#include <winpr/cast.h>
32#include <winpr/wlog.h>
33
34#ifdef __cplusplus
35extern "C"
36{
37#endif
38
39 typedef struct s_wStreamPool wStreamPool;
40
41 typedef struct
42 {
43 BYTE* buffer;
44 BYTE* pointer;
45 size_t length;
46 size_t capacity;
47
48 DWORD count;
49 wStreamPool* pool;
50 BOOL isAllocatedStream;
51 BOOL isOwner;
52 } wStream;
53
59 WINPR_ATTR_NODISCARD
60 static inline wStream Stream_Init(void)
61 {
62 const wStream empty = { nullptr, nullptr, 0, 0, 0, nullptr, FALSE, FALSE };
63 return empty;
64 }
65
66 WINPR_ATTR_NODISCARD static inline size_t Stream_Capacity(const wStream* _s);
67
68 WINPR_ATTR_NODISCARD
69 WINPR_API size_t Stream_GetRemainingCapacity(const wStream* _s);
70
71 WINPR_ATTR_NODISCARD
72 WINPR_API size_t Stream_GetRemainingLength(const wStream* _s);
73
74 WINPR_ATTR_NODISCARD
75 WINPR_API BOOL Stream_EnsureCapacity(wStream* s, size_t size);
76
77 WINPR_ATTR_NODISCARD
78 WINPR_API BOOL Stream_EnsureRemainingCapacity(wStream* s, size_t size);
79
80#define WINPR_STREAM_CAST(t, val) WINPR_PACKED_ALIGN_CAST(t, val)
81
82#define Stream_CheckAndLogRequiredCapacityOfSize(tag, s, nmemb, size) \
83 Stream_CheckAndLogRequiredCapacityEx(tag, WLOG_WARN, s, nmemb, size, "%s(%s:%" PRIuz ")", \
84 __func__, __FILE__, (size_t)__LINE__)
85#define Stream_CheckAndLogRequiredCapacity(tag, s, len) \
86 Stream_CheckAndLogRequiredCapacityOfSize((tag), (s), (len), 1)
87
88 WINPR_ATTR_NODISCARD
89 WINPR_API BOOL Stream_CheckAndLogRequiredCapacityEx(const char* tag, DWORD level, wStream* s,
90 size_t nmemb, size_t size, const char* fmt,
91 ...);
92
93 WINPR_ATTR_NODISCARD
94 WINPR_API BOOL Stream_CheckAndLogRequiredCapacityExVa(const char* tag, DWORD level, wStream* s,
95 size_t nmemb, size_t size,
96 const char* fmt, va_list args);
97
98#define Stream_CheckAndLogRequiredCapacityOfSizeWLog(log, s, nmemb, size) \
99 Stream_CheckAndLogRequiredCapacityWLogEx(log, WLOG_WARN, s, nmemb, size, "%s(%s:%" PRIuz ")", \
100 __func__, __FILE__, (size_t)__LINE__)
101
102#define Stream_CheckAndLogRequiredCapacityWLog(log, s, len) \
103 Stream_CheckAndLogRequiredCapacityOfSizeWLog((log), (s), (len), 1)
104
105 WINPR_ATTR_NODISCARD
106 WINPR_API BOOL Stream_CheckAndLogRequiredCapacityWLogEx(wLog* log, DWORD level, wStream* s,
107 size_t nmemb, size_t size,
108 const char* fmt, ...);
109
110 WINPR_ATTR_NODISCARD
111 WINPR_API BOOL Stream_CheckAndLogRequiredCapacityWLogExVa(wLog* log, DWORD level, wStream* s,
112 size_t nmemb, size_t size,
113 const char* fmt, va_list args);
114
115 WINPR_API void Stream_Free(wStream* s, BOOL bFreeBuffer);
116
117 WINPR_ATTR_MALLOC(Stream_Free, 1)
118 WINPR_API wStream* Stream_New(BYTE* buffer, size_t size);
119
120 WINPR_API wStream* Stream_StaticConstInit(wStream* s, const BYTE* buffer, size_t size);
121
122 WINPR_API wStream* Stream_StaticInit(wStream* s, BYTE* buffer, size_t size);
123
124#define Stream_CheckAndLogRequiredLengthOfSize(tag, s, nmemb, size) \
125 Stream_CheckAndLogRequiredLengthEx(tag, WLOG_WARN, s, nmemb, size, "%s(%s:%" PRIuz ")", \
126 __func__, __FILE__, (size_t)__LINE__)
127#define Stream_CheckAndLogRequiredLength(tag, s, len) \
128 Stream_CheckAndLogRequiredLengthOfSize(tag, s, len, 1)
129
130 WINPR_ATTR_NODISCARD
131 WINPR_API BOOL Stream_CheckAndLogRequiredLengthEx(const char* tag, DWORD level, wStream* s,
132 size_t nmemb, size_t size, const char* fmt,
133 ...);
134
135 WINPR_ATTR_NODISCARD
136 WINPR_API BOOL Stream_CheckAndLogRequiredLengthExVa(const char* tag, DWORD level, wStream* s,
137 size_t nmemb, size_t size, const char* fmt,
138 va_list args);
139
140#define Stream_CheckAndLogRequiredLengthOfSizeWLog(log, s, nmemb, size) \
141 Stream_CheckAndLogRequiredLengthWLogEx(log, WLOG_WARN, s, nmemb, size, "%s(%s:%" PRIuz ")", \
142 __func__, __FILE__, (size_t)__LINE__)
143#define Stream_CheckAndLogRequiredLengthWLog(log, s, len) \
144 Stream_CheckAndLogRequiredLengthOfSizeWLog(log, s, len, 1)
145
146 WINPR_ATTR_NODISCARD
147 WINPR_API BOOL Stream_CheckAndLogRequiredLengthWLogEx(wLog* log, DWORD level, wStream* s,
148 size_t nmemb, size_t size,
149 const char* fmt, ...);
150
151 WINPR_ATTR_NODISCARD
152 WINPR_API BOOL Stream_CheckAndLogRequiredLengthWLogExVa(wLog* log, DWORD level, wStream* s,
153 size_t nmemb, size_t size,
154 const char* fmt, va_list args);
155
156 static inline void Stream_Seek(wStream* s, size_t _offset)
157 {
158 WINPR_ASSERT(s);
159 WINPR_ASSERT(Stream_GetRemainingCapacity(s) >= _offset);
160 s->pointer += (_offset);
161 }
162
163 static inline void Stream_Rewind(wStream* s, size_t _offset)
164 {
165 WINPR_ASSERT(s);
166 WINPR_ASSERT(s->buffer <= s->pointer);
167 const size_t cur = WINPR_ASSERTING_INT_CAST(size_t, s->pointer - s->buffer);
168 WINPR_ASSERT(cur >= _offset);
169 if (cur >= _offset)
170 s->pointer -= (_offset);
171 else
172 s->pointer = s->buffer;
173 }
174
175 WINPR_ATTR_NODISCARD static inline UINT8 stream_read_u8(wStream* _s, BOOL seek)
176 {
177 WINPR_ASSERT(_s);
178 WINPR_ASSERT(Stream_GetRemainingLength(_s) >= sizeof(UINT8));
179
180 const UINT8 v = winpr_Data_Get_UINT8(_s->pointer);
181 if (seek)
182 Stream_Seek(_s, sizeof(UINT8));
183 return v;
184 }
185
186 WINPR_ATTR_NODISCARD static inline INT8 stream_read_i8(wStream* _s, BOOL seek)
187 {
188 const INT8 v = winpr_Data_Get_INT8(_s->pointer);
189 if (seek)
190 Stream_Seek(_s, sizeof(INT8));
191 return v;
192 }
193
194 WINPR_ATTR_NODISCARD static inline UINT16 stream_read_u16_le(wStream* _s, BOOL seek)
195 {
196 const size_t typesize = sizeof(UINT16);
197 WINPR_ASSERT(_s);
198 WINPR_ASSERT(Stream_GetRemainingLength(_s) >= typesize);
199
200 const UINT16 v = winpr_Data_Get_UINT16(_s->pointer);
201 if (seek)
202 Stream_Seek(_s, typesize);
203 return v;
204 }
205
206 WINPR_ATTR_NODISCARD static inline UINT16 stream_read_u16_be(wStream* _s, BOOL seek)
207 {
208 const size_t typesize = sizeof(UINT16);
209 WINPR_ASSERT(_s);
210 WINPR_ASSERT(Stream_GetRemainingLength(_s) >= typesize);
211
212 const UINT16 v = winpr_Data_Get_UINT16_BE(_s->pointer);
213 if (seek)
214 Stream_Seek(_s, typesize);
215 return v;
216 }
217
218 WINPR_ATTR_NODISCARD static inline INT16 stream_read_i16_le(wStream* _s, BOOL seek)
219 {
220 const size_t typesize = sizeof(INT16);
221 WINPR_ASSERT(_s);
222 WINPR_ASSERT(Stream_GetRemainingLength(_s) >= typesize);
223
224 const INT16 v = winpr_Data_Get_INT16(_s->pointer);
225 if (seek)
226 Stream_Seek(_s, typesize);
227 return v;
228 }
229
230 WINPR_ATTR_NODISCARD static inline INT16 stream_read_i16_be(wStream* _s, BOOL seek)
231 {
232 const size_t typesize = sizeof(INT16);
233 WINPR_ASSERT(_s);
234 WINPR_ASSERT(Stream_GetRemainingLength(_s) >= typesize);
235
236 const INT16 v = winpr_Data_Get_INT16_BE(_s->pointer);
237 if (seek)
238 Stream_Seek(_s, typesize);
239 return v;
240 }
241
242 WINPR_ATTR_NODISCARD static inline UINT32 stream_read_u32_le(wStream* _s, BOOL seek)
243 {
244 const size_t typesize = sizeof(UINT32);
245 WINPR_ASSERT(_s);
246 WINPR_ASSERT(Stream_GetRemainingLength(_s) >= typesize);
247
248 const UINT32 v = winpr_Data_Get_UINT32(_s->pointer);
249 if (seek)
250 Stream_Seek(_s, typesize);
251 return v;
252 }
253
254 WINPR_ATTR_NODISCARD static inline UINT32 stream_read_u32_be(wStream* _s, BOOL seek)
255 {
256 const size_t typesize = sizeof(UINT32);
257 WINPR_ASSERT(_s);
258 WINPR_ASSERT(Stream_GetRemainingLength(_s) >= typesize);
259
260 const UINT32 v = winpr_Data_Get_UINT32_BE(_s->pointer);
261 if (seek)
262 Stream_Seek(_s, typesize);
263 return v;
264 }
265
266 WINPR_ATTR_NODISCARD static inline INT32 stream_read_i32_le(wStream* _s, BOOL seek)
267 {
268 const size_t typesize = sizeof(INT32);
269 WINPR_ASSERT(_s);
270 WINPR_ASSERT(Stream_GetRemainingLength(_s) >= typesize);
271
272 const INT32 v = winpr_Data_Get_INT32(_s->pointer);
273 if (seek)
274 Stream_Seek(_s, typesize);
275 return v;
276 }
277
278 WINPR_ATTR_NODISCARD static inline INT32 stream_read_i32_be(wStream* _s, BOOL seek)
279 {
280 const size_t typesize = sizeof(INT32);
281 WINPR_ASSERT(_s);
282 WINPR_ASSERT(Stream_GetRemainingLength(_s) >= typesize);
283
284 const INT32 v = winpr_Data_Get_INT32_BE(_s->pointer);
285 if (seek)
286 Stream_Seek(_s, typesize);
287 return v;
288 }
289
290 WINPR_ATTR_NODISCARD static inline UINT64 stream_read_u64_le(wStream* _s, BOOL seek)
291 {
292 const size_t typesize = sizeof(UINT64);
293 WINPR_ASSERT(_s);
294 WINPR_ASSERT(Stream_GetRemainingLength(_s) >= typesize);
295
296 const UINT64 v = winpr_Data_Get_UINT64(_s->pointer);
297 if (seek)
298 Stream_Seek(_s, typesize);
299 return v;
300 }
301
302 WINPR_ATTR_NODISCARD static inline UINT64 stream_read_u64_be(wStream* _s, BOOL seek)
303 {
304 const size_t typesize = sizeof(UINT64);
305 WINPR_ASSERT(_s);
306 WINPR_ASSERT(Stream_GetRemainingLength(_s) >= typesize);
307
308 const UINT64 v = winpr_Data_Get_UINT64_BE(_s->pointer);
309 if (seek)
310 Stream_Seek(_s, typesize);
311 return v;
312 }
313
314 WINPR_ATTR_NODISCARD static inline INT64 stream_read_i64_le(wStream* _s, BOOL seek)
315 {
316 const size_t typesize = sizeof(INT64);
317 WINPR_ASSERT(_s);
318 WINPR_ASSERT(Stream_GetRemainingLength(_s) >= typesize);
319
320 const INT64 v = winpr_Data_Get_INT64(_s->pointer);
321 if (seek)
322 Stream_Seek(_s, typesize);
323 return v;
324 }
325
326 WINPR_ATTR_NODISCARD static inline INT64 stream_read_i64_be(wStream* _s, BOOL seek)
327 {
328 const size_t typesize = sizeof(INT64);
329 WINPR_ASSERT(_s);
330 WINPR_ASSERT(Stream_GetRemainingLength(_s) >= typesize);
331
332 const INT64 v = winpr_Data_Get_INT64_BE(_s->pointer);
333 if (seek)
334 Stream_Seek(_s, typesize);
335 return v;
336 }
337
344 WINPR_ATTR_NODISCARD static inline UINT8 Stream_Get_UINT8(wStream* _s)
345 {
346 return stream_read_u8(_s, TRUE);
347 }
348
355 WINPR_ATTR_NODISCARD static inline INT8 Stream_Get_INT8(wStream* _s)
356 {
357 return stream_read_i8(_s, TRUE);
358 }
359
366 WINPR_ATTR_NODISCARD static inline UINT16 Stream_Get_UINT16(wStream* _s)
367 {
368 return stream_read_u16_le(_s, TRUE);
369 }
370
377 WINPR_ATTR_NODISCARD static inline INT16 Stream_Get_INT16(wStream* _s)
378 {
379 return stream_read_i16_le(_s, TRUE);
380 }
381
388 WINPR_ATTR_NODISCARD static inline UINT16 Stream_Get_UINT16_BE(wStream* _s)
389 {
390 return stream_read_u16_be(_s, TRUE);
391 }
392
399 WINPR_ATTR_NODISCARD static inline INT16 Stream_Get_INT16_BE(wStream* _s)
400 {
401 return stream_read_i16_be(_s, TRUE);
402 }
403
410 WINPR_ATTR_NODISCARD static inline UINT32 Stream_Get_UINT32(wStream* _s)
411 {
412 return stream_read_u32_le(_s, TRUE);
413 }
414
421 WINPR_ATTR_NODISCARD static inline INT32 Stream_Get_INT32(wStream* _s)
422 {
423 return stream_read_i32_le(_s, TRUE);
424 }
425
432 WINPR_ATTR_NODISCARD static inline UINT32 Stream_Get_UINT32_BE(wStream* _s)
433 {
434 return stream_read_u32_be(_s, TRUE);
435 }
436
443 WINPR_ATTR_NODISCARD static inline INT32 Stream_Get_INT32_BE(wStream* _s)
444 {
445 return stream_read_i32_be(_s, TRUE);
446 }
447
454 WINPR_ATTR_NODISCARD static inline UINT64 Stream_Get_UINT64(wStream* _s)
455 {
456 return stream_read_u64_le(_s, TRUE);
457 }
458
465 WINPR_ATTR_NODISCARD static inline INT64 Stream_Get_INT64(wStream* _s)
466 {
467 return stream_read_i64_le(_s, TRUE);
468 }
469
476 WINPR_ATTR_NODISCARD static inline UINT64 Stream_Get_UINT64_BE(wStream* _s)
477 {
478 return stream_read_u64_be(_s, TRUE);
479 }
480
487 WINPR_ATTR_NODISCARD static inline INT64 Stream_Get_INT64_BE(wStream* _s)
488 {
489 return stream_read_i64_be(_s, TRUE);
490 }
491
498 WINPR_ATTR_NODISCARD static inline UINT8 Stream_Peek_Get_UINT8(wStream* _s)
499 {
500 return stream_read_u8(_s, FALSE);
501 }
502
509 WINPR_ATTR_NODISCARD static inline INT8 Stream_Peek_Get_INT8(wStream* _s)
510 {
511 return stream_read_i8(_s, FALSE);
512 }
513
520 WINPR_ATTR_NODISCARD static inline UINT16 Stream_Peek_Get_UINT16(wStream* _s)
521 {
522 return stream_read_u16_le(_s, FALSE);
523 }
524
531 WINPR_ATTR_NODISCARD static inline INT16 Stream_Peek_Get_INT16(wStream* _s)
532 {
533 return stream_read_i16_le(_s, FALSE);
534 }
535
542 WINPR_ATTR_NODISCARD static inline UINT16 Stream_Peek_Get_UINT16_BE(wStream* _s)
543 {
544 return stream_read_u16_be(_s, FALSE);
545 }
546
553 WINPR_ATTR_NODISCARD static inline INT16 Stream_Peek_Get_INT16_BE(wStream* _s)
554 {
555 return stream_read_i16_be(_s, FALSE);
556 }
557
564 WINPR_ATTR_NODISCARD static inline UINT32 Stream_Peek_Get_UINT32(wStream* _s)
565 {
566 return stream_read_u32_le(_s, FALSE);
567 }
568
575 WINPR_ATTR_NODISCARD static inline INT32 Stream_Peek_Get_INT32(wStream* _s)
576 {
577 return stream_read_i32_le(_s, FALSE);
578 }
579
586 WINPR_ATTR_NODISCARD static inline UINT32 Stream_Peek_Get_UINT32_BE(wStream* _s)
587 {
588 return stream_read_u32_be(_s, FALSE);
589 }
590
597 WINPR_ATTR_NODISCARD static inline INT32 Stream_Peek_Get_INT32_BE(wStream* _s)
598 {
599 return stream_read_i32_be(_s, FALSE);
600 }
601
608 WINPR_ATTR_NODISCARD static inline UINT64 Stream_Peek_Get_UINT64(wStream* _s)
609 {
610 return stream_read_u64_le(_s, FALSE);
611 }
612
619 WINPR_ATTR_NODISCARD static inline INT64 Stream_Peek_Get_INT64(wStream* _s)
620 {
621 return stream_read_i64_le(_s, FALSE);
622 }
623
630 WINPR_ATTR_NODISCARD static inline UINT64 Stream_Peek_Get_UINT64_BE(wStream* _s)
631 {
632 return stream_read_u64_be(_s, FALSE);
633 }
634
641 WINPR_ATTR_NODISCARD static inline INT64 Stream_Peek_Get_INT64_BE(wStream* _s)
642 {
643 return stream_read_i64_be(_s, FALSE);
644 }
645
646#define Stream_Read_UINT8(_s, _v) \
647 do \
648 { \
649 _v = stream_read_u8(_s, TRUE); \
650 } while (0)
651
652#define Stream_Read_INT8(_s, _v) \
653 do \
654 { \
655 _v = stream_read_i8(_s, TRUE); \
656 } while (0)
657
658#define Stream_Read_UINT16(_s, _v) \
659 do \
660 { \
661 _v = stream_read_u16_le(_s, TRUE); \
662 } while (0)
663
664#define Stream_Read_INT16(_s, _v) \
665 do \
666 { \
667 _v = stream_read_i16_le(_s, TRUE); \
668 } while (0)
669
670#define Stream_Read_UINT16_BE(_s, _v) \
671 do \
672 { \
673 _v = stream_read_u16_be(_s, TRUE); \
674 } while (0)
675
676#define Stream_Read_INT16_BE(_s, _v) \
677 do \
678 { \
679 _v = stream_read_i16_be(_s, TRUE); \
680 } while (0)
681
682#define Stream_Read_UINT32(_s, _v) \
683 do \
684 { \
685 _v = stream_read_u32_le(_s, TRUE); \
686 } while (0)
687
688#define Stream_Read_INT32(_s, _v) \
689 do \
690 { \
691 _v = stream_read_i32_le(_s, TRUE); \
692 } while (0)
693
694#define Stream_Read_UINT32_BE(_s, _v) \
695 do \
696 { \
697 _v = stream_read_u32_be(_s, TRUE); \
698 } while (0)
699
700#define Stream_Read_INT32_BE(_s, _v) \
701 do \
702 { \
703 _v = stream_read_i32_be(_s, TRUE); \
704 } while (0)
705
706#define Stream_Read_UINT64(_s, _v) \
707 do \
708 { \
709 _v = stream_read_u64_le(_s, TRUE); \
710 } while (0)
711
712#define Stream_Read_INT64(_s, _v) \
713 do \
714 { \
715 _v = stream_read_i64_le(_s, TRUE); \
716 } while (0)
717
718#define Stream_Read_UINT64_BE(_s, _v) \
719 do \
720 { \
721 _v = stream_read_u64_be(_s, TRUE); \
722 } while (0)
723
724#define Stream_Read_INT64_BE(_s, _v) \
725 do \
726 { \
727 _v = stream_read_i64_be(_s, TRUE); \
728 } while (0)
729
730 static inline void Stream_Read(wStream* _s, void* _b, size_t _n)
731 {
732 WINPR_ASSERT(_s);
733 WINPR_ASSERT(_b || (_n == 0));
734 WINPR_ASSERT(Stream_GetRemainingCapacity(_s) >= _n);
735 memcpy(_b, (_s->pointer), (_n));
736 Stream_Seek(_s, _n);
737 }
738
739#define Stream_Peek_UINT8(_s, _v) \
740 do \
741 { \
742 _v = stream_read_u8(_s, FALSE); \
743 } while (0)
744
745#define Stream_Peek_INT8(_s, _v) \
746 do \
747 { \
748 _v = stream_read_i8(_s, FALSE); \
749 } while (0)
750
751#define Stream_Peek_UINT16(_s, _v) \
752 do \
753 { \
754 _v = stream_read_u16_le(_s, FALSE); \
755 } while (0)
756
757#define Stream_Peek_INT16(_s, _v) \
758 do \
759 { \
760 _v = stream_read_i16_le(_s, FALSE); \
761 } while (0)
762
763#define Stream_Peek_UINT16_BE(_s, _v) \
764 do \
765 { \
766 _v = stream_read_u16_be(_s, FALSE); \
767 } while (0)
768
769#define Stream_Peek_INT16_BE(_s, _v) \
770 do \
771 { \
772 _v = stream_read_i16_be(_s, FALSE); \
773 } while (0)
774
775#define Stream_Peek_UINT32(_s, _v) \
776 do \
777 { \
778 _v = stream_read_u32_le(_s, FALSE); \
779 } while (0)
780
781#define Stream_Peek_INT32(_s, _v) \
782 do \
783 { \
784 _v = stream_read_i32_le(_s, FALSE); \
785 } while (0)
786
787#define Stream_Peek_UINT32_BE(_s, _v) \
788 do \
789 { \
790 _v = stream_read_u32_be(_s, FALSE); \
791 } while (0)
792
793#define Stream_Peek_INT32_BE(_s, _v) \
794 do \
795 { \
796 _v = stream_read_i32_be(_s, FALSE); \
797 } while (0)
798
799#define Stream_Peek_UINT64(_s, _v) \
800 do \
801 { \
802 _v = stream_read_u64_le(_s, FALSE); \
803 } while (0)
804
805#define Stream_Peek_INT64(_s, _v) \
806 do \
807 { \
808 _v = stream_read_i64_le(_s, FALSE); \
809 } while (0)
810
811#define Stream_Peek_UINT64_BE(_s, _v) \
812 do \
813 { \
814 _v = stream_read_u64_be(_s, FALSE); \
815 } while (0)
816
817#define Stream_Peek_INT64_BE(_s, _v) \
818 do \
819 { \
820 _v = stream_read_i64_be(_s, FALSE); \
821 } while (0)
822
823 static inline void Stream_Peek(const wStream* _s, void* _b, size_t _n)
824 {
825 WINPR_ASSERT(_s);
826 WINPR_ASSERT(_b || (_n == 0));
827 WINPR_ASSERT(Stream_GetRemainingCapacity(_s) >= _n);
828 memcpy(_b, (_s->pointer), (_n));
829 }
830
831#define Stream_Write_INT8(s, v) \
832 do \
833 { \
834 WINPR_ASSERT((v) <= INT8_MAX); \
835 WINPR_ASSERT((v) >= INT8_MIN); \
836 Stream_Write_INT8_unchecked((s), (v)); \
837 } while (0)
838
846 static inline void Stream_Write_INT8_unchecked(wStream* _s, INT8 _v)
847 {
848 WINPR_ASSERT(_s);
849 WINPR_ASSERT(_s->pointer);
850 WINPR_ASSERT(Stream_GetRemainingCapacity(_s) >= 1);
851
852 winpr_Data_Write_INT8(_s->pointer, _v);
853 _s->pointer += 1;
854 }
855
856#define Stream_Write_UINT8(s, v) \
857 do \
858 { \
859 WINPR_ASSERT((v) <= UINT8_MAX); \
860 WINPR_ASSERT((v) >= 0); \
861 Stream_Write_UINT8_unchecked((s), (v)); \
862 } while (0)
863
871 static inline void Stream_Write_UINT8_unchecked(wStream* _s, UINT8 _v)
872 {
873 WINPR_ASSERT(_s);
874 WINPR_ASSERT(_s->pointer);
875 WINPR_ASSERT(Stream_GetRemainingCapacity(_s) >= 1);
876
877 winpr_Data_Write_UINT8(_s->pointer, _v);
878 _s->pointer += 1;
879 }
880
881#define Stream_Write_INT16(s, v) \
882 do \
883 { \
884 WINPR_ASSERT((v) >= INT16_MIN); \
885 WINPR_ASSERT((v) <= INT16_MAX); \
886 Stream_Write_INT16_unchecked((s), (v)); \
887 } while (0)
888
897 static inline void Stream_Write_INT16_unchecked(wStream* _s, INT16 _v)
898 {
899 WINPR_ASSERT(_s);
900 WINPR_ASSERT(_s->pointer);
901 WINPR_ASSERT(Stream_GetRemainingCapacity(_s) >= 2);
902
903 winpr_Data_Write_INT16(_s->pointer, _v);
904 _s->pointer += 2;
905 }
906
907#define Stream_Write_UINT16(s, v) \
908 do \
909 { \
910 WINPR_ASSERT((v) <= UINT16_MAX); \
911 WINPR_ASSERT((v) >= 0); \
912 Stream_Write_UINT16_unchecked((s), (v)); \
913 } while (0)
914
923 static inline void Stream_Write_UINT16_unchecked(wStream* _s, UINT16 _v)
924 {
925 WINPR_ASSERT(_s);
926 WINPR_ASSERT(_s->pointer);
927 WINPR_ASSERT(Stream_GetRemainingCapacity(_s) >= 2);
928
929 winpr_Data_Write_UINT16(_s->pointer, _v);
930 _s->pointer += 2;
931 }
932
933#define Stream_Write_UINT16_BE(s, v) \
934 do \
935 { \
936 WINPR_ASSERT((v) <= UINT16_MAX); \
937 WINPR_ASSERT((v) >= 0); \
938 Stream_Write_UINT16_BE_unchecked((s), (v)); \
939 } while (0)
940
949 static inline void Stream_Write_UINT16_BE_unchecked(wStream* _s, UINT16 _v)
950 {
951 WINPR_ASSERT(_s);
952 WINPR_ASSERT(_s->pointer);
953 WINPR_ASSERT(Stream_GetRemainingCapacity(_s) >= 2);
954
955 winpr_Data_Write_UINT16_BE(_s->pointer, _v);
956 _s->pointer += 2;
957 }
958
959#define Stream_Write_INT16_BE(s, v) \
960 do \
961 { \
962 WINPR_ASSERT((v) <= INT16_MAX); \
963 WINPR_ASSERT((v) >= INT16_MIN); \
964 Stream_Write_INT16_BE_unchecked((s), (v)); \
965 } while (0)
966
977 static inline void Stream_Write_INT16_BE_unchecked(wStream* _s, INT16 _v)
978 {
979 WINPR_ASSERT(_s);
980 WINPR_ASSERT(_s->pointer);
981 WINPR_ASSERT(Stream_GetRemainingCapacity(_s) >= 2);
982
983 winpr_Data_Write_INT16_BE(_s->pointer, _v);
984 _s->pointer += 2;
985 }
986
987#define Stream_Write_UINT24_BE(s, v) \
988 do \
989 { \
990 WINPR_ASSERT((v) <= 0xFFFFFF); \
991 WINPR_ASSERT((v) >= 0); \
992 Stream_Write_UINT24_BE_unchecked((s), (v)); \
993 } while (0)
994
1003 static inline void Stream_Write_UINT24_BE_unchecked(wStream* _s, UINT32 _v)
1004 {
1005 WINPR_ASSERT(_s);
1006 WINPR_ASSERT(_s->pointer);
1007 WINPR_ASSERT(_v <= 0x00FFFFFF);
1008 WINPR_ASSERT(Stream_GetRemainingCapacity(_s) >= 3);
1009
1010 *_s->pointer++ = ((_v) >> 16) & 0xFF;
1011 *_s->pointer++ = ((_v) >> 8) & 0xFF;
1012 *_s->pointer++ = (_v) & 0xFF;
1013 }
1014
1015#define Stream_Write_INT32(s, v) \
1016 do \
1017 { \
1018 WINPR_ASSERT((v) <= INT32_MAX); \
1019 WINPR_ASSERT((v) >= INT32_MIN); \
1020 Stream_Write_INT32_unchecked((s), (v)); \
1021 } while (0)
1022
1031 static inline void Stream_Write_INT32_unchecked(wStream* _s, INT32 _v)
1032 {
1033 WINPR_ASSERT(_s);
1034 WINPR_ASSERT(_s->pointer);
1035 WINPR_ASSERT(Stream_GetRemainingCapacity(_s) >= 4);
1036
1037 winpr_Data_Write_INT32(_s->pointer, _v);
1038 _s->pointer += 4;
1039 }
1040
1041#define Stream_Write_INT32_BE(s, v) \
1042 do \
1043 { \
1044 WINPR_ASSERT((v) <= INT32_MAX); \
1045 WINPR_ASSERT((v) >= INT32_MIN); \
1046 Stream_Write_INT32_BE_unchecked((s), (v)); \
1047 } while (0)
1048
1059 static inline void Stream_Write_INT32_BE_unchecked(wStream* _s, INT32 _v)
1060 {
1061 WINPR_ASSERT(_s);
1062 WINPR_ASSERT(_s->pointer);
1063 WINPR_ASSERT(Stream_GetRemainingCapacity(_s) >= 4);
1064
1065 winpr_Data_Write_INT32_BE(_s->pointer, _v);
1066 _s->pointer += 4;
1067 }
1068
1069#define Stream_Write_UINT32(s, v) \
1070 do \
1071 { \
1072 WINPR_ASSERT((v) <= UINT32_MAX); \
1073 WINPR_ASSERT((v) >= 0); \
1074 Stream_Write_UINT32_unchecked((s), (v)); \
1075 } while (0)
1076
1085 static inline void Stream_Write_UINT32_unchecked(wStream* _s, UINT32 _v)
1086 {
1087 WINPR_ASSERT(_s);
1088 WINPR_ASSERT(_s->pointer);
1089 WINPR_ASSERT(Stream_GetRemainingCapacity(_s) >= 4);
1090
1091 winpr_Data_Write_UINT32(_s->pointer, _v);
1092 _s->pointer += 4;
1093 }
1094
1095#define Stream_Write_UINT32_BE(s, v) \
1096 do \
1097 { \
1098 WINPR_ASSERT((v) <= UINT32_MAX); \
1099 WINPR_ASSERT((v) >= 0); \
1100 Stream_Write_UINT32_BE_unchecked((s), (v)); \
1101 } while (0)
1102
1111 static inline void Stream_Write_UINT32_BE_unchecked(wStream* _s, UINT32 _v)
1112 {
1113 WINPR_ASSERT(Stream_GetRemainingCapacity(_s) >= 4);
1114
1115 winpr_Data_Write_UINT32_BE(_s->pointer, _v);
1116 _s->pointer += 4;
1117 }
1118
1125 static inline void Stream_Write_UINT64(wStream* _s, UINT64 _v)
1126 {
1127 WINPR_ASSERT(_s);
1128 WINPR_ASSERT(_s->pointer);
1129 WINPR_ASSERT(Stream_GetRemainingCapacity(_s) >= 8);
1130
1131 winpr_Data_Write_UINT64(_s->pointer, _v);
1132 _s->pointer += 8;
1133 }
1134
1141 static inline void Stream_Write_UINT64_BE(wStream* _s, UINT64 _v)
1142 {
1143 WINPR_ASSERT(_s);
1144 WINPR_ASSERT(_s->pointer);
1145 WINPR_ASSERT(Stream_GetRemainingCapacity(_s) >= 8);
1146
1147 winpr_Data_Write_UINT64_BE(_s->pointer, _v);
1148 _s->pointer += 8;
1149 }
1150
1158 static inline void Stream_Write_INT64(wStream* _s, INT64 _v)
1159 {
1160 WINPR_ASSERT(_s);
1161 WINPR_ASSERT(_s->pointer);
1162 WINPR_ASSERT(Stream_GetRemainingCapacity(_s) >= 8);
1163
1164 winpr_Data_Write_INT64(_s->pointer, _v);
1165 _s->pointer += 8;
1166 }
1167
1175 static inline void Stream_Write_INT64_BE(wStream* _s, INT64 _v)
1176 {
1177 WINPR_ASSERT(_s);
1178 WINPR_ASSERT(_s->pointer);
1179 WINPR_ASSERT(Stream_GetRemainingCapacity(_s) >= 8);
1180
1181 winpr_Data_Write_INT64_BE(_s->pointer, _v);
1182 _s->pointer += 8;
1183 }
1184
1185 static inline void Stream_Write(wStream* _s, const void* _b, size_t _n)
1186 {
1187 if (_n > 0)
1188 {
1189 WINPR_ASSERT(_s);
1190 WINPR_ASSERT(_b);
1191 WINPR_ASSERT(Stream_GetRemainingCapacity(_s) >= _n);
1192 memcpy(_s->pointer, (_b), (_n));
1193 Stream_Seek(_s, _n);
1194 }
1195 }
1196
1197 static inline void Stream_Seek_UINT8(wStream* _s)
1198 {
1199 Stream_Seek(_s, sizeof(UINT8));
1200 }
1201 static inline void Stream_Seek_UINT16(wStream* _s)
1202 {
1203 Stream_Seek(_s, sizeof(UINT16));
1204 }
1205 static inline void Stream_Seek_UINT32(wStream* _s)
1206 {
1207 Stream_Seek(_s, sizeof(UINT32));
1208 }
1209 static inline void Stream_Seek_UINT64(wStream* _s)
1210 {
1211 Stream_Seek(_s, sizeof(UINT64));
1212 }
1213
1214 static inline void Stream_Rewind_UINT8(wStream* _s)
1215 {
1216 Stream_Rewind(_s, sizeof(UINT8));
1217 }
1218 static inline void Stream_Rewind_UINT16(wStream* _s)
1219 {
1220 Stream_Rewind(_s, sizeof(UINT16));
1221 }
1222 static inline void Stream_Rewind_UINT32(wStream* _s)
1223 {
1224 Stream_Rewind(_s, sizeof(UINT32));
1225 }
1226 static inline void Stream_Rewind_UINT64(wStream* _s)
1227 {
1228 Stream_Rewind(_s, sizeof(UINT64));
1229 }
1230
1231 static inline void Stream_Fill(wStream* _s, int _v, size_t _n)
1232 {
1233 WINPR_ASSERT(_s);
1234 WINPR_ASSERT(Stream_GetRemainingCapacity(_s) >= (_n));
1235 memset(_s->pointer, _v, (_n));
1236 Stream_Seek(_s, _n);
1237 }
1238
1239 static inline void Stream_Zero(wStream* _s, size_t _n)
1240 {
1241 Stream_Fill(_s, '\0', _n);
1242 }
1243
1244#define Stream_SafeZero(s, size) Stream_SafeZeroEx(s, size, __FILE__, __LINE__, __func__)
1245
1261 WINPR_ATTR_NODISCARD
1262 WINPR_API BOOL Stream_SafeZeroEx(wStream* s, size_t size, const char* file, size_t line,
1263 const char* fkt);
1264
1265 static inline void Stream_Copy(wStream* _src, wStream* _dst, size_t _n)
1266 {
1267 WINPR_ASSERT(_src);
1268 WINPR_ASSERT(_dst);
1269 WINPR_ASSERT(Stream_GetRemainingCapacity(_src) >= (_n));
1270 WINPR_ASSERT(Stream_GetRemainingCapacity(_dst) >= (_n));
1271
1272 memcpy(_dst->pointer, _src->pointer, _n);
1273 Stream_Seek(_dst, _n);
1274 Stream_Seek(_src, _n);
1275 }
1276
1281#define Stream_BufferAs(s, type) WINPR_STREAM_CAST(type*, Stream_Buffer(s))
1282
1283 WINPR_ATTR_NODISCARD static inline BYTE* Stream_Buffer(wStream* _s)
1284 {
1285 WINPR_ASSERT(_s);
1286 return _s->buffer;
1287 }
1288
1293#define Stream_ConstBufferAs(s, type) WINPR_STREAM_CAST(type*, Stream_ConstBuffer(s))
1294 WINPR_ATTR_NODISCARD static inline const BYTE* Stream_ConstBuffer(const wStream* _s)
1295 {
1296 WINPR_ASSERT(_s);
1297 return _s->buffer;
1298 }
1299
1300#define Stream_GetBuffer(_s, _b) _b = Stream_Buffer(_s)
1301
1306#define Stream_GetBufferAs(_s, _b) _b = Stream_BufferAs(_s, __typeof(_b))
1307
1308#define Stream_PointerAs(s, type) WINPR_STREAM_CAST(type*, Stream_Pointer(s))
1309
1310 WINPR_ATTR_NODISCARD static inline void* Stream_Pointer(wStream* _s)
1311 {
1312 WINPR_ASSERT(_s);
1313 return _s->pointer;
1314 }
1315
1316 WINPR_ATTR_NODISCARD static inline const void* Stream_ConstPointer(const wStream* _s)
1317 {
1318 WINPR_ASSERT(_s);
1319 return _s->pointer;
1320 }
1321
1322#define Stream_GetPointer(_s, _p) _p = Stream_Pointer(_s)
1323
1328#define Stream_GetPointerAs(_s, _p) _p = Stream_PointerAs(_s, __typeof(_p))
1329
1330#if defined(WITH_WINPR_DEPRECATED)
1331 WINPR_DEPRECATED_VAR("Use Stream_SetPosition instead",
1332 WINPR_ATTR_NODISCARD WINPR_API BOOL Stream_SetPointer(wStream* _s,
1333 BYTE* _p));
1334
1335 WINPR_DEPRECATED_VAR("Use Stream_New(buffer, capacity) instead",
1336 WINPR_ATTR_NODISCARD WINPR_API BOOL Stream_SetBuffer(wStream* _s,
1337 BYTE* _b));
1338
1339 WINPR_DEPRECATED_VAR("Use Stream_New(buffer, capacity) instead",
1340 WINPR_API void Stream_SetCapacity(wStream* _s, size_t capacity));
1341#endif
1342
1343 WINPR_ATTR_NODISCARD static inline size_t Stream_Length(const wStream* _s)
1344 {
1345 WINPR_ASSERT(_s);
1346 return _s->length;
1347 }
1348
1349#define Stream_GetLength(_s, _l) _l = Stream_Length(_s)
1350 WINPR_ATTR_NODISCARD
1351 WINPR_API BOOL Stream_SetLength(wStream* _s, size_t _l);
1352
1353 WINPR_ATTR_NODISCARD static inline size_t Stream_Capacity(const wStream* _s)
1354 {
1355 WINPR_ASSERT(_s);
1356 return _s->capacity;
1357 }
1358
1359#define Stream_GetCapacity(_s, _c) _c = Stream_Capacity(_s);
1360
1361 WINPR_ATTR_NODISCARD static inline size_t Stream_GetPosition(const wStream* _s)
1362 {
1363 WINPR_ASSERT(_s);
1364 WINPR_ASSERT(_s->buffer <= _s->pointer);
1365 return WINPR_ASSERTING_INT_CAST(size_t, (_s->pointer - _s->buffer));
1366 }
1367
1376 static inline void Stream_ResetPosition(wStream* _s)
1377 {
1378 WINPR_ASSERT(_s);
1379 _s->pointer = _s->buffer;
1380 }
1381
1382 WINPR_ATTR_NODISCARD
1383 WINPR_API BOOL Stream_SetPosition(wStream* _s, size_t _p);
1384
1385 WINPR_API void Stream_SealLength(wStream* _s);
1386
1387 static inline void Stream_Clear(wStream* _s)
1388 {
1389 WINPR_ASSERT(_s);
1390 memset(_s->buffer, 0, _s->capacity);
1391 }
1392
1393#define Stream_SafeSeek(s, size) Stream_SafeSeekEx(s, size, __FILE__, __LINE__, __func__)
1394 WINPR_ATTR_NODISCARD
1395 WINPR_API BOOL Stream_SafeSeekEx(wStream* s, size_t size, const char* file, size_t line,
1396 const char* fkt);
1397
1398 WINPR_ATTR_NODISCARD
1399 WINPR_API BOOL Stream_Read_UTF16_String(wStream* s, WCHAR* dst, size_t charLength);
1400
1401 WINPR_ATTR_NODISCARD
1402 WINPR_API BOOL Stream_Write_UTF16_String(wStream* s, const WCHAR* src, size_t charLength);
1403
1413 WINPR_ATTR_MALLOC(free, 1)
1414 WINPR_API char* Stream_Read_UTF16_String_As_UTF8(wStream* s, size_t wcharLength,
1415 size_t* pUtfCharLength);
1416
1426 WINPR_ATTR_NODISCARD
1427 WINPR_API SSIZE_T Stream_Read_UTF16_String_As_UTF8_Buffer(wStream* s, size_t wcharLength,
1428 char* utfBuffer,
1429 size_t utfBufferCharLength);
1430
1445 WINPR_ATTR_NODISCARD
1446 WINPR_API SSIZE_T Stream_Write_UTF16_String_From_UTF8(wStream* s, size_t wcharLength,
1447 const char* src, size_t length,
1448 BOOL fill);
1449
1450 /* StreamPool */
1451
1452 WINPR_API void StreamPool_Return(wStreamPool* pool, wStream* s);
1453
1459 WINPR_API void Stream_AddRef(wStream* s);
1460
1468 WINPR_API void Stream_Release(wStream* s);
1469
1470 WINPR_ATTR_MALLOC(Stream_Release, 1)
1471 WINPR_ATTR_NODISCARD
1472 WINPR_API wStream* StreamPool_Take(wStreamPool* pool, size_t size);
1473
1474 WINPR_ATTR_NODISCARD
1475 WINPR_API wStream* StreamPool_Find(wStreamPool* pool, const BYTE* ptr);
1476
1485 WINPR_ATTR_NODISCARD
1486 WINPR_API size_t StreamPool_UsedCount(wStreamPool* pool);
1487
1498 WINPR_API BOOL StreamPool_WaitForReturn(wStreamPool* pool, UINT32 timeoutMS);
1499
1500 WINPR_API void StreamPool_Clear(wStreamPool* pool);
1501
1502 WINPR_API void StreamPool_Free(wStreamPool* pool);
1503
1504 WINPR_ATTR_MALLOC(StreamPool_Free, 1)
1505 WINPR_API wStreamPool* StreamPool_New(BOOL synchronized, size_t defaultSize);
1506
1507 WINPR_API char* StreamPool_GetStatistics(wStreamPool* pool, char* buffer, size_t size);
1508
1509#ifdef __cplusplus
1510}
1511#endif
1512
1513#endif /* WINPR_UTILS_STREAM_H */