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
54 static inline size_t Stream_Capacity(const wStream* _s);
55 WINPR_API size_t Stream_GetRemainingCapacity(const wStream* _s);
56 WINPR_API size_t Stream_GetRemainingLength(const wStream* _s);
57
58 WINPR_API BOOL Stream_EnsureCapacity(wStream* s, size_t size);
59 WINPR_API BOOL Stream_EnsureRemainingCapacity(wStream* s, size_t size);
60
61#define WINPR_STREAM_CAST(t, val) WINPR_CXX_COMPAT_CAST(t, val)
62
63#define Stream_CheckAndLogRequiredCapacityOfSize(tag, s, nmemb, size) \
64 Stream_CheckAndLogRequiredCapacityEx(tag, WLOG_WARN, s, nmemb, size, "%s(%s:%" PRIuz ")", \
65 __func__, __FILE__, (size_t)__LINE__)
66#define Stream_CheckAndLogRequiredCapacity(tag, s, len) \
67 Stream_CheckAndLogRequiredCapacityOfSize((tag), (s), (len), 1)
68
69 WINPR_API BOOL Stream_CheckAndLogRequiredCapacityEx(const char* tag, DWORD level, wStream* s,
70 size_t nmemb, size_t size, const char* fmt,
71 ...);
72 WINPR_API BOOL Stream_CheckAndLogRequiredCapacityExVa(const char* tag, DWORD level, wStream* s,
73 size_t nmemb, size_t size,
74 const char* fmt, va_list args);
75
76#define Stream_CheckAndLogRequiredCapacityOfSizeWLog(log, s, nmemb, size) \
77 Stream_CheckAndLogRequiredCapacityWLogEx(log, WLOG_WARN, s, nmemb, size, "%s(%s:%" PRIuz ")", \
78 __func__, __FILE__, (size_t)__LINE__)
79
80#define Stream_CheckAndLogRequiredCapacityWLog(log, s, len) \
81 Stream_CheckAndLogRequiredCapacityOfSizeWLog((log), (s), (len), 1)
82
83 WINPR_API BOOL Stream_CheckAndLogRequiredCapacityWLogEx(wLog* log, DWORD level, wStream* s,
84 size_t nmemb, size_t size,
85 const char* fmt, ...);
86 WINPR_API BOOL Stream_CheckAndLogRequiredCapacityWLogExVa(wLog* log, DWORD level, wStream* s,
87 size_t nmemb, size_t size,
88 const char* fmt, va_list args);
89
90 WINPR_API void Stream_Free(wStream* s, BOOL bFreeBuffer);
91
92 WINPR_ATTR_MALLOC(Stream_Free, 1)
93 WINPR_ATTR_NODISCARD
94 WINPR_API wStream* Stream_New(BYTE* buffer, size_t size);
95 WINPR_API wStream* Stream_StaticConstInit(wStream* s, const BYTE* buffer, size_t size);
96 WINPR_API wStream* Stream_StaticInit(wStream* s, BYTE* buffer, size_t size);
97
98#define Stream_CheckAndLogRequiredLengthOfSize(tag, s, nmemb, size) \
99 Stream_CheckAndLogRequiredLengthEx(tag, WLOG_WARN, s, nmemb, size, "%s(%s:%" PRIuz ")", \
100 __func__, __FILE__, (size_t)__LINE__)
101#define Stream_CheckAndLogRequiredLength(tag, s, len) \
102 Stream_CheckAndLogRequiredLengthOfSize(tag, s, len, 1)
103
104 WINPR_API BOOL Stream_CheckAndLogRequiredLengthEx(const char* tag, DWORD level, wStream* s,
105 size_t nmemb, size_t size, const char* fmt,
106 ...);
107 WINPR_API BOOL Stream_CheckAndLogRequiredLengthExVa(const char* tag, DWORD level, wStream* s,
108 size_t nmemb, size_t size, const char* fmt,
109 va_list args);
110
111#define Stream_CheckAndLogRequiredLengthOfSizeWLog(log, s, nmemb, size) \
112 Stream_CheckAndLogRequiredLengthWLogEx(log, WLOG_WARN, s, nmemb, size, "%s(%s:%" PRIuz ")", \
113 __func__, __FILE__, (size_t)__LINE__)
114#define Stream_CheckAndLogRequiredLengthWLog(log, s, len) \
115 Stream_CheckAndLogRequiredLengthOfSizeWLog(log, s, len, 1)
116
117 WINPR_API BOOL Stream_CheckAndLogRequiredLengthWLogEx(wLog* log, DWORD level, wStream* s,
118 size_t nmemb, size_t size,
119 const char* fmt, ...);
120 WINPR_API BOOL Stream_CheckAndLogRequiredLengthWLogExVa(wLog* log, DWORD level, wStream* s,
121 size_t nmemb, size_t size,
122 const char* fmt, va_list args);
123
124 static inline void Stream_Seek(wStream* s, size_t _offset)
125 {
126 WINPR_ASSERT(s);
127 WINPR_ASSERT(Stream_GetRemainingCapacity(s) >= _offset);
128 s->pointer += (_offset);
129 }
130
131 static inline void Stream_Rewind(wStream* s, size_t _offset)
132 {
133 size_t cur = 0;
134 WINPR_ASSERT(s);
135 WINPR_ASSERT(s->buffer <= s->pointer);
136 cur = WINPR_STREAM_CAST(size_t, s->pointer - s->buffer);
137 WINPR_ASSERT(cur >= _offset);
138 if (cur >= _offset)
139 s->pointer -= (_offset);
140 else
141 s->pointer = s->buffer;
142 }
143
144 static inline UINT8 stream_read_u8(wStream* _s, BOOL seek)
145 {
146 WINPR_ASSERT(_s);
147 WINPR_ASSERT(Stream_GetRemainingLength(_s) >= sizeof(UINT8));
148
149 const UINT8 v = winpr_Data_Get_UINT8(_s->pointer);
150 if (seek)
151 Stream_Seek(_s, sizeof(UINT8));
152 return v;
153 }
154
155 static inline INT8 stream_read_i8(wStream* _s, BOOL seek)
156 {
157 const INT8 v = winpr_Data_Get_INT8(_s->pointer);
158 if (seek)
159 Stream_Seek(_s, sizeof(INT8));
160 return v;
161 }
162
163 static inline UINT16 stream_read_u16_le(wStream* _s, BOOL seek)
164 {
165 const size_t typesize = sizeof(UINT16);
166 WINPR_ASSERT(_s);
167 WINPR_ASSERT(Stream_GetRemainingLength(_s) >= typesize);
168
169 const UINT16 v = winpr_Data_Get_UINT16(_s->pointer);
170 if (seek)
171 Stream_Seek(_s, typesize);
172 return v;
173 }
174
175 static inline UINT16 stream_read_u16_be(wStream* _s, BOOL seek)
176 {
177 const size_t typesize = sizeof(UINT16);
178 WINPR_ASSERT(_s);
179 WINPR_ASSERT(Stream_GetRemainingLength(_s) >= typesize);
180
181 const UINT16 v = winpr_Data_Get_UINT16_BE(_s->pointer);
182 if (seek)
183 Stream_Seek(_s, typesize);
184 return v;
185 }
186
187 static inline INT16 stream_read_i16_le(wStream* _s, BOOL seek)
188 {
189 const size_t typesize = sizeof(INT16);
190 WINPR_ASSERT(_s);
191 WINPR_ASSERT(Stream_GetRemainingLength(_s) >= typesize);
192
193 const INT16 v = winpr_Data_Get_INT16(_s->pointer);
194 if (seek)
195 Stream_Seek(_s, typesize);
196 return v;
197 }
198
199 static inline INT16 stream_read_i16_be(wStream* _s, BOOL seek)
200 {
201 const size_t typesize = sizeof(INT16);
202 WINPR_ASSERT(_s);
203 WINPR_ASSERT(Stream_GetRemainingLength(_s) >= typesize);
204
205 const INT16 v = winpr_Data_Get_INT16_BE(_s->pointer);
206 if (seek)
207 Stream_Seek(_s, typesize);
208 return v;
209 }
210
211 static inline UINT32 stream_read_u32_le(wStream* _s, BOOL seek)
212 {
213 const size_t typesize = sizeof(UINT32);
214 WINPR_ASSERT(_s);
215 WINPR_ASSERT(Stream_GetRemainingLength(_s) >= typesize);
216
217 const UINT32 v = winpr_Data_Get_UINT32(_s->pointer);
218 if (seek)
219 Stream_Seek(_s, typesize);
220 return v;
221 }
222
223 static inline UINT32 stream_read_u32_be(wStream* _s, BOOL seek)
224 {
225 const size_t typesize = sizeof(UINT32);
226 WINPR_ASSERT(_s);
227 WINPR_ASSERT(Stream_GetRemainingLength(_s) >= typesize);
228
229 const UINT32 v = winpr_Data_Get_UINT32_BE(_s->pointer);
230 if (seek)
231 Stream_Seek(_s, typesize);
232 return v;
233 }
234
235 static inline INT32 stream_read_i32_le(wStream* _s, BOOL seek)
236 {
237 const size_t typesize = sizeof(INT32);
238 WINPR_ASSERT(_s);
239 WINPR_ASSERT(Stream_GetRemainingLength(_s) >= typesize);
240
241 const INT32 v = winpr_Data_Get_INT32(_s->pointer);
242 if (seek)
243 Stream_Seek(_s, typesize);
244 return v;
245 }
246
247 static inline INT32 stream_read_i32_be(wStream* _s, BOOL seek)
248 {
249 const size_t typesize = sizeof(INT32);
250 WINPR_ASSERT(_s);
251 WINPR_ASSERT(Stream_GetRemainingLength(_s) >= typesize);
252
253 const INT32 v = winpr_Data_Get_INT32_BE(_s->pointer);
254 if (seek)
255 Stream_Seek(_s, typesize);
256 return v;
257 }
258
259 static inline UINT64 stream_read_u64_le(wStream* _s, BOOL seek)
260 {
261 const size_t typesize = sizeof(UINT64);
262 WINPR_ASSERT(_s);
263 WINPR_ASSERT(Stream_GetRemainingLength(_s) >= typesize);
264
265 const UINT64 v = winpr_Data_Get_UINT64(_s->pointer);
266 if (seek)
267 Stream_Seek(_s, typesize);
268 return v;
269 }
270
271 static inline UINT64 stream_read_u64_be(wStream* _s, BOOL seek)
272 {
273 const size_t typesize = sizeof(UINT64);
274 WINPR_ASSERT(_s);
275 WINPR_ASSERT(Stream_GetRemainingLength(_s) >= typesize);
276
277 const UINT64 v = winpr_Data_Get_UINT64_BE(_s->pointer);
278 if (seek)
279 Stream_Seek(_s, typesize);
280 return v;
281 }
282
283 static inline INT64 stream_read_i64_le(wStream* _s, BOOL seek)
284 {
285 const size_t typesize = sizeof(INT64);
286 WINPR_ASSERT(_s);
287 WINPR_ASSERT(Stream_GetRemainingLength(_s) >= typesize);
288
289 const INT64 v = winpr_Data_Get_INT64(_s->pointer);
290 if (seek)
291 Stream_Seek(_s, typesize);
292 return v;
293 }
294
295 static inline INT64 stream_read_i64_be(wStream* _s, BOOL seek)
296 {
297 const size_t typesize = sizeof(INT64);
298 WINPR_ASSERT(_s);
299 WINPR_ASSERT(Stream_GetRemainingLength(_s) >= typesize);
300
301 const INT64 v = winpr_Data_Get_INT64_BE(_s->pointer);
302 if (seek)
303 Stream_Seek(_s, typesize);
304 return v;
305 }
306
313 static inline UINT8 Stream_Get_UINT8(wStream* _s)
314 {
315 return stream_read_u8(_s, TRUE);
316 }
317
324 static inline INT8 Stream_Get_INT8(wStream* _s)
325 {
326 return stream_read_i8(_s, TRUE);
327 }
328
335 static inline UINT16 Stream_Get_UINT16(wStream* _s)
336 {
337 return stream_read_u16_le(_s, TRUE);
338 }
339
346 static inline INT16 Stream_Get_INT16(wStream* _s)
347 {
348 return stream_read_i16_le(_s, TRUE);
349 }
350
357 static inline UINT16 Stream_Get_UINT16_BE(wStream* _s)
358 {
359 return stream_read_u16_be(_s, TRUE);
360 }
361
368 static inline INT16 Stream_Get_INT16_BE(wStream* _s)
369 {
370 return stream_read_i16_be(_s, TRUE);
371 }
372
379 static inline UINT32 Stream_Get_UINT32(wStream* _s)
380 {
381 return stream_read_u32_le(_s, TRUE);
382 }
383
390 static inline INT32 Stream_Get_INT32(wStream* _s)
391 {
392 return stream_read_i32_le(_s, TRUE);
393 }
394
401 static inline UINT32 Stream_Get_UINT32_BE(wStream* _s)
402 {
403 return stream_read_u32_be(_s, TRUE);
404 }
405
412 static inline INT32 Stream_Get_INT32_BE(wStream* _s)
413 {
414 return stream_read_i32_be(_s, TRUE);
415 }
416
423 static inline UINT64 Stream_Get_UINT64(wStream* _s)
424 {
425 return stream_read_u64_le(_s, TRUE);
426 }
427
434 static inline INT64 Stream_Get_INT64(wStream* _s)
435 {
436 return stream_read_i64_le(_s, TRUE);
437 }
438
445 static inline UINT64 Stream_Get_UINT64_BE(wStream* _s)
446 {
447 return stream_read_u64_be(_s, TRUE);
448 }
449
456 static inline INT64 Stream_Get_INT64_BE(wStream* _s)
457 {
458 return stream_read_i64_be(_s, TRUE);
459 }
460
467 static inline UINT8 Stream_Peek_Get_UINT8(wStream* _s)
468 {
469 return stream_read_u8(_s, FALSE);
470 }
471
478 static inline INT8 Stream_Peek_Get_INT8(wStream* _s)
479 {
480 return stream_read_i8(_s, FALSE);
481 }
482
489 static inline UINT16 Stream_Peek_Get_UINT16(wStream* _s)
490 {
491 return stream_read_u16_le(_s, FALSE);
492 }
493
500 static inline INT16 Stream_Peek_Get_INT16(wStream* _s)
501 {
502 return stream_read_i16_le(_s, FALSE);
503 }
504
511 static inline UINT16 Stream_Peek_Get_UINT16_BE(wStream* _s)
512 {
513 return stream_read_u16_be(_s, FALSE);
514 }
515
522 static inline INT16 Stream_Peek_Get_INT16_BE(wStream* _s)
523 {
524 return stream_read_i16_be(_s, FALSE);
525 }
526
533 static inline UINT32 Stream_Peek_Get_UINT32(wStream* _s)
534 {
535 return stream_read_u32_le(_s, FALSE);
536 }
537
544 static inline INT32 Stream_Peek_Get_INT32(wStream* _s)
545 {
546 return stream_read_i32_le(_s, FALSE);
547 }
548
555 static inline UINT32 Stream_Peek_Get_UINT32_BE(wStream* _s)
556 {
557 return stream_read_u32_be(_s, FALSE);
558 }
559
566 static inline INT32 Stream_Peek_Get_INT32_BE(wStream* _s)
567 {
568 return stream_read_i32_be(_s, FALSE);
569 }
570
577 static inline UINT64 Stream_Peek_Get_UINT64(wStream* _s)
578 {
579 return stream_read_u64_le(_s, FALSE);
580 }
581
588 static inline INT64 Stream_Peek_Get_INT64(wStream* _s)
589 {
590 return stream_read_i64_le(_s, FALSE);
591 }
592
599 static inline UINT64 Stream_Peek_Get_UINT64_BE(wStream* _s)
600 {
601 return stream_read_u64_be(_s, FALSE);
602 }
603
610 static inline INT64 Stream_Peek_Get_INT64_BE(wStream* _s)
611 {
612 return stream_read_i64_be(_s, FALSE);
613 }
614
615#define Stream_Read_UINT8(_s, _v) \
616 do \
617 { \
618 _v = stream_read_u8(_s, TRUE); \
619 } while (0)
620
621#define Stream_Read_INT8(_s, _v) \
622 do \
623 { \
624 _v = stream_read_i8(_s, TRUE); \
625 } while (0)
626
627#define Stream_Read_UINT16(_s, _v) \
628 do \
629 { \
630 _v = stream_read_u16_le(_s, TRUE); \
631 } while (0)
632
633#define Stream_Read_INT16(_s, _v) \
634 do \
635 { \
636 _v = stream_read_i16_le(_s, TRUE); \
637 } while (0)
638
639#define Stream_Read_UINT16_BE(_s, _v) \
640 do \
641 { \
642 _v = stream_read_u16_be(_s, TRUE); \
643 } while (0)
644
645#define Stream_Read_INT16_BE(_s, _v) \
646 do \
647 { \
648 _v = stream_read_i16_be(_s, TRUE); \
649 } while (0)
650
651#define Stream_Read_UINT32(_s, _v) \
652 do \
653 { \
654 _v = stream_read_u32_le(_s, TRUE); \
655 } while (0)
656
657#define Stream_Read_INT32(_s, _v) \
658 do \
659 { \
660 _v = stream_read_i32_le(_s, TRUE); \
661 } while (0)
662
663#define Stream_Read_UINT32_BE(_s, _v) \
664 do \
665 { \
666 _v = stream_read_u32_be(_s, TRUE); \
667 } while (0)
668
669#define Stream_Read_INT32_BE(_s, _v) \
670 do \
671 { \
672 _v = stream_read_i32_be(_s, TRUE); \
673 } while (0)
674
675#define Stream_Read_UINT64(_s, _v) \
676 do \
677 { \
678 _v = stream_read_u64_le(_s, TRUE); \
679 } while (0)
680
681#define Stream_Read_INT64(_s, _v) \
682 do \
683 { \
684 _v = stream_read_i64_le(_s, TRUE); \
685 } while (0)
686
687#define Stream_Read_UINT64_BE(_s, _v) \
688 do \
689 { \
690 _v = stream_read_u64_be(_s, TRUE); \
691 } while (0)
692
693#define Stream_Read_INT64_BE(_s, _v) \
694 do \
695 { \
696 _v = stream_read_i64_be(_s, TRUE); \
697 } while (0)
698
699 static inline void Stream_Read(wStream* _s, void* _b, size_t _n)
700 {
701 WINPR_ASSERT(_s);
702 WINPR_ASSERT(_b || (_n == 0));
703 WINPR_ASSERT(Stream_GetRemainingCapacity(_s) >= _n);
704 memcpy(_b, (_s->pointer), (_n));
705 Stream_Seek(_s, _n);
706 }
707
708#define Stream_Peek_UINT8(_s, _v) \
709 do \
710 { \
711 _v = stream_read_u8(_s, FALSE); \
712 } while (0)
713
714#define Stream_Peek_INT8(_s, _v) \
715 do \
716 { \
717 _v = stream_read_i8(_s, FALSE); \
718 } while (0)
719
720#define Stream_Peek_UINT16(_s, _v) \
721 do \
722 { \
723 _v = stream_read_u16_le(_s, FALSE); \
724 } while (0)
725
726#define Stream_Peek_INT16(_s, _v) \
727 do \
728 { \
729 _v = stream_read_i16_le(_s, FALSE); \
730 } while (0)
731
732#define Stream_Peek_UINT16_BE(_s, _v) \
733 do \
734 { \
735 _v = stream_read_u16_be(_s, FALSE); \
736 } while (0)
737
738#define Stream_Peek_INT16_BE(_s, _v) \
739 do \
740 { \
741 _v = stream_read_i16_be(_s, FALSE); \
742 } while (0)
743
744#define Stream_Peek_UINT32(_s, _v) \
745 do \
746 { \
747 _v = stream_read_u32_le(_s, FALSE); \
748 } while (0)
749
750#define Stream_Peek_INT32(_s, _v) \
751 do \
752 { \
753 _v = stream_read_i32_le(_s, FALSE); \
754 } while (0)
755
756#define Stream_Peek_UINT32_BE(_s, _v) \
757 do \
758 { \
759 _v = stream_read_u32_be(_s, FALSE); \
760 } while (0)
761
762#define Stream_Peek_INT32_BE(_s, _v) \
763 do \
764 { \
765 _v = stream_read_i32_be(_s, FALSE); \
766 } while (0)
767
768#define Stream_Peek_UINT64(_s, _v) \
769 do \
770 { \
771 _v = stream_read_u64_le(_s, FALSE); \
772 } while (0)
773
774#define Stream_Peek_INT64(_s, _v) \
775 do \
776 { \
777 _v = stream_read_i64_le(_s, FALSE); \
778 } while (0)
779
780#define Stream_Peek_UINT64_BE(_s, _v) \
781 do \
782 { \
783 _v = stream_read_u64_be(_s, FALSE); \
784 } while (0)
785
786#define Stream_Peek_INT64_BE(_s, _v) \
787 do \
788 { \
789 _v = stream_read_i64_be(_s, FALSE); \
790 } while (0)
791
792 static inline void Stream_Peek(const wStream* _s, void* _b, size_t _n)
793 {
794 WINPR_ASSERT(_s);
795 WINPR_ASSERT(_b || (_n == 0));
796 WINPR_ASSERT(Stream_GetRemainingCapacity(_s) >= _n);
797 memcpy(_b, (_s->pointer), (_n));
798 }
799
800#define Stream_Write_INT8(s, v) \
801 do \
802 { \
803 WINPR_ASSERT((v) <= INT8_MAX); \
804 WINPR_ASSERT((v) >= INT8_MIN); \
805 Stream_Write_INT8_unchecked((s), (v)); \
806 } while (0)
807
815 static inline void Stream_Write_INT8_unchecked(wStream* _s, INT8 _v)
816 {
817 WINPR_ASSERT(_s);
818 WINPR_ASSERT(_s->pointer);
819 WINPR_ASSERT(Stream_GetRemainingCapacity(_s) >= 1);
820
821 winpr_Data_Write_INT8(_s->pointer, _v);
822 _s->pointer += 1;
823 }
824
825#define Stream_Write_UINT8(s, v) \
826 do \
827 { \
828 WINPR_ASSERT((v) <= UINT8_MAX); \
829 WINPR_ASSERT((v) >= 0); \
830 Stream_Write_UINT8_unchecked((s), (v)); \
831 } while (0)
832
840 static inline void Stream_Write_UINT8_unchecked(wStream* _s, UINT8 _v)
841 {
842 WINPR_ASSERT(_s);
843 WINPR_ASSERT(_s->pointer);
844 WINPR_ASSERT(Stream_GetRemainingCapacity(_s) >= 1);
845
846 winpr_Data_Write_UINT8(_s->pointer, _v);
847 _s->pointer += 1;
848 }
849
850#define Stream_Write_INT16(s, v) \
851 do \
852 { \
853 WINPR_ASSERT((v) >= INT16_MIN); \
854 WINPR_ASSERT((v) <= INT16_MAX); \
855 Stream_Write_INT16_unchecked((s), (v)); \
856 } while (0)
857
866 static inline void Stream_Write_INT16_unchecked(wStream* _s, INT16 _v)
867 {
868 WINPR_ASSERT(_s);
869 WINPR_ASSERT(_s->pointer);
870 WINPR_ASSERT(Stream_GetRemainingCapacity(_s) >= 2);
871
872 winpr_Data_Write_INT16(_s->pointer, _v);
873 _s->pointer += 2;
874 }
875
876#define Stream_Write_UINT16(s, v) \
877 do \
878 { \
879 WINPR_ASSERT((v) <= UINT16_MAX); \
880 WINPR_ASSERT((v) >= 0); \
881 Stream_Write_UINT16_unchecked((s), (v)); \
882 } while (0)
883
892 static inline void Stream_Write_UINT16_unchecked(wStream* _s, UINT16 _v)
893 {
894 WINPR_ASSERT(_s);
895 WINPR_ASSERT(_s->pointer);
896 WINPR_ASSERT(Stream_GetRemainingCapacity(_s) >= 2);
897
898 winpr_Data_Write_UINT16(_s->pointer, _v);
899 _s->pointer += 2;
900 }
901
902#define Stream_Write_UINT16_BE(s, v) \
903 do \
904 { \
905 WINPR_ASSERT((v) <= UINT16_MAX); \
906 WINPR_ASSERT((v) >= 0); \
907 Stream_Write_UINT16_BE_unchecked((s), (v)); \
908 } while (0)
909
918 static inline void Stream_Write_UINT16_BE_unchecked(wStream* _s, UINT16 _v)
919 {
920 WINPR_ASSERT(_s);
921 WINPR_ASSERT(_s->pointer);
922 WINPR_ASSERT(Stream_GetRemainingCapacity(_s) >= 2);
923
924 winpr_Data_Write_UINT16_BE(_s->pointer, _v);
925 _s->pointer += 2;
926 }
927
928#define Stream_Write_INT16_BE(s, v) \
929 do \
930 { \
931 WINPR_ASSERT((v) <= INT16_MAX); \
932 WINPR_ASSERT((v) >= INT16_MIN); \
933 Stream_Write_INT16_BE_unchecked((s), (v)); \
934 } while (0)
935
946 static inline void Stream_Write_INT16_BE_unchecked(wStream* _s, INT16 _v)
947 {
948 WINPR_ASSERT(_s);
949 WINPR_ASSERT(_s->pointer);
950 WINPR_ASSERT(Stream_GetRemainingCapacity(_s) >= 2);
951
952 winpr_Data_Write_INT16_BE(_s->pointer, _v);
953 _s->pointer += 2;
954 }
955
956#define Stream_Write_UINT24_BE(s, v) \
957 do \
958 { \
959 WINPR_ASSERT((v) <= 0xFFFFFF); \
960 WINPR_ASSERT((v) >= 0); \
961 Stream_Write_UINT24_BE_unchecked((s), (v)); \
962 } while (0)
963
972 static inline void Stream_Write_UINT24_BE_unchecked(wStream* _s, UINT32 _v)
973 {
974 WINPR_ASSERT(_s);
975 WINPR_ASSERT(_s->pointer);
976 WINPR_ASSERT(_v <= 0x00FFFFFF);
977 WINPR_ASSERT(Stream_GetRemainingCapacity(_s) >= 3);
978
979 *_s->pointer++ = ((_v) >> 16) & 0xFF;
980 *_s->pointer++ = ((_v) >> 8) & 0xFF;
981 *_s->pointer++ = (_v) & 0xFF;
982 }
983
984#define Stream_Write_INT32(s, v) \
985 do \
986 { \
987 WINPR_ASSERT((v) <= INT32_MAX); \
988 WINPR_ASSERT((v) >= INT32_MIN); \
989 Stream_Write_INT32_unchecked((s), (v)); \
990 } while (0)
991
1000 static inline void Stream_Write_INT32_unchecked(wStream* _s, INT32 _v)
1001 {
1002 WINPR_ASSERT(_s);
1003 WINPR_ASSERT(_s->pointer);
1004 WINPR_ASSERT(Stream_GetRemainingCapacity(_s) >= 4);
1005
1006 winpr_Data_Write_INT32(_s->pointer, _v);
1007 _s->pointer += 4;
1008 }
1009
1010#define Stream_Write_INT32_BE(s, v) \
1011 do \
1012 { \
1013 WINPR_ASSERT((v) <= INT32_MAX); \
1014 WINPR_ASSERT((v) >= INT32_MIN); \
1015 Stream_Write_INT32_BE_unchecked((s), (v)); \
1016 } while (0)
1017
1028 static inline void Stream_Write_INT32_BE_unchecked(wStream* _s, INT32 _v)
1029 {
1030 WINPR_ASSERT(_s);
1031 WINPR_ASSERT(_s->pointer);
1032 WINPR_ASSERT(Stream_GetRemainingCapacity(_s) >= 4);
1033
1034 winpr_Data_Write_INT32_BE(_s->pointer, _v);
1035 _s->pointer += 4;
1036 }
1037
1038#define Stream_Write_UINT32(s, v) \
1039 do \
1040 { \
1041 WINPR_ASSERT((v) <= UINT32_MAX); \
1042 WINPR_ASSERT((v) >= 0); \
1043 Stream_Write_UINT32_unchecked((s), (v)); \
1044 } while (0)
1045
1054 static inline void Stream_Write_UINT32_unchecked(wStream* _s, UINT32 _v)
1055 {
1056 WINPR_ASSERT(_s);
1057 WINPR_ASSERT(_s->pointer);
1058 WINPR_ASSERT(Stream_GetRemainingCapacity(_s) >= 4);
1059
1060 winpr_Data_Write_UINT32(_s->pointer, _v);
1061 _s->pointer += 4;
1062 }
1063
1064#define Stream_Write_UINT32_BE(s, v) \
1065 do \
1066 { \
1067 WINPR_ASSERT((v) <= UINT32_MAX); \
1068 WINPR_ASSERT((v) >= 0); \
1069 Stream_Write_UINT32_BE_unchecked((s), (v)); \
1070 } while (0)
1071
1080 static inline void Stream_Write_UINT32_BE_unchecked(wStream* _s, UINT32 _v)
1081 {
1082 WINPR_ASSERT(Stream_GetRemainingCapacity(_s) >= 4);
1083
1084 winpr_Data_Write_UINT32_BE(_s->pointer, _v);
1085 _s->pointer += 4;
1086 }
1087
1094 static inline void Stream_Write_UINT64(wStream* _s, UINT64 _v)
1095 {
1096 WINPR_ASSERT(_s);
1097 WINPR_ASSERT(_s->pointer);
1098 WINPR_ASSERT(Stream_GetRemainingCapacity(_s) >= 8);
1099
1100 winpr_Data_Write_UINT64(_s->pointer, _v);
1101 _s->pointer += 8;
1102 }
1103
1110 static inline void Stream_Write_UINT64_BE(wStream* _s, UINT64 _v)
1111 {
1112 WINPR_ASSERT(_s);
1113 WINPR_ASSERT(_s->pointer);
1114 WINPR_ASSERT(Stream_GetRemainingCapacity(_s) >= 8);
1115
1116 winpr_Data_Write_UINT64_BE(_s->pointer, _v);
1117 _s->pointer += 8;
1118 }
1119
1127 static inline void Stream_Write_INT64(wStream* _s, INT64 _v)
1128 {
1129 WINPR_ASSERT(_s);
1130 WINPR_ASSERT(_s->pointer);
1131 WINPR_ASSERT(Stream_GetRemainingCapacity(_s) >= 8);
1132
1133 winpr_Data_Write_INT64(_s->pointer, _v);
1134 _s->pointer += 8;
1135 }
1136
1144 static inline void Stream_Write_INT64_BE(wStream* _s, INT64 _v)
1145 {
1146 WINPR_ASSERT(_s);
1147 WINPR_ASSERT(_s->pointer);
1148 WINPR_ASSERT(Stream_GetRemainingCapacity(_s) >= 8);
1149
1150 winpr_Data_Write_INT64_BE(_s->pointer, _v);
1151 _s->pointer += 8;
1152 }
1153
1154 static inline void Stream_Write(wStream* _s, const void* _b, size_t _n)
1155 {
1156 if (_n > 0)
1157 {
1158 WINPR_ASSERT(_s);
1159 WINPR_ASSERT(_b);
1160 WINPR_ASSERT(Stream_GetRemainingCapacity(_s) >= _n);
1161 memcpy(_s->pointer, (_b), (_n));
1162 Stream_Seek(_s, _n);
1163 }
1164 }
1165
1166 static inline void Stream_Seek_UINT8(wStream* _s)
1167 {
1168 Stream_Seek(_s, sizeof(UINT8));
1169 }
1170 static inline void Stream_Seek_UINT16(wStream* _s)
1171 {
1172 Stream_Seek(_s, sizeof(UINT16));
1173 }
1174 static inline void Stream_Seek_UINT32(wStream* _s)
1175 {
1176 Stream_Seek(_s, sizeof(UINT32));
1177 }
1178 static inline void Stream_Seek_UINT64(wStream* _s)
1179 {
1180 Stream_Seek(_s, sizeof(UINT64));
1181 }
1182
1183 static inline void Stream_Rewind_UINT8(wStream* _s)
1184 {
1185 Stream_Rewind(_s, sizeof(UINT8));
1186 }
1187 static inline void Stream_Rewind_UINT16(wStream* _s)
1188 {
1189 Stream_Rewind(_s, sizeof(UINT16));
1190 }
1191 static inline void Stream_Rewind_UINT32(wStream* _s)
1192 {
1193 Stream_Rewind(_s, sizeof(UINT32));
1194 }
1195 static inline void Stream_Rewind_UINT64(wStream* _s)
1196 {
1197 Stream_Rewind(_s, sizeof(UINT64));
1198 }
1199
1200 static inline void Stream_Fill(wStream* _s, int _v, size_t _n)
1201 {
1202 WINPR_ASSERT(_s);
1203 WINPR_ASSERT(Stream_GetRemainingCapacity(_s) >= (_n));
1204 memset(_s->pointer, _v, (_n));
1205 Stream_Seek(_s, _n);
1206 }
1207
1208 static inline void Stream_Zero(wStream* _s, size_t _n)
1209 {
1210 Stream_Fill(_s, '\0', _n);
1211 }
1212
1213 static inline void Stream_Copy(wStream* _src, wStream* _dst, size_t _n)
1214 {
1215 WINPR_ASSERT(_src);
1216 WINPR_ASSERT(_dst);
1217 WINPR_ASSERT(Stream_GetRemainingCapacity(_src) >= (_n));
1218 WINPR_ASSERT(Stream_GetRemainingCapacity(_dst) >= (_n));
1219
1220 memcpy(_dst->pointer, _src->pointer, _n);
1221 Stream_Seek(_dst, _n);
1222 Stream_Seek(_src, _n);
1223 }
1224
1229#define Stream_BufferAs(s, type) WINPR_STREAM_CAST(type*, Stream_Buffer(s))
1230
1231 static inline BYTE* Stream_Buffer(wStream* _s)
1232 {
1233 WINPR_ASSERT(_s);
1234 return _s->buffer;
1235 }
1236
1241#define Stream_ConstBufferAs(s, type) WINPR_STREAM_CAST(type*, Stream_ConstBuffer(s))
1242 static inline const BYTE* Stream_ConstBuffer(const wStream* _s)
1243 {
1244 WINPR_ASSERT(_s);
1245 return _s->buffer;
1246 }
1247
1248#define Stream_GetBuffer(_s, _b) _b = Stream_Buffer(_s)
1249
1254#define Stream_GetBufferAs(_s, _b) _b = Stream_BufferAs(_s, __typeof(_b))
1255
1256#define Stream_PointerAs(s, type) WINPR_STREAM_CAST(type*, Stream_Pointer(s))
1257
1258 static inline void* Stream_Pointer(wStream* _s)
1259 {
1260 WINPR_ASSERT(_s);
1261 return _s->pointer;
1262 }
1263
1264 static inline const void* Stream_ConstPointer(const wStream* _s)
1265 {
1266 WINPR_ASSERT(_s);
1267 return _s->pointer;
1268 }
1269
1270#define Stream_GetPointer(_s, _p) _p = Stream_Pointer(_s)
1271
1276#define Stream_GetPointerAs(_s, _p) _p = Stream_PointerAs(_s, __typeof(_p))
1277
1278#if defined(WITH_WINPR_DEPRECATED)
1279 WINPR_DEPRECATED_VAR("Use Stream_SetPosition instead",
1280 WINPR_API BOOL Stream_SetPointer(wStream* _s, BYTE* _p));
1281 WINPR_DEPRECATED_VAR("Use Stream_New(buffer, capacity) instead",
1282 WINPR_API BOOL Stream_SetBuffer(wStream* _s, BYTE* _b));
1283 WINPR_DEPRECATED_VAR("Use Stream_New(buffer, capacity) instead",
1284 WINPR_API void Stream_SetCapacity(wStream* _s, size_t capacity));
1285#endif
1286
1287 static inline size_t Stream_Length(const wStream* _s)
1288 {
1289 WINPR_ASSERT(_s);
1290 return _s->length;
1291 }
1292
1293#define Stream_GetLength(_s, _l) _l = Stream_Length(_s)
1294 WINPR_API BOOL Stream_SetLength(wStream* _s, size_t _l);
1295
1296 static inline size_t Stream_Capacity(const wStream* _s)
1297 {
1298 WINPR_ASSERT(_s);
1299 return _s->capacity;
1300 }
1301
1302#define Stream_GetCapacity(_s, _c) _c = Stream_Capacity(_s);
1303
1304 static inline size_t Stream_GetPosition(const wStream* _s)
1305 {
1306 WINPR_ASSERT(_s);
1307 WINPR_ASSERT(_s->buffer <= _s->pointer);
1308 return WINPR_STREAM_CAST(size_t, (_s->pointer - _s->buffer));
1309 }
1310
1311 WINPR_API BOOL Stream_SetPosition(wStream* _s, size_t _p);
1312
1313 WINPR_API void Stream_SealLength(wStream* _s);
1314
1315 static inline void Stream_Clear(wStream* _s)
1316 {
1317 WINPR_ASSERT(_s);
1318 memset(_s->buffer, 0, _s->capacity);
1319 }
1320
1321#define Stream_SafeSeek(s, size) Stream_SafeSeekEx(s, size, __FILE__, __LINE__, __func__)
1322 WINPR_API BOOL Stream_SafeSeekEx(wStream* s, size_t size, const char* file, size_t line,
1323 const char* fkt);
1324
1325 WINPR_API BOOL Stream_Read_UTF16_String(wStream* s, WCHAR* dst, size_t charLength);
1326 WINPR_API BOOL Stream_Write_UTF16_String(wStream* s, const WCHAR* src, size_t charLength);
1327
1337 WINPR_API char* Stream_Read_UTF16_String_As_UTF8(wStream* s, size_t wcharLength,
1338 size_t* pUtfCharLength);
1339
1349 WINPR_API SSIZE_T Stream_Read_UTF16_String_As_UTF8_Buffer(wStream* s, size_t wcharLength,
1350 char* utfBuffer,
1351 size_t utfBufferCharLength);
1352
1364 WINPR_API SSIZE_T Stream_Write_UTF16_String_From_UTF8(wStream* s, size_t wcharLength,
1365 const char* src, size_t length,
1366 BOOL fill);
1367
1368 /* StreamPool */
1369
1370 WINPR_API void StreamPool_Return(wStreamPool* pool, wStream* s);
1371
1377 WINPR_API void Stream_AddRef(wStream* s);
1378
1386 WINPR_API void Stream_Release(wStream* s);
1387
1388 WINPR_ATTR_MALLOC(Stream_Release, 1)
1389 WINPR_ATTR_NODISCARD
1390 WINPR_API wStream* StreamPool_Take(wStreamPool* pool, size_t size);
1391
1392 WINPR_API wStream* StreamPool_Find(wStreamPool* pool, const BYTE* ptr);
1393
1402 WINPR_API size_t StreamPool_UsedCount(wStreamPool* pool);
1403
1414 WINPR_API BOOL StreamPool_WaitForReturn(wStreamPool* pool, UINT32 timeoutMS);
1415
1416 WINPR_API void StreamPool_Clear(wStreamPool* pool);
1417
1418 WINPR_API void StreamPool_Free(wStreamPool* pool);
1419
1420 WINPR_ATTR_MALLOC(StreamPool_Free, 1)
1421 WINPR_ATTR_NODISCARD
1422 WINPR_API wStreamPool* StreamPool_New(BOOL synchronized, size_t defaultSize);
1423
1424 WINPR_API char* StreamPool_GetStatistics(wStreamPool* pool, char* buffer, size_t size);
1425
1426#ifdef __cplusplus
1427}
1428#endif
1429
1430#endif /* WINPR_UTILS_STREAM_H */