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 static inline wStream Stream_Init(void)
60 {
61 const wStream empty = { nullptr, nullptr, 0, 0, 0, nullptr, FALSE, FALSE };
62 return empty;
63 }
64
65 static inline size_t Stream_Capacity(const wStream* _s);
66 WINPR_API size_t Stream_GetRemainingCapacity(const wStream* _s);
67 WINPR_API size_t Stream_GetRemainingLength(const wStream* _s);
68
69 WINPR_API BOOL Stream_EnsureCapacity(wStream* s, size_t size);
70 WINPR_API BOOL Stream_EnsureRemainingCapacity(wStream* s, size_t size);
71
72#define WINPR_STREAM_CAST(t, val) WINPR_CXX_COMPAT_CAST(t, val)
73
74#define Stream_CheckAndLogRequiredCapacityOfSize(tag, s, nmemb, size) \
75 Stream_CheckAndLogRequiredCapacityEx(tag, WLOG_WARN, s, nmemb, size, "%s(%s:%" PRIuz ")", \
76 __func__, __FILE__, (size_t)__LINE__)
77#define Stream_CheckAndLogRequiredCapacity(tag, s, len) \
78 Stream_CheckAndLogRequiredCapacityOfSize((tag), (s), (len), 1)
79
80 WINPR_API BOOL Stream_CheckAndLogRequiredCapacityEx(const char* tag, DWORD level, wStream* s,
81 size_t nmemb, size_t size, const char* fmt,
82 ...);
83 WINPR_API BOOL Stream_CheckAndLogRequiredCapacityExVa(const char* tag, DWORD level, wStream* s,
84 size_t nmemb, size_t size,
85 const char* fmt, va_list args);
86
87#define Stream_CheckAndLogRequiredCapacityOfSizeWLog(log, s, nmemb, size) \
88 Stream_CheckAndLogRequiredCapacityWLogEx(log, WLOG_WARN, s, nmemb, size, "%s(%s:%" PRIuz ")", \
89 __func__, __FILE__, (size_t)__LINE__)
90
91#define Stream_CheckAndLogRequiredCapacityWLog(log, s, len) \
92 Stream_CheckAndLogRequiredCapacityOfSizeWLog((log), (s), (len), 1)
93
94 WINPR_API BOOL Stream_CheckAndLogRequiredCapacityWLogEx(wLog* log, DWORD level, wStream* s,
95 size_t nmemb, size_t size,
96 const char* fmt, ...);
97 WINPR_API BOOL Stream_CheckAndLogRequiredCapacityWLogExVa(wLog* log, DWORD level, wStream* s,
98 size_t nmemb, size_t size,
99 const char* fmt, va_list args);
100
101 WINPR_API void Stream_Free(wStream* s, BOOL bFreeBuffer);
102
103 WINPR_ATTR_MALLOC(Stream_Free, 1)
104 WINPR_ATTR_NODISCARD
105 WINPR_API wStream* Stream_New(BYTE* buffer, size_t size);
106 WINPR_API wStream* Stream_StaticConstInit(wStream* s, const BYTE* buffer, size_t size);
107 WINPR_API wStream* Stream_StaticInit(wStream* s, BYTE* buffer, size_t size);
108
109#define Stream_CheckAndLogRequiredLengthOfSize(tag, s, nmemb, size) \
110 Stream_CheckAndLogRequiredLengthEx(tag, WLOG_WARN, s, nmemb, size, "%s(%s:%" PRIuz ")", \
111 __func__, __FILE__, (size_t)__LINE__)
112#define Stream_CheckAndLogRequiredLength(tag, s, len) \
113 Stream_CheckAndLogRequiredLengthOfSize(tag, s, len, 1)
114
115 WINPR_API BOOL Stream_CheckAndLogRequiredLengthEx(const char* tag, DWORD level, wStream* s,
116 size_t nmemb, size_t size, const char* fmt,
117 ...);
118 WINPR_API BOOL Stream_CheckAndLogRequiredLengthExVa(const char* tag, DWORD level, wStream* s,
119 size_t nmemb, size_t size, const char* fmt,
120 va_list args);
121
122#define Stream_CheckAndLogRequiredLengthOfSizeWLog(log, s, nmemb, size) \
123 Stream_CheckAndLogRequiredLengthWLogEx(log, WLOG_WARN, s, nmemb, size, "%s(%s:%" PRIuz ")", \
124 __func__, __FILE__, (size_t)__LINE__)
125#define Stream_CheckAndLogRequiredLengthWLog(log, s, len) \
126 Stream_CheckAndLogRequiredLengthOfSizeWLog(log, s, len, 1)
127
128 WINPR_API BOOL Stream_CheckAndLogRequiredLengthWLogEx(wLog* log, DWORD level, wStream* s,
129 size_t nmemb, size_t size,
130 const char* fmt, ...);
131 WINPR_API BOOL Stream_CheckAndLogRequiredLengthWLogExVa(wLog* log, DWORD level, wStream* s,
132 size_t nmemb, size_t size,
133 const char* fmt, va_list args);
134
135 static inline void Stream_Seek(wStream* s, size_t _offset)
136 {
137 WINPR_ASSERT(s);
138 WINPR_ASSERT(Stream_GetRemainingCapacity(s) >= _offset);
139 s->pointer += (_offset);
140 }
141
142 static inline void Stream_Rewind(wStream* s, size_t _offset)
143 {
144 size_t cur = 0;
145 WINPR_ASSERT(s);
146 WINPR_ASSERT(s->buffer <= s->pointer);
147 cur = WINPR_STREAM_CAST(size_t, s->pointer - s->buffer);
148 WINPR_ASSERT(cur >= _offset);
149 if (cur >= _offset)
150 s->pointer -= (_offset);
151 else
152 s->pointer = s->buffer;
153 }
154
155 static inline UINT8 stream_read_u8(wStream* _s, BOOL seek)
156 {
157 WINPR_ASSERT(_s);
158 WINPR_ASSERT(Stream_GetRemainingLength(_s) >= sizeof(UINT8));
159
160 const UINT8 v = winpr_Data_Get_UINT8(_s->pointer);
161 if (seek)
162 Stream_Seek(_s, sizeof(UINT8));
163 return v;
164 }
165
166 static inline INT8 stream_read_i8(wStream* _s, BOOL seek)
167 {
168 const INT8 v = winpr_Data_Get_INT8(_s->pointer);
169 if (seek)
170 Stream_Seek(_s, sizeof(INT8));
171 return v;
172 }
173
174 static inline UINT16 stream_read_u16_le(wStream* _s, BOOL seek)
175 {
176 const size_t typesize = sizeof(UINT16);
177 WINPR_ASSERT(_s);
178 WINPR_ASSERT(Stream_GetRemainingLength(_s) >= typesize);
179
180 const UINT16 v = winpr_Data_Get_UINT16(_s->pointer);
181 if (seek)
182 Stream_Seek(_s, typesize);
183 return v;
184 }
185
186 static inline UINT16 stream_read_u16_be(wStream* _s, BOOL seek)
187 {
188 const size_t typesize = sizeof(UINT16);
189 WINPR_ASSERT(_s);
190 WINPR_ASSERT(Stream_GetRemainingLength(_s) >= typesize);
191
192 const UINT16 v = winpr_Data_Get_UINT16_BE(_s->pointer);
193 if (seek)
194 Stream_Seek(_s, typesize);
195 return v;
196 }
197
198 static inline INT16 stream_read_i16_le(wStream* _s, BOOL seek)
199 {
200 const size_t typesize = sizeof(INT16);
201 WINPR_ASSERT(_s);
202 WINPR_ASSERT(Stream_GetRemainingLength(_s) >= typesize);
203
204 const INT16 v = winpr_Data_Get_INT16(_s->pointer);
205 if (seek)
206 Stream_Seek(_s, typesize);
207 return v;
208 }
209
210 static inline INT16 stream_read_i16_be(wStream* _s, BOOL seek)
211 {
212 const size_t typesize = sizeof(INT16);
213 WINPR_ASSERT(_s);
214 WINPR_ASSERT(Stream_GetRemainingLength(_s) >= typesize);
215
216 const INT16 v = winpr_Data_Get_INT16_BE(_s->pointer);
217 if (seek)
218 Stream_Seek(_s, typesize);
219 return v;
220 }
221
222 static inline UINT32 stream_read_u32_le(wStream* _s, BOOL seek)
223 {
224 const size_t typesize = sizeof(UINT32);
225 WINPR_ASSERT(_s);
226 WINPR_ASSERT(Stream_GetRemainingLength(_s) >= typesize);
227
228 const UINT32 v = winpr_Data_Get_UINT32(_s->pointer);
229 if (seek)
230 Stream_Seek(_s, typesize);
231 return v;
232 }
233
234 static inline UINT32 stream_read_u32_be(wStream* _s, BOOL seek)
235 {
236 const size_t typesize = sizeof(UINT32);
237 WINPR_ASSERT(_s);
238 WINPR_ASSERT(Stream_GetRemainingLength(_s) >= typesize);
239
240 const UINT32 v = winpr_Data_Get_UINT32_BE(_s->pointer);
241 if (seek)
242 Stream_Seek(_s, typesize);
243 return v;
244 }
245
246 static inline INT32 stream_read_i32_le(wStream* _s, BOOL seek)
247 {
248 const size_t typesize = sizeof(INT32);
249 WINPR_ASSERT(_s);
250 WINPR_ASSERT(Stream_GetRemainingLength(_s) >= typesize);
251
252 const INT32 v = winpr_Data_Get_INT32(_s->pointer);
253 if (seek)
254 Stream_Seek(_s, typesize);
255 return v;
256 }
257
258 static inline INT32 stream_read_i32_be(wStream* _s, BOOL seek)
259 {
260 const size_t typesize = sizeof(INT32);
261 WINPR_ASSERT(_s);
262 WINPR_ASSERT(Stream_GetRemainingLength(_s) >= typesize);
263
264 const INT32 v = winpr_Data_Get_INT32_BE(_s->pointer);
265 if (seek)
266 Stream_Seek(_s, typesize);
267 return v;
268 }
269
270 static inline UINT64 stream_read_u64_le(wStream* _s, BOOL seek)
271 {
272 const size_t typesize = sizeof(UINT64);
273 WINPR_ASSERT(_s);
274 WINPR_ASSERT(Stream_GetRemainingLength(_s) >= typesize);
275
276 const UINT64 v = winpr_Data_Get_UINT64(_s->pointer);
277 if (seek)
278 Stream_Seek(_s, typesize);
279 return v;
280 }
281
282 static inline UINT64 stream_read_u64_be(wStream* _s, BOOL seek)
283 {
284 const size_t typesize = sizeof(UINT64);
285 WINPR_ASSERT(_s);
286 WINPR_ASSERT(Stream_GetRemainingLength(_s) >= typesize);
287
288 const UINT64 v = winpr_Data_Get_UINT64_BE(_s->pointer);
289 if (seek)
290 Stream_Seek(_s, typesize);
291 return v;
292 }
293
294 static inline INT64 stream_read_i64_le(wStream* _s, BOOL seek)
295 {
296 const size_t typesize = sizeof(INT64);
297 WINPR_ASSERT(_s);
298 WINPR_ASSERT(Stream_GetRemainingLength(_s) >= typesize);
299
300 const INT64 v = winpr_Data_Get_INT64(_s->pointer);
301 if (seek)
302 Stream_Seek(_s, typesize);
303 return v;
304 }
305
306 static inline INT64 stream_read_i64_be(wStream* _s, BOOL seek)
307 {
308 const size_t typesize = sizeof(INT64);
309 WINPR_ASSERT(_s);
310 WINPR_ASSERT(Stream_GetRemainingLength(_s) >= typesize);
311
312 const INT64 v = winpr_Data_Get_INT64_BE(_s->pointer);
313 if (seek)
314 Stream_Seek(_s, typesize);
315 return v;
316 }
317
324 static inline UINT8 Stream_Get_UINT8(wStream* _s)
325 {
326 return stream_read_u8(_s, TRUE);
327 }
328
335 static inline INT8 Stream_Get_INT8(wStream* _s)
336 {
337 return stream_read_i8(_s, TRUE);
338 }
339
346 static inline UINT16 Stream_Get_UINT16(wStream* _s)
347 {
348 return stream_read_u16_le(_s, TRUE);
349 }
350
357 static inline INT16 Stream_Get_INT16(wStream* _s)
358 {
359 return stream_read_i16_le(_s, TRUE);
360 }
361
368 static inline UINT16 Stream_Get_UINT16_BE(wStream* _s)
369 {
370 return stream_read_u16_be(_s, TRUE);
371 }
372
379 static inline INT16 Stream_Get_INT16_BE(wStream* _s)
380 {
381 return stream_read_i16_be(_s, TRUE);
382 }
383
390 static inline UINT32 Stream_Get_UINT32(wStream* _s)
391 {
392 return stream_read_u32_le(_s, TRUE);
393 }
394
401 static inline INT32 Stream_Get_INT32(wStream* _s)
402 {
403 return stream_read_i32_le(_s, TRUE);
404 }
405
412 static inline UINT32 Stream_Get_UINT32_BE(wStream* _s)
413 {
414 return stream_read_u32_be(_s, TRUE);
415 }
416
423 static inline INT32 Stream_Get_INT32_BE(wStream* _s)
424 {
425 return stream_read_i32_be(_s, TRUE);
426 }
427
434 static inline UINT64 Stream_Get_UINT64(wStream* _s)
435 {
436 return stream_read_u64_le(_s, TRUE);
437 }
438
445 static inline INT64 Stream_Get_INT64(wStream* _s)
446 {
447 return stream_read_i64_le(_s, TRUE);
448 }
449
456 static inline UINT64 Stream_Get_UINT64_BE(wStream* _s)
457 {
458 return stream_read_u64_be(_s, TRUE);
459 }
460
467 static inline INT64 Stream_Get_INT64_BE(wStream* _s)
468 {
469 return stream_read_i64_be(_s, TRUE);
470 }
471
478 static inline UINT8 Stream_Peek_Get_UINT8(wStream* _s)
479 {
480 return stream_read_u8(_s, FALSE);
481 }
482
489 static inline INT8 Stream_Peek_Get_INT8(wStream* _s)
490 {
491 return stream_read_i8(_s, FALSE);
492 }
493
500 static inline UINT16 Stream_Peek_Get_UINT16(wStream* _s)
501 {
502 return stream_read_u16_le(_s, FALSE);
503 }
504
511 static inline INT16 Stream_Peek_Get_INT16(wStream* _s)
512 {
513 return stream_read_i16_le(_s, FALSE);
514 }
515
522 static inline UINT16 Stream_Peek_Get_UINT16_BE(wStream* _s)
523 {
524 return stream_read_u16_be(_s, FALSE);
525 }
526
533 static inline INT16 Stream_Peek_Get_INT16_BE(wStream* _s)
534 {
535 return stream_read_i16_be(_s, FALSE);
536 }
537
544 static inline UINT32 Stream_Peek_Get_UINT32(wStream* _s)
545 {
546 return stream_read_u32_le(_s, FALSE);
547 }
548
555 static inline INT32 Stream_Peek_Get_INT32(wStream* _s)
556 {
557 return stream_read_i32_le(_s, FALSE);
558 }
559
566 static inline UINT32 Stream_Peek_Get_UINT32_BE(wStream* _s)
567 {
568 return stream_read_u32_be(_s, FALSE);
569 }
570
577 static inline INT32 Stream_Peek_Get_INT32_BE(wStream* _s)
578 {
579 return stream_read_i32_be(_s, FALSE);
580 }
581
588 static inline UINT64 Stream_Peek_Get_UINT64(wStream* _s)
589 {
590 return stream_read_u64_le(_s, FALSE);
591 }
592
599 static inline INT64 Stream_Peek_Get_INT64(wStream* _s)
600 {
601 return stream_read_i64_le(_s, FALSE);
602 }
603
610 static inline UINT64 Stream_Peek_Get_UINT64_BE(wStream* _s)
611 {
612 return stream_read_u64_be(_s, FALSE);
613 }
614
621 static inline INT64 Stream_Peek_Get_INT64_BE(wStream* _s)
622 {
623 return stream_read_i64_be(_s, FALSE);
624 }
625
626#define Stream_Read_UINT8(_s, _v) \
627 do \
628 { \
629 _v = stream_read_u8(_s, TRUE); \
630 } while (0)
631
632#define Stream_Read_INT8(_s, _v) \
633 do \
634 { \
635 _v = stream_read_i8(_s, TRUE); \
636 } while (0)
637
638#define Stream_Read_UINT16(_s, _v) \
639 do \
640 { \
641 _v = stream_read_u16_le(_s, TRUE); \
642 } while (0)
643
644#define Stream_Read_INT16(_s, _v) \
645 do \
646 { \
647 _v = stream_read_i16_le(_s, TRUE); \
648 } while (0)
649
650#define Stream_Read_UINT16_BE(_s, _v) \
651 do \
652 { \
653 _v = stream_read_u16_be(_s, TRUE); \
654 } while (0)
655
656#define Stream_Read_INT16_BE(_s, _v) \
657 do \
658 { \
659 _v = stream_read_i16_be(_s, TRUE); \
660 } while (0)
661
662#define Stream_Read_UINT32(_s, _v) \
663 do \
664 { \
665 _v = stream_read_u32_le(_s, TRUE); \
666 } while (0)
667
668#define Stream_Read_INT32(_s, _v) \
669 do \
670 { \
671 _v = stream_read_i32_le(_s, TRUE); \
672 } while (0)
673
674#define Stream_Read_UINT32_BE(_s, _v) \
675 do \
676 { \
677 _v = stream_read_u32_be(_s, TRUE); \
678 } while (0)
679
680#define Stream_Read_INT32_BE(_s, _v) \
681 do \
682 { \
683 _v = stream_read_i32_be(_s, TRUE); \
684 } while (0)
685
686#define Stream_Read_UINT64(_s, _v) \
687 do \
688 { \
689 _v = stream_read_u64_le(_s, TRUE); \
690 } while (0)
691
692#define Stream_Read_INT64(_s, _v) \
693 do \
694 { \
695 _v = stream_read_i64_le(_s, TRUE); \
696 } while (0)
697
698#define Stream_Read_UINT64_BE(_s, _v) \
699 do \
700 { \
701 _v = stream_read_u64_be(_s, TRUE); \
702 } while (0)
703
704#define Stream_Read_INT64_BE(_s, _v) \
705 do \
706 { \
707 _v = stream_read_i64_be(_s, TRUE); \
708 } while (0)
709
710 static inline void Stream_Read(wStream* _s, void* _b, size_t _n)
711 {
712 WINPR_ASSERT(_s);
713 WINPR_ASSERT(_b || (_n == 0));
714 WINPR_ASSERT(Stream_GetRemainingCapacity(_s) >= _n);
715 memcpy(_b, (_s->pointer), (_n));
716 Stream_Seek(_s, _n);
717 }
718
719#define Stream_Peek_UINT8(_s, _v) \
720 do \
721 { \
722 _v = stream_read_u8(_s, FALSE); \
723 } while (0)
724
725#define Stream_Peek_INT8(_s, _v) \
726 do \
727 { \
728 _v = stream_read_i8(_s, FALSE); \
729 } while (0)
730
731#define Stream_Peek_UINT16(_s, _v) \
732 do \
733 { \
734 _v = stream_read_u16_le(_s, FALSE); \
735 } while (0)
736
737#define Stream_Peek_INT16(_s, _v) \
738 do \
739 { \
740 _v = stream_read_i16_le(_s, FALSE); \
741 } while (0)
742
743#define Stream_Peek_UINT16_BE(_s, _v) \
744 do \
745 { \
746 _v = stream_read_u16_be(_s, FALSE); \
747 } while (0)
748
749#define Stream_Peek_INT16_BE(_s, _v) \
750 do \
751 { \
752 _v = stream_read_i16_be(_s, FALSE); \
753 } while (0)
754
755#define Stream_Peek_UINT32(_s, _v) \
756 do \
757 { \
758 _v = stream_read_u32_le(_s, FALSE); \
759 } while (0)
760
761#define Stream_Peek_INT32(_s, _v) \
762 do \
763 { \
764 _v = stream_read_i32_le(_s, FALSE); \
765 } while (0)
766
767#define Stream_Peek_UINT32_BE(_s, _v) \
768 do \
769 { \
770 _v = stream_read_u32_be(_s, FALSE); \
771 } while (0)
772
773#define Stream_Peek_INT32_BE(_s, _v) \
774 do \
775 { \
776 _v = stream_read_i32_be(_s, FALSE); \
777 } while (0)
778
779#define Stream_Peek_UINT64(_s, _v) \
780 do \
781 { \
782 _v = stream_read_u64_le(_s, FALSE); \
783 } while (0)
784
785#define Stream_Peek_INT64(_s, _v) \
786 do \
787 { \
788 _v = stream_read_i64_le(_s, FALSE); \
789 } while (0)
790
791#define Stream_Peek_UINT64_BE(_s, _v) \
792 do \
793 { \
794 _v = stream_read_u64_be(_s, FALSE); \
795 } while (0)
796
797#define Stream_Peek_INT64_BE(_s, _v) \
798 do \
799 { \
800 _v = stream_read_i64_be(_s, FALSE); \
801 } while (0)
802
803 static inline void Stream_Peek(const wStream* _s, void* _b, size_t _n)
804 {
805 WINPR_ASSERT(_s);
806 WINPR_ASSERT(_b || (_n == 0));
807 WINPR_ASSERT(Stream_GetRemainingCapacity(_s) >= _n);
808 memcpy(_b, (_s->pointer), (_n));
809 }
810
811#define Stream_Write_INT8(s, v) \
812 do \
813 { \
814 WINPR_ASSERT((v) <= INT8_MAX); \
815 WINPR_ASSERT((v) >= INT8_MIN); \
816 Stream_Write_INT8_unchecked((s), (v)); \
817 } while (0)
818
826 static inline void Stream_Write_INT8_unchecked(wStream* _s, INT8 _v)
827 {
828 WINPR_ASSERT(_s);
829 WINPR_ASSERT(_s->pointer);
830 WINPR_ASSERT(Stream_GetRemainingCapacity(_s) >= 1);
831
832 winpr_Data_Write_INT8(_s->pointer, _v);
833 _s->pointer += 1;
834 }
835
836#define Stream_Write_UINT8(s, v) \
837 do \
838 { \
839 WINPR_ASSERT((v) <= UINT8_MAX); \
840 WINPR_ASSERT((v) >= 0); \
841 Stream_Write_UINT8_unchecked((s), (v)); \
842 } while (0)
843
851 static inline void Stream_Write_UINT8_unchecked(wStream* _s, UINT8 _v)
852 {
853 WINPR_ASSERT(_s);
854 WINPR_ASSERT(_s->pointer);
855 WINPR_ASSERT(Stream_GetRemainingCapacity(_s) >= 1);
856
857 winpr_Data_Write_UINT8(_s->pointer, _v);
858 _s->pointer += 1;
859 }
860
861#define Stream_Write_INT16(s, v) \
862 do \
863 { \
864 WINPR_ASSERT((v) >= INT16_MIN); \
865 WINPR_ASSERT((v) <= INT16_MAX); \
866 Stream_Write_INT16_unchecked((s), (v)); \
867 } while (0)
868
877 static inline void Stream_Write_INT16_unchecked(wStream* _s, INT16 _v)
878 {
879 WINPR_ASSERT(_s);
880 WINPR_ASSERT(_s->pointer);
881 WINPR_ASSERT(Stream_GetRemainingCapacity(_s) >= 2);
882
883 winpr_Data_Write_INT16(_s->pointer, _v);
884 _s->pointer += 2;
885 }
886
887#define Stream_Write_UINT16(s, v) \
888 do \
889 { \
890 WINPR_ASSERT((v) <= UINT16_MAX); \
891 WINPR_ASSERT((v) >= 0); \
892 Stream_Write_UINT16_unchecked((s), (v)); \
893 } while (0)
894
903 static inline void Stream_Write_UINT16_unchecked(wStream* _s, UINT16 _v)
904 {
905 WINPR_ASSERT(_s);
906 WINPR_ASSERT(_s->pointer);
907 WINPR_ASSERT(Stream_GetRemainingCapacity(_s) >= 2);
908
909 winpr_Data_Write_UINT16(_s->pointer, _v);
910 _s->pointer += 2;
911 }
912
913#define Stream_Write_UINT16_BE(s, v) \
914 do \
915 { \
916 WINPR_ASSERT((v) <= UINT16_MAX); \
917 WINPR_ASSERT((v) >= 0); \
918 Stream_Write_UINT16_BE_unchecked((s), (v)); \
919 } while (0)
920
929 static inline void Stream_Write_UINT16_BE_unchecked(wStream* _s, UINT16 _v)
930 {
931 WINPR_ASSERT(_s);
932 WINPR_ASSERT(_s->pointer);
933 WINPR_ASSERT(Stream_GetRemainingCapacity(_s) >= 2);
934
935 winpr_Data_Write_UINT16_BE(_s->pointer, _v);
936 _s->pointer += 2;
937 }
938
939#define Stream_Write_INT16_BE(s, v) \
940 do \
941 { \
942 WINPR_ASSERT((v) <= INT16_MAX); \
943 WINPR_ASSERT((v) >= INT16_MIN); \
944 Stream_Write_INT16_BE_unchecked((s), (v)); \
945 } while (0)
946
957 static inline void Stream_Write_INT16_BE_unchecked(wStream* _s, INT16 _v)
958 {
959 WINPR_ASSERT(_s);
960 WINPR_ASSERT(_s->pointer);
961 WINPR_ASSERT(Stream_GetRemainingCapacity(_s) >= 2);
962
963 winpr_Data_Write_INT16_BE(_s->pointer, _v);
964 _s->pointer += 2;
965 }
966
967#define Stream_Write_UINT24_BE(s, v) \
968 do \
969 { \
970 WINPR_ASSERT((v) <= 0xFFFFFF); \
971 WINPR_ASSERT((v) >= 0); \
972 Stream_Write_UINT24_BE_unchecked((s), (v)); \
973 } while (0)
974
983 static inline void Stream_Write_UINT24_BE_unchecked(wStream* _s, UINT32 _v)
984 {
985 WINPR_ASSERT(_s);
986 WINPR_ASSERT(_s->pointer);
987 WINPR_ASSERT(_v <= 0x00FFFFFF);
988 WINPR_ASSERT(Stream_GetRemainingCapacity(_s) >= 3);
989
990 *_s->pointer++ = ((_v) >> 16) & 0xFF;
991 *_s->pointer++ = ((_v) >> 8) & 0xFF;
992 *_s->pointer++ = (_v) & 0xFF;
993 }
994
995#define Stream_Write_INT32(s, v) \
996 do \
997 { \
998 WINPR_ASSERT((v) <= INT32_MAX); \
999 WINPR_ASSERT((v) >= INT32_MIN); \
1000 Stream_Write_INT32_unchecked((s), (v)); \
1001 } while (0)
1002
1011 static inline void Stream_Write_INT32_unchecked(wStream* _s, INT32 _v)
1012 {
1013 WINPR_ASSERT(_s);
1014 WINPR_ASSERT(_s->pointer);
1015 WINPR_ASSERT(Stream_GetRemainingCapacity(_s) >= 4);
1016
1017 winpr_Data_Write_INT32(_s->pointer, _v);
1018 _s->pointer += 4;
1019 }
1020
1021#define Stream_Write_INT32_BE(s, v) \
1022 do \
1023 { \
1024 WINPR_ASSERT((v) <= INT32_MAX); \
1025 WINPR_ASSERT((v) >= INT32_MIN); \
1026 Stream_Write_INT32_BE_unchecked((s), (v)); \
1027 } while (0)
1028
1039 static inline void Stream_Write_INT32_BE_unchecked(wStream* _s, INT32 _v)
1040 {
1041 WINPR_ASSERT(_s);
1042 WINPR_ASSERT(_s->pointer);
1043 WINPR_ASSERT(Stream_GetRemainingCapacity(_s) >= 4);
1044
1045 winpr_Data_Write_INT32_BE(_s->pointer, _v);
1046 _s->pointer += 4;
1047 }
1048
1049#define Stream_Write_UINT32(s, v) \
1050 do \
1051 { \
1052 WINPR_ASSERT((v) <= UINT32_MAX); \
1053 WINPR_ASSERT((v) >= 0); \
1054 Stream_Write_UINT32_unchecked((s), (v)); \
1055 } while (0)
1056
1065 static inline void Stream_Write_UINT32_unchecked(wStream* _s, UINT32 _v)
1066 {
1067 WINPR_ASSERT(_s);
1068 WINPR_ASSERT(_s->pointer);
1069 WINPR_ASSERT(Stream_GetRemainingCapacity(_s) >= 4);
1070
1071 winpr_Data_Write_UINT32(_s->pointer, _v);
1072 _s->pointer += 4;
1073 }
1074
1075#define Stream_Write_UINT32_BE(s, v) \
1076 do \
1077 { \
1078 WINPR_ASSERT((v) <= UINT32_MAX); \
1079 WINPR_ASSERT((v) >= 0); \
1080 Stream_Write_UINT32_BE_unchecked((s), (v)); \
1081 } while (0)
1082
1091 static inline void Stream_Write_UINT32_BE_unchecked(wStream* _s, UINT32 _v)
1092 {
1093 WINPR_ASSERT(Stream_GetRemainingCapacity(_s) >= 4);
1094
1095 winpr_Data_Write_UINT32_BE(_s->pointer, _v);
1096 _s->pointer += 4;
1097 }
1098
1105 static inline void Stream_Write_UINT64(wStream* _s, UINT64 _v)
1106 {
1107 WINPR_ASSERT(_s);
1108 WINPR_ASSERT(_s->pointer);
1109 WINPR_ASSERT(Stream_GetRemainingCapacity(_s) >= 8);
1110
1111 winpr_Data_Write_UINT64(_s->pointer, _v);
1112 _s->pointer += 8;
1113 }
1114
1121 static inline void Stream_Write_UINT64_BE(wStream* _s, UINT64 _v)
1122 {
1123 WINPR_ASSERT(_s);
1124 WINPR_ASSERT(_s->pointer);
1125 WINPR_ASSERT(Stream_GetRemainingCapacity(_s) >= 8);
1126
1127 winpr_Data_Write_UINT64_BE(_s->pointer, _v);
1128 _s->pointer += 8;
1129 }
1130
1138 static inline void Stream_Write_INT64(wStream* _s, INT64 _v)
1139 {
1140 WINPR_ASSERT(_s);
1141 WINPR_ASSERT(_s->pointer);
1142 WINPR_ASSERT(Stream_GetRemainingCapacity(_s) >= 8);
1143
1144 winpr_Data_Write_INT64(_s->pointer, _v);
1145 _s->pointer += 8;
1146 }
1147
1155 static inline void Stream_Write_INT64_BE(wStream* _s, INT64 _v)
1156 {
1157 WINPR_ASSERT(_s);
1158 WINPR_ASSERT(_s->pointer);
1159 WINPR_ASSERT(Stream_GetRemainingCapacity(_s) >= 8);
1160
1161 winpr_Data_Write_INT64_BE(_s->pointer, _v);
1162 _s->pointer += 8;
1163 }
1164
1165 static inline void Stream_Write(wStream* _s, const void* _b, size_t _n)
1166 {
1167 if (_n > 0)
1168 {
1169 WINPR_ASSERT(_s);
1170 WINPR_ASSERT(_b);
1171 WINPR_ASSERT(Stream_GetRemainingCapacity(_s) >= _n);
1172 memcpy(_s->pointer, (_b), (_n));
1173 Stream_Seek(_s, _n);
1174 }
1175 }
1176
1177 static inline void Stream_Seek_UINT8(wStream* _s)
1178 {
1179 Stream_Seek(_s, sizeof(UINT8));
1180 }
1181 static inline void Stream_Seek_UINT16(wStream* _s)
1182 {
1183 Stream_Seek(_s, sizeof(UINT16));
1184 }
1185 static inline void Stream_Seek_UINT32(wStream* _s)
1186 {
1187 Stream_Seek(_s, sizeof(UINT32));
1188 }
1189 static inline void Stream_Seek_UINT64(wStream* _s)
1190 {
1191 Stream_Seek(_s, sizeof(UINT64));
1192 }
1193
1194 static inline void Stream_Rewind_UINT8(wStream* _s)
1195 {
1196 Stream_Rewind(_s, sizeof(UINT8));
1197 }
1198 static inline void Stream_Rewind_UINT16(wStream* _s)
1199 {
1200 Stream_Rewind(_s, sizeof(UINT16));
1201 }
1202 static inline void Stream_Rewind_UINT32(wStream* _s)
1203 {
1204 Stream_Rewind(_s, sizeof(UINT32));
1205 }
1206 static inline void Stream_Rewind_UINT64(wStream* _s)
1207 {
1208 Stream_Rewind(_s, sizeof(UINT64));
1209 }
1210
1211 static inline void Stream_Fill(wStream* _s, int _v, size_t _n)
1212 {
1213 WINPR_ASSERT(_s);
1214 WINPR_ASSERT(Stream_GetRemainingCapacity(_s) >= (_n));
1215 memset(_s->pointer, _v, (_n));
1216 Stream_Seek(_s, _n);
1217 }
1218
1219 static inline void Stream_Zero(wStream* _s, size_t _n)
1220 {
1221 Stream_Fill(_s, '\0', _n);
1222 }
1223
1224 static inline void Stream_Copy(wStream* _src, wStream* _dst, size_t _n)
1225 {
1226 WINPR_ASSERT(_src);
1227 WINPR_ASSERT(_dst);
1228 WINPR_ASSERT(Stream_GetRemainingCapacity(_src) >= (_n));
1229 WINPR_ASSERT(Stream_GetRemainingCapacity(_dst) >= (_n));
1230
1231 memcpy(_dst->pointer, _src->pointer, _n);
1232 Stream_Seek(_dst, _n);
1233 Stream_Seek(_src, _n);
1234 }
1235
1240#define Stream_BufferAs(s, type) WINPR_STREAM_CAST(type*, Stream_Buffer(s))
1241
1242 static inline BYTE* Stream_Buffer(wStream* _s)
1243 {
1244 WINPR_ASSERT(_s);
1245 return _s->buffer;
1246 }
1247
1252#define Stream_ConstBufferAs(s, type) WINPR_STREAM_CAST(type*, Stream_ConstBuffer(s))
1253 static inline const BYTE* Stream_ConstBuffer(const wStream* _s)
1254 {
1255 WINPR_ASSERT(_s);
1256 return _s->buffer;
1257 }
1258
1259#define Stream_GetBuffer(_s, _b) _b = Stream_Buffer(_s)
1260
1265#define Stream_GetBufferAs(_s, _b) _b = Stream_BufferAs(_s, __typeof(_b))
1266
1267#define Stream_PointerAs(s, type) WINPR_STREAM_CAST(type*, Stream_Pointer(s))
1268
1269 static inline void* Stream_Pointer(wStream* _s)
1270 {
1271 WINPR_ASSERT(_s);
1272 return _s->pointer;
1273 }
1274
1275 static inline const void* Stream_ConstPointer(const wStream* _s)
1276 {
1277 WINPR_ASSERT(_s);
1278 return _s->pointer;
1279 }
1280
1281#define Stream_GetPointer(_s, _p) _p = Stream_Pointer(_s)
1282
1287#define Stream_GetPointerAs(_s, _p) _p = Stream_PointerAs(_s, __typeof(_p))
1288
1289#if defined(WITH_WINPR_DEPRECATED)
1290 WINPR_DEPRECATED_VAR("Use Stream_SetPosition instead",
1291 WINPR_API BOOL Stream_SetPointer(wStream* _s, BYTE* _p));
1292 WINPR_DEPRECATED_VAR("Use Stream_New(buffer, capacity) instead",
1293 WINPR_API BOOL Stream_SetBuffer(wStream* _s, BYTE* _b));
1294 WINPR_DEPRECATED_VAR("Use Stream_New(buffer, capacity) instead",
1295 WINPR_API void Stream_SetCapacity(wStream* _s, size_t capacity));
1296#endif
1297
1298 static inline size_t Stream_Length(const wStream* _s)
1299 {
1300 WINPR_ASSERT(_s);
1301 return _s->length;
1302 }
1303
1304#define Stream_GetLength(_s, _l) _l = Stream_Length(_s)
1305 WINPR_API BOOL Stream_SetLength(wStream* _s, size_t _l);
1306
1307 static inline size_t Stream_Capacity(const wStream* _s)
1308 {
1309 WINPR_ASSERT(_s);
1310 return _s->capacity;
1311 }
1312
1313#define Stream_GetCapacity(_s, _c) _c = Stream_Capacity(_s);
1314
1315 static inline size_t Stream_GetPosition(const wStream* _s)
1316 {
1317 WINPR_ASSERT(_s);
1318 WINPR_ASSERT(_s->buffer <= _s->pointer);
1319 return WINPR_STREAM_CAST(size_t, (_s->pointer - _s->buffer));
1320 }
1321
1322 WINPR_API BOOL Stream_SetPosition(wStream* _s, size_t _p);
1323
1324 WINPR_API void Stream_SealLength(wStream* _s);
1325
1326 static inline void Stream_Clear(wStream* _s)
1327 {
1328 WINPR_ASSERT(_s);
1329 memset(_s->buffer, 0, _s->capacity);
1330 }
1331
1332#define Stream_SafeSeek(s, size) Stream_SafeSeekEx(s, size, __FILE__, __LINE__, __func__)
1333 WINPR_API BOOL Stream_SafeSeekEx(wStream* s, size_t size, const char* file, size_t line,
1334 const char* fkt);
1335
1336 WINPR_API BOOL Stream_Read_UTF16_String(wStream* s, WCHAR* dst, size_t charLength);
1337 WINPR_API BOOL Stream_Write_UTF16_String(wStream* s, const WCHAR* src, size_t charLength);
1338
1348 WINPR_API char* Stream_Read_UTF16_String_As_UTF8(wStream* s, size_t wcharLength,
1349 size_t* pUtfCharLength);
1350
1360 WINPR_API SSIZE_T Stream_Read_UTF16_String_As_UTF8_Buffer(wStream* s, size_t wcharLength,
1361 char* utfBuffer,
1362 size_t utfBufferCharLength);
1363
1375 WINPR_API SSIZE_T Stream_Write_UTF16_String_From_UTF8(wStream* s, size_t wcharLength,
1376 const char* src, size_t length,
1377 BOOL fill);
1378
1379 /* StreamPool */
1380
1381 WINPR_API void StreamPool_Return(wStreamPool* pool, wStream* s);
1382
1388 WINPR_API void Stream_AddRef(wStream* s);
1389
1397 WINPR_API void Stream_Release(wStream* s);
1398
1399 WINPR_ATTR_MALLOC(Stream_Release, 1)
1400 WINPR_ATTR_NODISCARD
1401 WINPR_API wStream* StreamPool_Take(wStreamPool* pool, size_t size);
1402
1403 WINPR_API wStream* StreamPool_Find(wStreamPool* pool, const BYTE* ptr);
1404
1413 WINPR_API size_t StreamPool_UsedCount(wStreamPool* pool);
1414
1425 WINPR_API BOOL StreamPool_WaitForReturn(wStreamPool* pool, UINT32 timeoutMS);
1426
1427 WINPR_API void StreamPool_Clear(wStreamPool* pool);
1428
1429 WINPR_API void StreamPool_Free(wStreamPool* pool);
1430
1431 WINPR_ATTR_MALLOC(StreamPool_Free, 1)
1432 WINPR_ATTR_NODISCARD
1433 WINPR_API wStreamPool* StreamPool_New(BOOL synchronized, size_t defaultSize);
1434
1435 WINPR_API char* StreamPool_GetStatistics(wStreamPool* pool, char* buffer, size_t size);
1436
1437#ifdef __cplusplus
1438}
1439#endif
1440
1441#endif /* WINPR_UTILS_STREAM_H */