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_CXX_COMPAT_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 size_t cur = 0;
166 WINPR_ASSERT(s);
167 WINPR_ASSERT(s->buffer <= s->pointer);
168 cur = WINPR_STREAM_CAST(size_t, s->pointer - s->buffer);
169 WINPR_ASSERT(cur >= _offset);
170 if (cur >= _offset)
171 s->pointer -= (_offset);
172 else
173 s->pointer = s->buffer;
174 }
175
176 WINPR_ATTR_NODISCARD static inline UINT8 stream_read_u8(wStream* _s, BOOL seek)
177 {
178 WINPR_ASSERT(_s);
179 WINPR_ASSERT(Stream_GetRemainingLength(_s) >= sizeof(UINT8));
180
181 const UINT8 v = winpr_Data_Get_UINT8(_s->pointer);
182 if (seek)
183 Stream_Seek(_s, sizeof(UINT8));
184 return v;
185 }
186
187 WINPR_ATTR_NODISCARD static inline INT8 stream_read_i8(wStream* _s, BOOL seek)
188 {
189 const INT8 v = winpr_Data_Get_INT8(_s->pointer);
190 if (seek)
191 Stream_Seek(_s, sizeof(INT8));
192 return v;
193 }
194
195 WINPR_ATTR_NODISCARD static inline UINT16 stream_read_u16_le(wStream* _s, BOOL seek)
196 {
197 const size_t typesize = sizeof(UINT16);
198 WINPR_ASSERT(_s);
199 WINPR_ASSERT(Stream_GetRemainingLength(_s) >= typesize);
200
201 const UINT16 v = winpr_Data_Get_UINT16(_s->pointer);
202 if (seek)
203 Stream_Seek(_s, typesize);
204 return v;
205 }
206
207 WINPR_ATTR_NODISCARD static inline UINT16 stream_read_u16_be(wStream* _s, BOOL seek)
208 {
209 const size_t typesize = sizeof(UINT16);
210 WINPR_ASSERT(_s);
211 WINPR_ASSERT(Stream_GetRemainingLength(_s) >= typesize);
212
213 const UINT16 v = winpr_Data_Get_UINT16_BE(_s->pointer);
214 if (seek)
215 Stream_Seek(_s, typesize);
216 return v;
217 }
218
219 WINPR_ATTR_NODISCARD static inline INT16 stream_read_i16_le(wStream* _s, BOOL seek)
220 {
221 const size_t typesize = sizeof(INT16);
222 WINPR_ASSERT(_s);
223 WINPR_ASSERT(Stream_GetRemainingLength(_s) >= typesize);
224
225 const INT16 v = winpr_Data_Get_INT16(_s->pointer);
226 if (seek)
227 Stream_Seek(_s, typesize);
228 return v;
229 }
230
231 WINPR_ATTR_NODISCARD static inline INT16 stream_read_i16_be(wStream* _s, BOOL seek)
232 {
233 const size_t typesize = sizeof(INT16);
234 WINPR_ASSERT(_s);
235 WINPR_ASSERT(Stream_GetRemainingLength(_s) >= typesize);
236
237 const INT16 v = winpr_Data_Get_INT16_BE(_s->pointer);
238 if (seek)
239 Stream_Seek(_s, typesize);
240 return v;
241 }
242
243 WINPR_ATTR_NODISCARD static inline UINT32 stream_read_u32_le(wStream* _s, BOOL seek)
244 {
245 const size_t typesize = sizeof(UINT32);
246 WINPR_ASSERT(_s);
247 WINPR_ASSERT(Stream_GetRemainingLength(_s) >= typesize);
248
249 const UINT32 v = winpr_Data_Get_UINT32(_s->pointer);
250 if (seek)
251 Stream_Seek(_s, typesize);
252 return v;
253 }
254
255 WINPR_ATTR_NODISCARD static inline UINT32 stream_read_u32_be(wStream* _s, BOOL seek)
256 {
257 const size_t typesize = sizeof(UINT32);
258 WINPR_ASSERT(_s);
259 WINPR_ASSERT(Stream_GetRemainingLength(_s) >= typesize);
260
261 const UINT32 v = winpr_Data_Get_UINT32_BE(_s->pointer);
262 if (seek)
263 Stream_Seek(_s, typesize);
264 return v;
265 }
266
267 WINPR_ATTR_NODISCARD static inline INT32 stream_read_i32_le(wStream* _s, BOOL seek)
268 {
269 const size_t typesize = sizeof(INT32);
270 WINPR_ASSERT(_s);
271 WINPR_ASSERT(Stream_GetRemainingLength(_s) >= typesize);
272
273 const INT32 v = winpr_Data_Get_INT32(_s->pointer);
274 if (seek)
275 Stream_Seek(_s, typesize);
276 return v;
277 }
278
279 WINPR_ATTR_NODISCARD static inline INT32 stream_read_i32_be(wStream* _s, BOOL seek)
280 {
281 const size_t typesize = sizeof(INT32);
282 WINPR_ASSERT(_s);
283 WINPR_ASSERT(Stream_GetRemainingLength(_s) >= typesize);
284
285 const INT32 v = winpr_Data_Get_INT32_BE(_s->pointer);
286 if (seek)
287 Stream_Seek(_s, typesize);
288 return v;
289 }
290
291 WINPR_ATTR_NODISCARD static inline UINT64 stream_read_u64_le(wStream* _s, BOOL seek)
292 {
293 const size_t typesize = sizeof(UINT64);
294 WINPR_ASSERT(_s);
295 WINPR_ASSERT(Stream_GetRemainingLength(_s) >= typesize);
296
297 const UINT64 v = winpr_Data_Get_UINT64(_s->pointer);
298 if (seek)
299 Stream_Seek(_s, typesize);
300 return v;
301 }
302
303 WINPR_ATTR_NODISCARD static inline UINT64 stream_read_u64_be(wStream* _s, BOOL seek)
304 {
305 const size_t typesize = sizeof(UINT64);
306 WINPR_ASSERT(_s);
307 WINPR_ASSERT(Stream_GetRemainingLength(_s) >= typesize);
308
309 const UINT64 v = winpr_Data_Get_UINT64_BE(_s->pointer);
310 if (seek)
311 Stream_Seek(_s, typesize);
312 return v;
313 }
314
315 WINPR_ATTR_NODISCARD static inline INT64 stream_read_i64_le(wStream* _s, BOOL seek)
316 {
317 const size_t typesize = sizeof(INT64);
318 WINPR_ASSERT(_s);
319 WINPR_ASSERT(Stream_GetRemainingLength(_s) >= typesize);
320
321 const INT64 v = winpr_Data_Get_INT64(_s->pointer);
322 if (seek)
323 Stream_Seek(_s, typesize);
324 return v;
325 }
326
327 WINPR_ATTR_NODISCARD static inline INT64 stream_read_i64_be(wStream* _s, BOOL seek)
328 {
329 const size_t typesize = sizeof(INT64);
330 WINPR_ASSERT(_s);
331 WINPR_ASSERT(Stream_GetRemainingLength(_s) >= typesize);
332
333 const INT64 v = winpr_Data_Get_INT64_BE(_s->pointer);
334 if (seek)
335 Stream_Seek(_s, typesize);
336 return v;
337 }
338
345 WINPR_ATTR_NODISCARD static inline UINT8 Stream_Get_UINT8(wStream* _s)
346 {
347 return stream_read_u8(_s, TRUE);
348 }
349
356 WINPR_ATTR_NODISCARD static inline INT8 Stream_Get_INT8(wStream* _s)
357 {
358 return stream_read_i8(_s, TRUE);
359 }
360
367 WINPR_ATTR_NODISCARD static inline UINT16 Stream_Get_UINT16(wStream* _s)
368 {
369 return stream_read_u16_le(_s, TRUE);
370 }
371
378 WINPR_ATTR_NODISCARD static inline INT16 Stream_Get_INT16(wStream* _s)
379 {
380 return stream_read_i16_le(_s, TRUE);
381 }
382
389 WINPR_ATTR_NODISCARD static inline UINT16 Stream_Get_UINT16_BE(wStream* _s)
390 {
391 return stream_read_u16_be(_s, TRUE);
392 }
393
400 WINPR_ATTR_NODISCARD static inline INT16 Stream_Get_INT16_BE(wStream* _s)
401 {
402 return stream_read_i16_be(_s, TRUE);
403 }
404
411 WINPR_ATTR_NODISCARD static inline UINT32 Stream_Get_UINT32(wStream* _s)
412 {
413 return stream_read_u32_le(_s, TRUE);
414 }
415
422 WINPR_ATTR_NODISCARD static inline INT32 Stream_Get_INT32(wStream* _s)
423 {
424 return stream_read_i32_le(_s, TRUE);
425 }
426
433 WINPR_ATTR_NODISCARD static inline UINT32 Stream_Get_UINT32_BE(wStream* _s)
434 {
435 return stream_read_u32_be(_s, TRUE);
436 }
437
444 WINPR_ATTR_NODISCARD static inline INT32 Stream_Get_INT32_BE(wStream* _s)
445 {
446 return stream_read_i32_be(_s, TRUE);
447 }
448
455 WINPR_ATTR_NODISCARD static inline UINT64 Stream_Get_UINT64(wStream* _s)
456 {
457 return stream_read_u64_le(_s, TRUE);
458 }
459
466 WINPR_ATTR_NODISCARD static inline INT64 Stream_Get_INT64(wStream* _s)
467 {
468 return stream_read_i64_le(_s, TRUE);
469 }
470
477 WINPR_ATTR_NODISCARD static inline UINT64 Stream_Get_UINT64_BE(wStream* _s)
478 {
479 return stream_read_u64_be(_s, TRUE);
480 }
481
488 WINPR_ATTR_NODISCARD static inline INT64 Stream_Get_INT64_BE(wStream* _s)
489 {
490 return stream_read_i64_be(_s, TRUE);
491 }
492
499 WINPR_ATTR_NODISCARD static inline UINT8 Stream_Peek_Get_UINT8(wStream* _s)
500 {
501 return stream_read_u8(_s, FALSE);
502 }
503
510 WINPR_ATTR_NODISCARD static inline INT8 Stream_Peek_Get_INT8(wStream* _s)
511 {
512 return stream_read_i8(_s, FALSE);
513 }
514
521 WINPR_ATTR_NODISCARD static inline UINT16 Stream_Peek_Get_UINT16(wStream* _s)
522 {
523 return stream_read_u16_le(_s, FALSE);
524 }
525
532 WINPR_ATTR_NODISCARD static inline INT16 Stream_Peek_Get_INT16(wStream* _s)
533 {
534 return stream_read_i16_le(_s, FALSE);
535 }
536
543 WINPR_ATTR_NODISCARD static inline UINT16 Stream_Peek_Get_UINT16_BE(wStream* _s)
544 {
545 return stream_read_u16_be(_s, FALSE);
546 }
547
554 WINPR_ATTR_NODISCARD static inline INT16 Stream_Peek_Get_INT16_BE(wStream* _s)
555 {
556 return stream_read_i16_be(_s, FALSE);
557 }
558
565 WINPR_ATTR_NODISCARD static inline UINT32 Stream_Peek_Get_UINT32(wStream* _s)
566 {
567 return stream_read_u32_le(_s, FALSE);
568 }
569
576 WINPR_ATTR_NODISCARD static inline INT32 Stream_Peek_Get_INT32(wStream* _s)
577 {
578 return stream_read_i32_le(_s, FALSE);
579 }
580
587 WINPR_ATTR_NODISCARD static inline UINT32 Stream_Peek_Get_UINT32_BE(wStream* _s)
588 {
589 return stream_read_u32_be(_s, FALSE);
590 }
591
598 WINPR_ATTR_NODISCARD static inline INT32 Stream_Peek_Get_INT32_BE(wStream* _s)
599 {
600 return stream_read_i32_be(_s, FALSE);
601 }
602
609 WINPR_ATTR_NODISCARD static inline UINT64 Stream_Peek_Get_UINT64(wStream* _s)
610 {
611 return stream_read_u64_le(_s, FALSE);
612 }
613
620 WINPR_ATTR_NODISCARD static inline INT64 Stream_Peek_Get_INT64(wStream* _s)
621 {
622 return stream_read_i64_le(_s, FALSE);
623 }
624
631 WINPR_ATTR_NODISCARD static inline UINT64 Stream_Peek_Get_UINT64_BE(wStream* _s)
632 {
633 return stream_read_u64_be(_s, FALSE);
634 }
635
642 WINPR_ATTR_NODISCARD static inline INT64 Stream_Peek_Get_INT64_BE(wStream* _s)
643 {
644 return stream_read_i64_be(_s, FALSE);
645 }
646
647#define Stream_Read_UINT8(_s, _v) \
648 do \
649 { \
650 _v = stream_read_u8(_s, TRUE); \
651 } while (0)
652
653#define Stream_Read_INT8(_s, _v) \
654 do \
655 { \
656 _v = stream_read_i8(_s, TRUE); \
657 } while (0)
658
659#define Stream_Read_UINT16(_s, _v) \
660 do \
661 { \
662 _v = stream_read_u16_le(_s, TRUE); \
663 } while (0)
664
665#define Stream_Read_INT16(_s, _v) \
666 do \
667 { \
668 _v = stream_read_i16_le(_s, TRUE); \
669 } while (0)
670
671#define Stream_Read_UINT16_BE(_s, _v) \
672 do \
673 { \
674 _v = stream_read_u16_be(_s, TRUE); \
675 } while (0)
676
677#define Stream_Read_INT16_BE(_s, _v) \
678 do \
679 { \
680 _v = stream_read_i16_be(_s, TRUE); \
681 } while (0)
682
683#define Stream_Read_UINT32(_s, _v) \
684 do \
685 { \
686 _v = stream_read_u32_le(_s, TRUE); \
687 } while (0)
688
689#define Stream_Read_INT32(_s, _v) \
690 do \
691 { \
692 _v = stream_read_i32_le(_s, TRUE); \
693 } while (0)
694
695#define Stream_Read_UINT32_BE(_s, _v) \
696 do \
697 { \
698 _v = stream_read_u32_be(_s, TRUE); \
699 } while (0)
700
701#define Stream_Read_INT32_BE(_s, _v) \
702 do \
703 { \
704 _v = stream_read_i32_be(_s, TRUE); \
705 } while (0)
706
707#define Stream_Read_UINT64(_s, _v) \
708 do \
709 { \
710 _v = stream_read_u64_le(_s, TRUE); \
711 } while (0)
712
713#define Stream_Read_INT64(_s, _v) \
714 do \
715 { \
716 _v = stream_read_i64_le(_s, TRUE); \
717 } while (0)
718
719#define Stream_Read_UINT64_BE(_s, _v) \
720 do \
721 { \
722 _v = stream_read_u64_be(_s, TRUE); \
723 } while (0)
724
725#define Stream_Read_INT64_BE(_s, _v) \
726 do \
727 { \
728 _v = stream_read_i64_be(_s, TRUE); \
729 } while (0)
730
731 static inline void Stream_Read(wStream* _s, void* _b, size_t _n)
732 {
733 WINPR_ASSERT(_s);
734 WINPR_ASSERT(_b || (_n == 0));
735 WINPR_ASSERT(Stream_GetRemainingCapacity(_s) >= _n);
736 memcpy(_b, (_s->pointer), (_n));
737 Stream_Seek(_s, _n);
738 }
739
740#define Stream_Peek_UINT8(_s, _v) \
741 do \
742 { \
743 _v = stream_read_u8(_s, FALSE); \
744 } while (0)
745
746#define Stream_Peek_INT8(_s, _v) \
747 do \
748 { \
749 _v = stream_read_i8(_s, FALSE); \
750 } while (0)
751
752#define Stream_Peek_UINT16(_s, _v) \
753 do \
754 { \
755 _v = stream_read_u16_le(_s, FALSE); \
756 } while (0)
757
758#define Stream_Peek_INT16(_s, _v) \
759 do \
760 { \
761 _v = stream_read_i16_le(_s, FALSE); \
762 } while (0)
763
764#define Stream_Peek_UINT16_BE(_s, _v) \
765 do \
766 { \
767 _v = stream_read_u16_be(_s, FALSE); \
768 } while (0)
769
770#define Stream_Peek_INT16_BE(_s, _v) \
771 do \
772 { \
773 _v = stream_read_i16_be(_s, FALSE); \
774 } while (0)
775
776#define Stream_Peek_UINT32(_s, _v) \
777 do \
778 { \
779 _v = stream_read_u32_le(_s, FALSE); \
780 } while (0)
781
782#define Stream_Peek_INT32(_s, _v) \
783 do \
784 { \
785 _v = stream_read_i32_le(_s, FALSE); \
786 } while (0)
787
788#define Stream_Peek_UINT32_BE(_s, _v) \
789 do \
790 { \
791 _v = stream_read_u32_be(_s, FALSE); \
792 } while (0)
793
794#define Stream_Peek_INT32_BE(_s, _v) \
795 do \
796 { \
797 _v = stream_read_i32_be(_s, FALSE); \
798 } while (0)
799
800#define Stream_Peek_UINT64(_s, _v) \
801 do \
802 { \
803 _v = stream_read_u64_le(_s, FALSE); \
804 } while (0)
805
806#define Stream_Peek_INT64(_s, _v) \
807 do \
808 { \
809 _v = stream_read_i64_le(_s, FALSE); \
810 } while (0)
811
812#define Stream_Peek_UINT64_BE(_s, _v) \
813 do \
814 { \
815 _v = stream_read_u64_be(_s, FALSE); \
816 } while (0)
817
818#define Stream_Peek_INT64_BE(_s, _v) \
819 do \
820 { \
821 _v = stream_read_i64_be(_s, FALSE); \
822 } while (0)
823
824 static inline void Stream_Peek(const wStream* _s, void* _b, size_t _n)
825 {
826 WINPR_ASSERT(_s);
827 WINPR_ASSERT(_b || (_n == 0));
828 WINPR_ASSERT(Stream_GetRemainingCapacity(_s) >= _n);
829 memcpy(_b, (_s->pointer), (_n));
830 }
831
832#define Stream_Write_INT8(s, v) \
833 do \
834 { \
835 WINPR_ASSERT((v) <= INT8_MAX); \
836 WINPR_ASSERT((v) >= INT8_MIN); \
837 Stream_Write_INT8_unchecked((s), (v)); \
838 } while (0)
839
847 static inline void Stream_Write_INT8_unchecked(wStream* _s, INT8 _v)
848 {
849 WINPR_ASSERT(_s);
850 WINPR_ASSERT(_s->pointer);
851 WINPR_ASSERT(Stream_GetRemainingCapacity(_s) >= 1);
852
853 winpr_Data_Write_INT8(_s->pointer, _v);
854 _s->pointer += 1;
855 }
856
857#define Stream_Write_UINT8(s, v) \
858 do \
859 { \
860 WINPR_ASSERT((v) <= UINT8_MAX); \
861 WINPR_ASSERT((v) >= 0); \
862 Stream_Write_UINT8_unchecked((s), (v)); \
863 } while (0)
864
872 static inline void Stream_Write_UINT8_unchecked(wStream* _s, UINT8 _v)
873 {
874 WINPR_ASSERT(_s);
875 WINPR_ASSERT(_s->pointer);
876 WINPR_ASSERT(Stream_GetRemainingCapacity(_s) >= 1);
877
878 winpr_Data_Write_UINT8(_s->pointer, _v);
879 _s->pointer += 1;
880 }
881
882#define Stream_Write_INT16(s, v) \
883 do \
884 { \
885 WINPR_ASSERT((v) >= INT16_MIN); \
886 WINPR_ASSERT((v) <= INT16_MAX); \
887 Stream_Write_INT16_unchecked((s), (v)); \
888 } while (0)
889
898 static inline void Stream_Write_INT16_unchecked(wStream* _s, INT16 _v)
899 {
900 WINPR_ASSERT(_s);
901 WINPR_ASSERT(_s->pointer);
902 WINPR_ASSERT(Stream_GetRemainingCapacity(_s) >= 2);
903
904 winpr_Data_Write_INT16(_s->pointer, _v);
905 _s->pointer += 2;
906 }
907
908#define Stream_Write_UINT16(s, v) \
909 do \
910 { \
911 WINPR_ASSERT((v) <= UINT16_MAX); \
912 WINPR_ASSERT((v) >= 0); \
913 Stream_Write_UINT16_unchecked((s), (v)); \
914 } while (0)
915
924 static inline void Stream_Write_UINT16_unchecked(wStream* _s, UINT16 _v)
925 {
926 WINPR_ASSERT(_s);
927 WINPR_ASSERT(_s->pointer);
928 WINPR_ASSERT(Stream_GetRemainingCapacity(_s) >= 2);
929
930 winpr_Data_Write_UINT16(_s->pointer, _v);
931 _s->pointer += 2;
932 }
933
934#define Stream_Write_UINT16_BE(s, v) \
935 do \
936 { \
937 WINPR_ASSERT((v) <= UINT16_MAX); \
938 WINPR_ASSERT((v) >= 0); \
939 Stream_Write_UINT16_BE_unchecked((s), (v)); \
940 } while (0)
941
950 static inline void Stream_Write_UINT16_BE_unchecked(wStream* _s, UINT16 _v)
951 {
952 WINPR_ASSERT(_s);
953 WINPR_ASSERT(_s->pointer);
954 WINPR_ASSERT(Stream_GetRemainingCapacity(_s) >= 2);
955
956 winpr_Data_Write_UINT16_BE(_s->pointer, _v);
957 _s->pointer += 2;
958 }
959
960#define Stream_Write_INT16_BE(s, v) \
961 do \
962 { \
963 WINPR_ASSERT((v) <= INT16_MAX); \
964 WINPR_ASSERT((v) >= INT16_MIN); \
965 Stream_Write_INT16_BE_unchecked((s), (v)); \
966 } while (0)
967
978 static inline void Stream_Write_INT16_BE_unchecked(wStream* _s, INT16 _v)
979 {
980 WINPR_ASSERT(_s);
981 WINPR_ASSERT(_s->pointer);
982 WINPR_ASSERT(Stream_GetRemainingCapacity(_s) >= 2);
983
984 winpr_Data_Write_INT16_BE(_s->pointer, _v);
985 _s->pointer += 2;
986 }
987
988#define Stream_Write_UINT24_BE(s, v) \
989 do \
990 { \
991 WINPR_ASSERT((v) <= 0xFFFFFF); \
992 WINPR_ASSERT((v) >= 0); \
993 Stream_Write_UINT24_BE_unchecked((s), (v)); \
994 } while (0)
995
1004 static inline void Stream_Write_UINT24_BE_unchecked(wStream* _s, UINT32 _v)
1005 {
1006 WINPR_ASSERT(_s);
1007 WINPR_ASSERT(_s->pointer);
1008 WINPR_ASSERT(_v <= 0x00FFFFFF);
1009 WINPR_ASSERT(Stream_GetRemainingCapacity(_s) >= 3);
1010
1011 *_s->pointer++ = ((_v) >> 16) & 0xFF;
1012 *_s->pointer++ = ((_v) >> 8) & 0xFF;
1013 *_s->pointer++ = (_v) & 0xFF;
1014 }
1015
1016#define Stream_Write_INT32(s, v) \
1017 do \
1018 { \
1019 WINPR_ASSERT((v) <= INT32_MAX); \
1020 WINPR_ASSERT((v) >= INT32_MIN); \
1021 Stream_Write_INT32_unchecked((s), (v)); \
1022 } while (0)
1023
1032 static inline void Stream_Write_INT32_unchecked(wStream* _s, INT32 _v)
1033 {
1034 WINPR_ASSERT(_s);
1035 WINPR_ASSERT(_s->pointer);
1036 WINPR_ASSERT(Stream_GetRemainingCapacity(_s) >= 4);
1037
1038 winpr_Data_Write_INT32(_s->pointer, _v);
1039 _s->pointer += 4;
1040 }
1041
1042#define Stream_Write_INT32_BE(s, v) \
1043 do \
1044 { \
1045 WINPR_ASSERT((v) <= INT32_MAX); \
1046 WINPR_ASSERT((v) >= INT32_MIN); \
1047 Stream_Write_INT32_BE_unchecked((s), (v)); \
1048 } while (0)
1049
1060 static inline void Stream_Write_INT32_BE_unchecked(wStream* _s, INT32 _v)
1061 {
1062 WINPR_ASSERT(_s);
1063 WINPR_ASSERT(_s->pointer);
1064 WINPR_ASSERT(Stream_GetRemainingCapacity(_s) >= 4);
1065
1066 winpr_Data_Write_INT32_BE(_s->pointer, _v);
1067 _s->pointer += 4;
1068 }
1069
1070#define Stream_Write_UINT32(s, v) \
1071 do \
1072 { \
1073 WINPR_ASSERT((v) <= UINT32_MAX); \
1074 WINPR_ASSERT((v) >= 0); \
1075 Stream_Write_UINT32_unchecked((s), (v)); \
1076 } while (0)
1077
1086 static inline void Stream_Write_UINT32_unchecked(wStream* _s, UINT32 _v)
1087 {
1088 WINPR_ASSERT(_s);
1089 WINPR_ASSERT(_s->pointer);
1090 WINPR_ASSERT(Stream_GetRemainingCapacity(_s) >= 4);
1091
1092 winpr_Data_Write_UINT32(_s->pointer, _v);
1093 _s->pointer += 4;
1094 }
1095
1096#define Stream_Write_UINT32_BE(s, v) \
1097 do \
1098 { \
1099 WINPR_ASSERT((v) <= UINT32_MAX); \
1100 WINPR_ASSERT((v) >= 0); \
1101 Stream_Write_UINT32_BE_unchecked((s), (v)); \
1102 } while (0)
1103
1112 static inline void Stream_Write_UINT32_BE_unchecked(wStream* _s, UINT32 _v)
1113 {
1114 WINPR_ASSERT(Stream_GetRemainingCapacity(_s) >= 4);
1115
1116 winpr_Data_Write_UINT32_BE(_s->pointer, _v);
1117 _s->pointer += 4;
1118 }
1119
1126 static inline void Stream_Write_UINT64(wStream* _s, UINT64 _v)
1127 {
1128 WINPR_ASSERT(_s);
1129 WINPR_ASSERT(_s->pointer);
1130 WINPR_ASSERT(Stream_GetRemainingCapacity(_s) >= 8);
1131
1132 winpr_Data_Write_UINT64(_s->pointer, _v);
1133 _s->pointer += 8;
1134 }
1135
1142 static inline void Stream_Write_UINT64_BE(wStream* _s, UINT64 _v)
1143 {
1144 WINPR_ASSERT(_s);
1145 WINPR_ASSERT(_s->pointer);
1146 WINPR_ASSERT(Stream_GetRemainingCapacity(_s) >= 8);
1147
1148 winpr_Data_Write_UINT64_BE(_s->pointer, _v);
1149 _s->pointer += 8;
1150 }
1151
1159 static inline void Stream_Write_INT64(wStream* _s, INT64 _v)
1160 {
1161 WINPR_ASSERT(_s);
1162 WINPR_ASSERT(_s->pointer);
1163 WINPR_ASSERT(Stream_GetRemainingCapacity(_s) >= 8);
1164
1165 winpr_Data_Write_INT64(_s->pointer, _v);
1166 _s->pointer += 8;
1167 }
1168
1176 static inline void Stream_Write_INT64_BE(wStream* _s, INT64 _v)
1177 {
1178 WINPR_ASSERT(_s);
1179 WINPR_ASSERT(_s->pointer);
1180 WINPR_ASSERT(Stream_GetRemainingCapacity(_s) >= 8);
1181
1182 winpr_Data_Write_INT64_BE(_s->pointer, _v);
1183 _s->pointer += 8;
1184 }
1185
1186 static inline void Stream_Write(wStream* _s, const void* _b, size_t _n)
1187 {
1188 if (_n > 0)
1189 {
1190 WINPR_ASSERT(_s);
1191 WINPR_ASSERT(_b);
1192 WINPR_ASSERT(Stream_GetRemainingCapacity(_s) >= _n);
1193 memcpy(_s->pointer, (_b), (_n));
1194 Stream_Seek(_s, _n);
1195 }
1196 }
1197
1198 static inline void Stream_Seek_UINT8(wStream* _s)
1199 {
1200 Stream_Seek(_s, sizeof(UINT8));
1201 }
1202 static inline void Stream_Seek_UINT16(wStream* _s)
1203 {
1204 Stream_Seek(_s, sizeof(UINT16));
1205 }
1206 static inline void Stream_Seek_UINT32(wStream* _s)
1207 {
1208 Stream_Seek(_s, sizeof(UINT32));
1209 }
1210 static inline void Stream_Seek_UINT64(wStream* _s)
1211 {
1212 Stream_Seek(_s, sizeof(UINT64));
1213 }
1214
1215 static inline void Stream_Rewind_UINT8(wStream* _s)
1216 {
1217 Stream_Rewind(_s, sizeof(UINT8));
1218 }
1219 static inline void Stream_Rewind_UINT16(wStream* _s)
1220 {
1221 Stream_Rewind(_s, sizeof(UINT16));
1222 }
1223 static inline void Stream_Rewind_UINT32(wStream* _s)
1224 {
1225 Stream_Rewind(_s, sizeof(UINT32));
1226 }
1227 static inline void Stream_Rewind_UINT64(wStream* _s)
1228 {
1229 Stream_Rewind(_s, sizeof(UINT64));
1230 }
1231
1232 static inline void Stream_Fill(wStream* _s, int _v, size_t _n)
1233 {
1234 WINPR_ASSERT(_s);
1235 WINPR_ASSERT(Stream_GetRemainingCapacity(_s) >= (_n));
1236 memset(_s->pointer, _v, (_n));
1237 Stream_Seek(_s, _n);
1238 }
1239
1240 static inline void Stream_Zero(wStream* _s, size_t _n)
1241 {
1242 Stream_Fill(_s, '\0', _n);
1243 }
1244
1245 static inline void Stream_Copy(wStream* _src, wStream* _dst, size_t _n)
1246 {
1247 WINPR_ASSERT(_src);
1248 WINPR_ASSERT(_dst);
1249 WINPR_ASSERT(Stream_GetRemainingCapacity(_src) >= (_n));
1250 WINPR_ASSERT(Stream_GetRemainingCapacity(_dst) >= (_n));
1251
1252 memcpy(_dst->pointer, _src->pointer, _n);
1253 Stream_Seek(_dst, _n);
1254 Stream_Seek(_src, _n);
1255 }
1256
1261#define Stream_BufferAs(s, type) WINPR_STREAM_CAST(type*, Stream_Buffer(s))
1262
1263 WINPR_ATTR_NODISCARD static inline BYTE* Stream_Buffer(wStream* _s)
1264 {
1265 WINPR_ASSERT(_s);
1266 return _s->buffer;
1267 }
1268
1273#define Stream_ConstBufferAs(s, type) WINPR_STREAM_CAST(type*, Stream_ConstBuffer(s))
1274 WINPR_ATTR_NODISCARD static inline const BYTE* Stream_ConstBuffer(const wStream* _s)
1275 {
1276 WINPR_ASSERT(_s);
1277 return _s->buffer;
1278 }
1279
1280#define Stream_GetBuffer(_s, _b) _b = Stream_Buffer(_s)
1281
1286#define Stream_GetBufferAs(_s, _b) _b = Stream_BufferAs(_s, __typeof(_b))
1287
1288#define Stream_PointerAs(s, type) WINPR_STREAM_CAST(type*, Stream_Pointer(s))
1289
1290 WINPR_ATTR_NODISCARD static inline void* Stream_Pointer(wStream* _s)
1291 {
1292 WINPR_ASSERT(_s);
1293 return _s->pointer;
1294 }
1295
1296 WINPR_ATTR_NODISCARD static inline const void* Stream_ConstPointer(const wStream* _s)
1297 {
1298 WINPR_ASSERT(_s);
1299 return _s->pointer;
1300 }
1301
1302#define Stream_GetPointer(_s, _p) _p = Stream_Pointer(_s)
1303
1308#define Stream_GetPointerAs(_s, _p) _p = Stream_PointerAs(_s, __typeof(_p))
1309
1310#if defined(WITH_WINPR_DEPRECATED)
1311 WINPR_DEPRECATED_VAR("Use Stream_SetPosition instead",
1312 WINPR_ATTR_NODISCARD WINPR_API BOOL Stream_SetPointer(wStream* _s,
1313 BYTE* _p));
1314
1315 WINPR_DEPRECATED_VAR("Use Stream_New(buffer, capacity) instead",
1316 WINPR_ATTR_NODISCARD WINPR_API BOOL Stream_SetBuffer(wStream* _s,
1317 BYTE* _b));
1318
1319 WINPR_DEPRECATED_VAR("Use Stream_New(buffer, capacity) instead",
1320 WINPR_API void Stream_SetCapacity(wStream* _s, size_t capacity));
1321#endif
1322
1323 WINPR_ATTR_NODISCARD static inline size_t Stream_Length(const wStream* _s)
1324 {
1325 WINPR_ASSERT(_s);
1326 return _s->length;
1327 }
1328
1329#define Stream_GetLength(_s, _l) _l = Stream_Length(_s)
1330 WINPR_ATTR_NODISCARD
1331 WINPR_API BOOL Stream_SetLength(wStream* _s, size_t _l);
1332
1333 WINPR_ATTR_NODISCARD static inline size_t Stream_Capacity(const wStream* _s)
1334 {
1335 WINPR_ASSERT(_s);
1336 return _s->capacity;
1337 }
1338
1339#define Stream_GetCapacity(_s, _c) _c = Stream_Capacity(_s);
1340
1341 WINPR_ATTR_NODISCARD static inline size_t Stream_GetPosition(const wStream* _s)
1342 {
1343 WINPR_ASSERT(_s);
1344 WINPR_ASSERT(_s->buffer <= _s->pointer);
1345 return WINPR_STREAM_CAST(size_t, (_s->pointer - _s->buffer));
1346 }
1347
1356 static inline void Stream_ResetPosition(wStream* _s)
1357 {
1358 WINPR_ASSERT(_s);
1359 _s->pointer = _s->buffer;
1360 }
1361
1362 WINPR_ATTR_NODISCARD
1363 WINPR_API BOOL Stream_SetPosition(wStream* _s, size_t _p);
1364
1365 WINPR_API void Stream_SealLength(wStream* _s);
1366
1367 static inline void Stream_Clear(wStream* _s)
1368 {
1369 WINPR_ASSERT(_s);
1370 memset(_s->buffer, 0, _s->capacity);
1371 }
1372
1373#define Stream_SafeSeek(s, size) Stream_SafeSeekEx(s, size, __FILE__, __LINE__, __func__)
1374 WINPR_ATTR_NODISCARD
1375 WINPR_API BOOL Stream_SafeSeekEx(wStream* s, size_t size, const char* file, size_t line,
1376 const char* fkt);
1377
1378 WINPR_ATTR_NODISCARD
1379 WINPR_API BOOL Stream_Read_UTF16_String(wStream* s, WCHAR* dst, size_t charLength);
1380
1381 WINPR_ATTR_NODISCARD
1382 WINPR_API BOOL Stream_Write_UTF16_String(wStream* s, const WCHAR* src, size_t charLength);
1383
1393 WINPR_ATTR_MALLOC(free, 1)
1394 WINPR_API char* Stream_Read_UTF16_String_As_UTF8(wStream* s, size_t wcharLength,
1395 size_t* pUtfCharLength);
1396
1406 WINPR_ATTR_NODISCARD
1407 WINPR_API SSIZE_T Stream_Read_UTF16_String_As_UTF8_Buffer(wStream* s, size_t wcharLength,
1408 char* utfBuffer,
1409 size_t utfBufferCharLength);
1410
1422 WINPR_ATTR_NODISCARD
1423 WINPR_API SSIZE_T Stream_Write_UTF16_String_From_UTF8(wStream* s, size_t wcharLength,
1424 const char* src, size_t length,
1425 BOOL fill);
1426
1427 /* StreamPool */
1428
1429 WINPR_API void StreamPool_Return(wStreamPool* pool, wStream* s);
1430
1436 WINPR_API void Stream_AddRef(wStream* s);
1437
1445 WINPR_API void Stream_Release(wStream* s);
1446
1447 WINPR_ATTR_MALLOC(Stream_Release, 1)
1448 WINPR_ATTR_NODISCARD
1449 WINPR_API wStream* StreamPool_Take(wStreamPool* pool, size_t size);
1450
1451 WINPR_ATTR_NODISCARD
1452 WINPR_API wStream* StreamPool_Find(wStreamPool* pool, const BYTE* ptr);
1453
1462 WINPR_ATTR_NODISCARD
1463 WINPR_API size_t StreamPool_UsedCount(wStreamPool* pool);
1464
1475 WINPR_API BOOL StreamPool_WaitForReturn(wStreamPool* pool, UINT32 timeoutMS);
1476
1477 WINPR_API void StreamPool_Clear(wStreamPool* pool);
1478
1479 WINPR_API void StreamPool_Free(wStreamPool* pool);
1480
1481 WINPR_ATTR_MALLOC(StreamPool_Free, 1)
1482 WINPR_API wStreamPool* StreamPool_New(BOOL synchronized, size_t defaultSize);
1483
1484 WINPR_API char* StreamPool_GetStatistics(wStreamPool* pool, char* buffer, size_t size);
1485
1486#ifdef __cplusplus
1487}
1488#endif
1489
1490#endif /* WINPR_UTILS_STREAM_H */