FreeRDP
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 
32 #ifdef __cplusplus
33 extern "C"
34 {
35 #endif
36 
37  typedef struct s_wStreamPool wStreamPool;
38 
39  typedef struct
40  {
41  BYTE* buffer;
42  BYTE* pointer;
43  size_t length;
44  size_t capacity;
45 
46  DWORD count;
47  wStreamPool* pool;
48  BOOL isAllocatedStream;
49  BOOL isOwner;
50  } wStream;
51 
52  static INLINE size_t Stream_Capacity(const wStream* _s);
53  WINPR_API size_t Stream_GetRemainingCapacity(const wStream* _s);
54  WINPR_API size_t Stream_GetRemainingLength(const wStream* _s);
55 
56  WINPR_API BOOL Stream_EnsureCapacity(wStream* s, size_t size);
57  WINPR_API BOOL Stream_EnsureRemainingCapacity(wStream* s, size_t size);
58 
59 #ifdef __cplusplus
60 #define WINPR_STREAM_CAST(t, val) static_cast<t>(val)
61 #else
62 #define WINPR_STREAM_CAST(t, val) (t)(val)
63 #endif
64 
65 #define Stream_CheckAndLogRequiredCapacityOfSize(tag, s, nmemb, size) \
66  Stream_CheckAndLogRequiredCapacityEx(tag, WLOG_WARN, s, nmemb, size, "%s(%s:%" PRIuz ")", \
67  __func__, __FILE__, (size_t)__LINE__)
68 #define Stream_CheckAndLogRequiredCapacity(tag, s, len) \
69  Stream_CheckAndLogRequiredCapacityOfSize((tag), (s), (len), 1)
70 
71  WINPR_API BOOL Stream_CheckAndLogRequiredCapacityEx(const char* tag, DWORD level, wStream* s,
72  size_t nmemb, size_t size, const char* fmt,
73  ...);
74  WINPR_API BOOL Stream_CheckAndLogRequiredCapacityExVa(const char* tag, DWORD level, wStream* s,
75  size_t nmemb, size_t size,
76  const char* fmt, va_list args);
77 
78 #define Stream_CheckAndLogRequiredCapacityOfSizeWLog(log, s, nmemb, size) \
79  Stream_CheckAndLogRequiredCapacityWLogEx(log, WLOG_WARN, s, nmemb, size, "%s(%s:%" PRIuz ")", \
80  __func__, __FILE__, (size_t)__LINE__)
81 
82 #define Stream_CheckAndLogRequiredCapacityWLog(log, s, len) \
83  Stream_CheckAndLogRequiredCapacityOfSizeWLog((log), (s), (len), 1)
84 
85  WINPR_API BOOL Stream_CheckAndLogRequiredCapacityWLogEx(wLog* log, DWORD level, wStream* s,
86  size_t nmemb, size_t size,
87  const char* fmt, ...);
88  WINPR_API BOOL Stream_CheckAndLogRequiredCapacityWLogExVa(wLog* log, DWORD level, wStream* s,
89  size_t nmemb, size_t size,
90  const char* fmt, va_list args);
91 
92  WINPR_API void Stream_Free(wStream* s, BOOL bFreeBuffer);
93 
94  WINPR_ATTR_MALLOC(Stream_Free, 1)
95  WINPR_API wStream* Stream_New(BYTE* buffer, size_t size);
96  WINPR_API wStream* Stream_StaticConstInit(wStream* s, const BYTE* buffer, size_t size);
97  WINPR_API wStream* Stream_StaticInit(wStream* s, BYTE* buffer, size_t size);
98 
99 #define Stream_CheckAndLogRequiredLengthOfSize(tag, s, nmemb, size) \
100  Stream_CheckAndLogRequiredLengthEx(tag, WLOG_WARN, s, nmemb, size, "%s(%s:%" PRIuz ")", \
101  __func__, __FILE__, (size_t)__LINE__)
102 #define Stream_CheckAndLogRequiredLength(tag, s, len) \
103  Stream_CheckAndLogRequiredLengthOfSize(tag, s, len, 1)
104 
105  WINPR_API BOOL Stream_CheckAndLogRequiredLengthEx(const char* tag, DWORD level, wStream* s,
106  size_t nmemb, size_t size, const char* fmt,
107  ...);
108  WINPR_API BOOL Stream_CheckAndLogRequiredLengthExVa(const char* tag, DWORD level, wStream* s,
109  size_t nmemb, size_t size, const char* fmt,
110  va_list args);
111 
112 #define Stream_CheckAndLogRequiredLengthOfSizeWLog(log, s, nmemb, size) \
113  Stream_CheckAndLogRequiredLengthWLogEx(log, WLOG_WARN, s, nmemb, size, "%s(%s:%" PRIuz ")", \
114  __func__, __FILE__, (size_t)__LINE__)
115 #define Stream_CheckAndLogRequiredLengthWLog(log, s, len) \
116  Stream_CheckAndLogRequiredLengthOfSizeWLog(log, s, len, 1)
117 
118  WINPR_API BOOL Stream_CheckAndLogRequiredLengthWLogEx(wLog* log, DWORD level, wStream* s,
119  size_t nmemb, size_t size,
120  const char* fmt, ...);
121  WINPR_API BOOL Stream_CheckAndLogRequiredLengthWLogExVa(wLog* log, DWORD level, wStream* s,
122  size_t nmemb, size_t size,
123  const char* fmt, va_list args);
124 
125  static INLINE void Stream_Seek(wStream* s, size_t _offset)
126  {
127  WINPR_ASSERT(s);
128  WINPR_ASSERT(Stream_GetRemainingCapacity(s) >= _offset);
129  s->pointer += (_offset);
130  }
131 
132  static INLINE void Stream_Rewind(wStream* s, size_t _offset)
133  {
134  size_t cur = 0;
135  WINPR_ASSERT(s);
136  WINPR_ASSERT(s->buffer <= s->pointer);
137  cur = WINPR_STREAM_CAST(size_t, s->pointer - s->buffer);
138  WINPR_ASSERT(cur >= _offset);
139  if (cur >= _offset)
140  s->pointer -= (_offset);
141  else
142  s->pointer = s->buffer;
143  }
144 
145  static INLINE UINT8 stream_read_u8(wStream* _s, BOOL seek)
146  {
147  WINPR_ASSERT(_s);
148  WINPR_ASSERT(Stream_GetRemainingLength(_s) >= sizeof(UINT8));
149 
150  const UINT8 v = *(_s)->pointer;
151  if (seek)
152  Stream_Seek(_s, sizeof(UINT8));
153  return v;
154  }
155 
156  static INLINE INT8 stream_read_i8(wStream* _s, BOOL seek)
157  {
158  const UINT8 v = stream_read_u8(_s, seek);
159  return WINPR_STREAM_CAST(INT8, v);
160  }
161 
162  static INLINE UINT16 stream_read_u16_le(wStream* _s, BOOL seek)
163  {
164  const size_t typesize = sizeof(UINT16);
165  WINPR_ASSERT(_s);
166  WINPR_ASSERT(Stream_GetRemainingLength(_s) >= typesize);
167 
168  UINT16 v = 0;
169  for (size_t x = 0; x < typesize; x++)
170  {
171  v <<= 8;
172  v |= (_s)->pointer[typesize - x - 1];
173  }
174  if (seek)
175  Stream_Seek(_s, typesize);
176  return v;
177  }
178 
179  static INLINE UINT16 stream_read_u16_be(wStream* _s, BOOL seek)
180  {
181  const size_t typesize = sizeof(UINT16);
182  WINPR_ASSERT(_s);
183  WINPR_ASSERT(Stream_GetRemainingLength(_s) >= typesize);
184 
185  UINT16 v = 0;
186  for (size_t x = 0; x < typesize; x++)
187  {
188  v <<= 8;
189  v |= (_s)->pointer[x];
190  }
191  if (seek)
192  Stream_Seek(_s, typesize);
193  return v;
194  }
195 
196  static INLINE INT16 stream_read_i16_le(wStream* _s, BOOL seek)
197  {
198  const UINT16 v = stream_read_u16_le(_s, seek);
199  return WINPR_STREAM_CAST(INT16, v);
200  }
201 
202  static INLINE INT16 stream_read_i16_be(wStream* _s, BOOL seek)
203  {
204  const UINT16 v = stream_read_u16_be(_s, seek);
205  return WINPR_STREAM_CAST(INT16, v);
206  }
207 
208  static INLINE UINT32 stream_read_u32_le(wStream* _s, BOOL seek)
209  {
210  const size_t typesize = sizeof(UINT32);
211  WINPR_ASSERT(_s);
212  WINPR_ASSERT(Stream_GetRemainingLength(_s) >= typesize);
213 
214  UINT32 v = 0;
215  for (size_t x = 0; x < typesize; x++)
216  {
217  v <<= 8;
218  v |= (_s)->pointer[typesize - x - 1];
219  }
220  if (seek)
221  Stream_Seek(_s, typesize);
222  return v;
223  }
224 
225  static INLINE UINT32 stream_read_u32_be(wStream* _s, BOOL seek)
226  {
227  const size_t typesize = sizeof(UINT32);
228  WINPR_ASSERT(_s);
229  WINPR_ASSERT(Stream_GetRemainingLength(_s) >= typesize);
230 
231  UINT32 v = 0;
232  for (size_t x = 0; x < typesize; x++)
233  {
234  v <<= 8;
235  v |= (_s)->pointer[x];
236  }
237  if (seek)
238  Stream_Seek(_s, typesize);
239  return v;
240  }
241 
242  static INLINE INT32 stream_read_i32_le(wStream* _s, BOOL seek)
243  {
244  const UINT32 v = stream_read_u32_le(_s, seek);
245  return WINPR_STREAM_CAST(INT32, v);
246  }
247 
248  static INLINE INT32 stream_read_i32_be(wStream* _s, BOOL seek)
249  {
250  const UINT32 v = stream_read_u32_be(_s, seek);
251  return WINPR_STREAM_CAST(INT32, v);
252  }
253 
254  static INLINE UINT64 stream_read_u64_le(wStream* _s, BOOL seek)
255  {
256  const size_t typesize = sizeof(UINT64);
257  WINPR_ASSERT(_s);
258  WINPR_ASSERT(Stream_GetRemainingLength(_s) >= typesize);
259 
260  UINT64 v = 0;
261  for (size_t x = 0; x < typesize; x++)
262  {
263  v <<= 8;
264  v |= (_s)->pointer[typesize - x - 1];
265  }
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  UINT64 v = 0;
278  for (size_t x = 0; x < typesize; x++)
279  {
280  v <<= 8;
281  v |= (_s)->pointer[x];
282  }
283  if (seek)
284  Stream_Seek(_s, typesize);
285  return v;
286  }
287 
288  static INLINE INT64 stream_read_i64_le(wStream* _s, BOOL seek)
289  {
290  const UINT64 v = stream_read_u64_le(_s, seek);
291  return WINPR_STREAM_CAST(INT64, v);
292  }
293 
294  static INLINE INT64 stream_read_i64_be(wStream* _s, BOOL seek)
295  {
296  const UINT64 v = stream_read_u64_be(_s, seek);
297  return WINPR_STREAM_CAST(INT64, v);
298  }
299 
306  static INLINE UINT8 Stream_Get_UINT8(wStream* _s)
307  {
308  return stream_read_u8(_s, TRUE);
309  }
310 
317  static INLINE INT8 Stream_Get_INT8(wStream* _s)
318  {
319  return stream_read_i8(_s, TRUE);
320  }
321 
328  static INLINE UINT16 Stream_Get_UINT16(wStream* _s)
329  {
330  return stream_read_u16_le(_s, TRUE);
331  }
332 
339  static INLINE INT16 Stream_Get_INT16(wStream* _s)
340  {
341  return stream_read_i16_le(_s, TRUE);
342  }
343 
350  static INLINE UINT16 Stream_Get_UINT16_BE(wStream* _s)
351  {
352  return stream_read_u16_be(_s, TRUE);
353  }
354 
361  static INLINE INT16 Stream_Get_INT16_BE(wStream* _s)
362  {
363  return stream_read_i16_be(_s, TRUE);
364  }
365 
372  static INLINE UINT32 Stream_Get_UINT32(wStream* _s)
373  {
374  return stream_read_u32_le(_s, TRUE);
375  }
376 
383  static INLINE INT32 Stream_Get_INT32(wStream* _s)
384  {
385  return stream_read_i32_le(_s, TRUE);
386  }
387 
394  static INLINE UINT32 Stream_Get_UINT32_BE(wStream* _s)
395  {
396  return stream_read_u32_be(_s, TRUE);
397  }
398 
405  static INLINE INT32 Stream_Get_INT32_BE(wStream* _s)
406  {
407  return stream_read_i32_be(_s, TRUE);
408  }
409 
416  static INLINE UINT64 Stream_Get_UINT64(wStream* _s)
417  {
418  return stream_read_u64_le(_s, TRUE);
419  }
420 
427  static INLINE INT64 Stream_Get_INT64(wStream* _s)
428  {
429  return stream_read_i64_le(_s, TRUE);
430  }
431 
438  static INLINE UINT64 Stream_Get_UINT64_BE(wStream* _s)
439  {
440  return stream_read_u64_be(_s, TRUE);
441  }
442 
449  static INLINE INT64 Stream_Get_INT64_BE(wStream* _s)
450  {
451  return stream_read_i64_be(_s, TRUE);
452  }
453 
460  static INLINE UINT8 Stream_Peek_Get_UINT8(wStream* _s)
461  {
462  return stream_read_u8(_s, FALSE);
463  }
464 
471  static INLINE INT8 Stream_Peek_Get_INT8(wStream* _s)
472  {
473  return stream_read_i8(_s, FALSE);
474  }
475 
482  static INLINE UINT16 Stream_Peek_Get_UINT16(wStream* _s)
483  {
484  return stream_read_u16_le(_s, FALSE);
485  }
486 
493  static INLINE INT16 Stream_Peek_Get_INT16(wStream* _s)
494  {
495  return stream_read_i16_le(_s, FALSE);
496  }
497 
504  static INLINE UINT16 Stream_Peek_Get_UINT16_BE(wStream* _s)
505  {
506  return stream_read_u16_be(_s, FALSE);
507  }
508 
515  static INLINE INT16 Stream_Peek_Get_INT16_BE(wStream* _s)
516  {
517  return stream_read_i16_be(_s, FALSE);
518  }
519 
526  static INLINE UINT32 Stream_Peek_Get_UINT32(wStream* _s)
527  {
528  return stream_read_u32_le(_s, FALSE);
529  }
530 
537  static INLINE INT32 Stream_Peek_Get_INT32(wStream* _s)
538  {
539  return stream_read_i32_le(_s, FALSE);
540  }
541 
548  static INLINE UINT32 Stream_Peek_Get_UINT32_BE(wStream* _s)
549  {
550  return stream_read_u32_be(_s, FALSE);
551  }
552 
559  static INLINE INT32 Stream_Peek_Get_INT32_BE(wStream* _s)
560  {
561  return stream_read_i32_be(_s, FALSE);
562  }
563 
570  static INLINE UINT64 Stream_Peek_Get_UINT64(wStream* _s)
571  {
572  return stream_read_u64_le(_s, FALSE);
573  }
574 
581  static INLINE INT64 Stream_Peek_Get_INT64(wStream* _s)
582  {
583  return stream_read_i64_le(_s, FALSE);
584  }
585 
592  static INLINE UINT64 Stream_Peek_Get_UINT64_BE(wStream* _s)
593  {
594  return stream_read_u64_be(_s, FALSE);
595  }
596 
603  static INLINE INT64 Stream_Peek_Get_INT64_BE(wStream* _s)
604  {
605  return stream_read_i64_be(_s, FALSE);
606  }
607 
608 #define Stream_Read_UINT8(_s, _v) \
609  do \
610  { \
611  _v = stream_read_u8(_s, TRUE); \
612  } while (0)
613 
614 #define Stream_Read_INT8(_s, _v) \
615  do \
616  { \
617  _v = stream_read_i8(_s, TRUE); \
618  } while (0)
619 
620 #define Stream_Read_UINT16(_s, _v) \
621  do \
622  { \
623  _v = stream_read_u16_le(_s, TRUE); \
624  } while (0)
625 
626 #define Stream_Read_INT16(_s, _v) \
627  do \
628  { \
629  _v = stream_read_i16_le(_s, TRUE); \
630  } while (0)
631 
632 #define Stream_Read_UINT16_BE(_s, _v) \
633  do \
634  { \
635  _v = stream_read_u16_be(_s, TRUE); \
636  } while (0)
637 
638 #define Stream_Read_INT16_BE(_s, _v) \
639  do \
640  { \
641  _v = stream_read_i16_be(_s, TRUE); \
642  } while (0)
643 
644 #define Stream_Read_UINT32(_s, _v) \
645  do \
646  { \
647  _v = stream_read_u32_le(_s, TRUE); \
648  } while (0)
649 
650 #define Stream_Read_INT32(_s, _v) \
651  do \
652  { \
653  _v = stream_read_i32_le(_s, TRUE); \
654  } while (0)
655 
656 #define Stream_Read_UINT32_BE(_s, _v) \
657  do \
658  { \
659  _v = stream_read_u32_be(_s, TRUE); \
660  } while (0)
661 
662 #define Stream_Read_INT32_BE(_s, _v) \
663  do \
664  { \
665  _v = stream_read_i32_be(_s, TRUE); \
666  } while (0)
667 
668 #define Stream_Read_UINT64(_s, _v) \
669  do \
670  { \
671  _v = stream_read_u64_le(_s, TRUE); \
672  } while (0)
673 
674 #define Stream_Read_INT64(_s, _v) \
675  do \
676  { \
677  _v = stream_read_i64_le(_s, TRUE); \
678  } while (0)
679 
680 #define Stream_Read_UINT64_BE(_s, _v) \
681  do \
682  { \
683  _v = stream_read_u64_be(_s, TRUE); \
684  } while (0)
685 
686 #define Stream_Read_INT64_BE(_s, _v) \
687  do \
688  { \
689  _v = stream_read_i64_be(_s, TRUE); \
690  } while (0)
691 
692  static INLINE void Stream_Read(wStream* _s, void* _b, size_t _n)
693  {
694  WINPR_ASSERT(_s);
695  WINPR_ASSERT(_b || (_n == 0));
696  WINPR_ASSERT(Stream_GetRemainingCapacity(_s) >= _n);
697  memcpy(_b, (_s->pointer), (_n));
698  Stream_Seek(_s, _n);
699  }
700 
701 #define Stream_Peek_UINT8(_s, _v) \
702  do \
703  { \
704  _v = stream_read_u8(_s, FALSE); \
705  } while (0)
706 
707 #define Stream_Peek_INT8(_s, _v) \
708  do \
709  { \
710  _v = stream_read_i8(_s, FALSE); \
711  } while (0)
712 
713 #define Stream_Peek_UINT16(_s, _v) \
714  do \
715  { \
716  _v = stream_read_u16_le(_s, FALSE); \
717  } while (0)
718 
719 #define Stream_Peek_INT16(_s, _v) \
720  do \
721  { \
722  _v = stream_read_i16_le(_s, FALSE); \
723  } while (0)
724 
725 #define Stream_Peek_UINT16_BE(_s, _v) \
726  do \
727  { \
728  _v = stream_read_u16_be(_s, FALSE); \
729  } while (0)
730 
731 #define Stream_Peek_INT16_BE(_s, _v) \
732  do \
733  { \
734  _v = stream_read_i16_be(_s, FALSE); \
735  } while (0)
736 
737 #define Stream_Peek_UINT32(_s, _v) \
738  do \
739  { \
740  _v = stream_read_u32_le(_s, FALSE); \
741  } while (0)
742 
743 #define Stream_Peek_INT32(_s, _v) \
744  do \
745  { \
746  _v = stream_read_i32_le(_s, FALSE); \
747  } while (0)
748 
749 #define Stream_Peek_UINT32_BE(_s, _v) \
750  do \
751  { \
752  _v = stream_read_u32_be(_s, FALSE); \
753  } while (0)
754 
755 #define Stream_Peek_INT32_BE(_s, _v) \
756  do \
757  { \
758  _v = stream_read_i32_be(_s, FALSE); \
759  } while (0)
760 
761 #define Stream_Peek_UINT64(_s, _v) \
762  do \
763  { \
764  _v = stream_read_u64_le(_s, FALSE); \
765  } while (0)
766 
767 #define Stream_Peek_INT64(_s, _v) \
768  do \
769  { \
770  _v = stream_read_i64_le(_s, FALSE); \
771  } while (0)
772 
773 #define Stream_Peek_UINT64_BE(_s, _v) \
774  do \
775  { \
776  _v = stream_read_u64_be(_s, FALSE); \
777  } while (0)
778 
779 #define Stream_Peek_INT64_BE(_s, _v) \
780  do \
781  { \
782  _v = stream_read_i64_be(_s, FALSE); \
783  } while (0)
784 
785  static INLINE void Stream_Peek(const wStream* _s, void* _b, size_t _n)
786  {
787  WINPR_ASSERT(_s);
788  WINPR_ASSERT(_b || (_n == 0));
789  WINPR_ASSERT(Stream_GetRemainingCapacity(_s) >= _n);
790  memcpy(_b, (_s->pointer), (_n));
791  }
792 
793  static INLINE void Stream_Write_UINT8(wStream* _s, UINT8 _v)
794  {
795  WINPR_ASSERT(_s);
796  WINPR_ASSERT(_s->pointer);
797  WINPR_ASSERT(Stream_GetRemainingCapacity(_s) >= 1);
798  *_s->pointer++ = (_v);
799  }
800 
801  static INLINE void Stream_Write_INT16(wStream* _s, INT16 _v)
802  {
803  WINPR_ASSERT(_s);
804  WINPR_ASSERT(_s->pointer);
805  WINPR_ASSERT(Stream_GetRemainingCapacity(_s) >= 2);
806  *_s->pointer++ = (_v)&0xFF;
807  *_s->pointer++ = ((_v) >> 8) & 0xFF;
808  }
809 
810  static INLINE void Stream_Write_UINT16(wStream* _s, UINT16 _v)
811  {
812  WINPR_ASSERT(_s);
813  WINPR_ASSERT(_s->pointer);
814  WINPR_ASSERT(Stream_GetRemainingCapacity(_s) >= 2);
815  *_s->pointer++ = (_v)&0xFF;
816  *_s->pointer++ = ((_v) >> 8) & 0xFF;
817  }
818 
819  static INLINE void Stream_Write_UINT16_BE(wStream* _s, UINT16 _v)
820  {
821  WINPR_ASSERT(_s);
822  WINPR_ASSERT(_s->pointer);
823  WINPR_ASSERT(Stream_GetRemainingCapacity(_s) >= 2);
824  *_s->pointer++ = ((_v) >> 8) & 0xFF;
825  *_s->pointer++ = (_v)&0xFF;
826  }
827 
828  static INLINE void Stream_Write_UINT24_BE(wStream* _s, UINT32 _v)
829  {
830  WINPR_ASSERT(_s);
831  WINPR_ASSERT(_s->pointer);
832  WINPR_ASSERT(_v <= 0x00FFFFFF);
833  WINPR_ASSERT(Stream_GetRemainingCapacity(_s) >= 3);
834  *_s->pointer++ = ((_v) >> 16) & 0xFF;
835  *_s->pointer++ = ((_v) >> 8) & 0xFF;
836  *_s->pointer++ = (_v)&0xFF;
837  }
838 
839  static INLINE void Stream_Write_INT32(wStream* _s, INT32 _v)
840  {
841  WINPR_ASSERT(_s);
842  WINPR_ASSERT(_s->pointer);
843  WINPR_ASSERT(Stream_GetRemainingCapacity(_s) >= 4);
844  *_s->pointer++ = (_v)&0xFF;
845  *_s->pointer++ = ((_v) >> 8) & 0xFF;
846  *_s->pointer++ = ((_v) >> 16) & 0xFF;
847  *_s->pointer++ = ((_v) >> 24) & 0xFF;
848  }
849 
850  static INLINE void Stream_Write_UINT32(wStream* _s, UINT32 _v)
851  {
852  WINPR_ASSERT(_s);
853  WINPR_ASSERT(_s->pointer);
854  WINPR_ASSERT(Stream_GetRemainingCapacity(_s) >= 4);
855  *_s->pointer++ = (_v)&0xFF;
856  *_s->pointer++ = ((_v) >> 8) & 0xFF;
857  *_s->pointer++ = ((_v) >> 16) & 0xFF;
858  *_s->pointer++ = ((_v) >> 24) & 0xFF;
859  }
860 
861  static INLINE void Stream_Write_UINT32_BE(wStream* _s, UINT32 _v)
862  {
863  WINPR_ASSERT(Stream_GetRemainingCapacity(_s) >= 4);
864  Stream_Write_UINT16_BE(_s, ((_v) >> 16 & 0xFFFF));
865  Stream_Write_UINT16_BE(_s, ((_v)&0xFFFF));
866  }
867 
868  static INLINE void Stream_Write_UINT64(wStream* _s, UINT64 _v)
869  {
870  WINPR_ASSERT(_s);
871  WINPR_ASSERT(_s->pointer);
872  WINPR_ASSERT(Stream_GetRemainingCapacity(_s) >= 8);
873  Stream_Write_UINT32(_s, ((_v)&0xFFFFFFFFUL));
874  Stream_Write_UINT32(_s, ((_v) >> 16 & 0xFFFFFFFFUL));
875  }
876 
877  static INLINE void Stream_Write_UINT64_BE(wStream* _s, UINT64 _v)
878  {
879  WINPR_ASSERT(_s);
880  WINPR_ASSERT(_s->pointer);
881  WINPR_ASSERT(Stream_GetRemainingCapacity(_s) >= 8);
882  Stream_Write_UINT32_BE(_s, ((_v) >> 16 & 0xFFFFFFFFUL));
883  Stream_Write_UINT32_BE(_s, ((_v)&0xFFFFFFFFUL));
884  }
885 
886  static INLINE void Stream_Write(wStream* _s, const void* _b, size_t _n)
887  {
888  if (_n > 0)
889  {
890  WINPR_ASSERT(_s);
891  WINPR_ASSERT(_b);
892  WINPR_ASSERT(Stream_GetRemainingCapacity(_s) >= _n);
893  memcpy(_s->pointer, (_b), (_n));
894  Stream_Seek(_s, _n);
895  }
896  }
897 
898  static INLINE void Stream_Seek_UINT8(wStream* _s)
899  {
900  Stream_Seek(_s, sizeof(UINT8));
901  }
902  static INLINE void Stream_Seek_UINT16(wStream* _s)
903  {
904  Stream_Seek(_s, sizeof(UINT16));
905  }
906  static INLINE void Stream_Seek_UINT32(wStream* _s)
907  {
908  Stream_Seek(_s, sizeof(UINT32));
909  }
910  static INLINE void Stream_Seek_UINT64(wStream* _s)
911  {
912  Stream_Seek(_s, sizeof(UINT64));
913  }
914 
915  static INLINE void Stream_Rewind_UINT8(wStream* _s)
916  {
917  Stream_Rewind(_s, sizeof(UINT8));
918  }
919  static INLINE void Stream_Rewind_UINT16(wStream* _s)
920  {
921  Stream_Rewind(_s, sizeof(UINT16));
922  }
923  static INLINE void Stream_Rewind_UINT32(wStream* _s)
924  {
925  Stream_Rewind(_s, sizeof(UINT32));
926  }
927  static INLINE void Stream_Rewind_UINT64(wStream* _s)
928  {
929  Stream_Rewind(_s, sizeof(UINT64));
930  }
931 
932  static INLINE void Stream_Zero(wStream* _s, size_t _n)
933  {
934  WINPR_ASSERT(_s);
935  WINPR_ASSERT(Stream_GetRemainingCapacity(_s) >= (_n));
936  memset(_s->pointer, '\0', (_n));
937  Stream_Seek(_s, _n);
938  }
939 
940  static INLINE void Stream_Fill(wStream* _s, int _v, size_t _n)
941  {
942  WINPR_ASSERT(_s);
943  WINPR_ASSERT(Stream_GetRemainingCapacity(_s) >= (_n));
944  memset(_s->pointer, _v, (_n));
945  Stream_Seek(_s, _n);
946  }
947 
948  static INLINE void Stream_Copy(wStream* _src, wStream* _dst, size_t _n)
949  {
950  WINPR_ASSERT(_src);
951  WINPR_ASSERT(_dst);
952  WINPR_ASSERT(Stream_GetRemainingCapacity(_src) >= (_n));
953  WINPR_ASSERT(Stream_GetRemainingCapacity(_dst) >= (_n));
954 
955  memcpy(_dst->pointer, _src->pointer, _n);
956  Stream_Seek(_dst, _n);
957  Stream_Seek(_src, _n);
958  }
959 
964 #define Stream_BufferAs(s, type) WINPR_STREAM_CAST(type*, Stream_Buffer(s))
965 
966  static INLINE BYTE* Stream_Buffer(wStream* _s)
967  {
968  WINPR_ASSERT(_s);
969  return _s->buffer;
970  }
971 
976 #define Stream_ConstBufferAs(s, type) WINPR_STREAM_CAST(type*, Stream_ConstBuffer(s))
977  static INLINE const BYTE* Stream_ConstBuffer(const wStream* _s)
978  {
979  WINPR_ASSERT(_s);
980  return _s->buffer;
981  }
982 
983 #define Stream_GetBuffer(_s, _b) _b = Stream_Buffer(_s)
984 
989 #define Stream_GetBufferAs(_s, _b) _b = Stream_BufferAs(_s, typeof(_b))
990 
991 #define Stream_PointerAs(s, type) WINPR_STREAM_CAST(type*, Stream_Pointer(s))
992 
993  static INLINE void* Stream_Pointer(wStream* _s)
994  {
995  WINPR_ASSERT(_s);
996  return _s->pointer;
997  }
998 
999  static INLINE const void* Stream_ConstPointer(const wStream* _s)
1000  {
1001  WINPR_ASSERT(_s);
1002  return _s->pointer;
1003  }
1004 
1005 #define Stream_GetPointer(_s, _p) _p = Stream_Pointer(_s)
1006 
1011 #define Stream_GetPointerAs(_s, _p) _p = Stream_PointerAs(_s, typeof(_p))
1012 
1013 #if defined(WITH_WINPR_DEPRECATED)
1014  WINPR_API WINPR_DEPRECATED_VAR("Use Stream_SetPosition instead",
1015  BOOL Stream_SetPointer(wStream* _s, BYTE* _p));
1016  WINPR_API WINPR_DEPRECATED_VAR("Use Stream_New(buffer, capacity) instead",
1017  BOOL Stream_SetBuffer(wStream* _s, BYTE* _b));
1018  WINPR_API WINPR_DEPRECATED_VAR("Use Stream_New(buffer, capacity) instead",
1019  void Stream_SetCapacity(wStream* _s, size_t capacity));
1020 #endif
1021 
1022  static INLINE size_t Stream_Length(const wStream* _s)
1023  {
1024  WINPR_ASSERT(_s);
1025  return _s->length;
1026  }
1027 
1028 #define Stream_GetLength(_s, _l) _l = Stream_Length(_s)
1029  WINPR_API BOOL Stream_SetLength(wStream* _s, size_t _l);
1030 
1031  static INLINE size_t Stream_Capacity(const wStream* _s)
1032  {
1033  WINPR_ASSERT(_s);
1034  return _s->capacity;
1035  }
1036 
1037 #define Stream_GetCapacity(_s, _c) _c = Stream_Capacity(_s);
1038 
1039  static INLINE size_t Stream_GetPosition(const wStream* _s)
1040  {
1041  WINPR_ASSERT(_s);
1042  WINPR_ASSERT(_s->buffer <= _s->pointer);
1043  return WINPR_STREAM_CAST(size_t, (_s->pointer - _s->buffer));
1044  }
1045 
1046  WINPR_API BOOL Stream_SetPosition(wStream* _s, size_t _p);
1047 
1048  WINPR_API void Stream_SealLength(wStream* _s);
1049 
1050  static INLINE void Stream_Clear(wStream* _s)
1051  {
1052  WINPR_ASSERT(_s);
1053  memset(_s->buffer, 0, _s->capacity);
1054  }
1055 
1056 #define Stream_SafeSeek(s, size) Stream_SafeSeekEx(s, size, __FILE__, __LINE__, __func__)
1057  WINPR_API BOOL Stream_SafeSeekEx(wStream* s, size_t size, const char* file, size_t line,
1058  const char* fkt);
1059 
1060  WINPR_API BOOL Stream_Read_UTF16_String(wStream* s, WCHAR* dst, size_t charLength);
1061  WINPR_API BOOL Stream_Write_UTF16_String(wStream* s, const WCHAR* src, size_t charLength);
1062 
1072  WINPR_API char* Stream_Read_UTF16_String_As_UTF8(wStream* s, size_t wcharLength,
1073  size_t* pUtfCharLength);
1074 
1084  WINPR_API SSIZE_T Stream_Read_UTF16_String_As_UTF8_Buffer(wStream* s, size_t wcharLength,
1085  char* utfBuffer,
1086  size_t utfBufferCharLength);
1087 
1099  WINPR_API SSIZE_T Stream_Write_UTF16_String_From_UTF8(wStream* s, size_t wcharLength,
1100  const char* src, size_t length,
1101  BOOL fill);
1102 
1103  /* StreamPool */
1104 
1105  WINPR_API void StreamPool_Return(wStreamPool* pool, wStream* s);
1106 
1107  WINPR_API wStream* StreamPool_Take(wStreamPool* pool, size_t size);
1108 
1109  WINPR_API void Stream_AddRef(wStream* s);
1110  WINPR_API void Stream_Release(wStream* s);
1111 
1112  WINPR_API wStream* StreamPool_Find(wStreamPool* pool, BYTE* ptr);
1113 
1114  WINPR_API void StreamPool_Clear(wStreamPool* pool);
1115 
1116  WINPR_API void StreamPool_Free(wStreamPool* pool);
1117 
1118  WINPR_ATTR_MALLOC(StreamPool_Free, 1)
1119  WINPR_API wStreamPool* StreamPool_New(BOOL synchronized, size_t defaultSize);
1120 
1121  WINPR_API char* StreamPool_GetStatistics(wStreamPool* pool, char* buffer, size_t size);
1122 
1123 #ifdef __cplusplus
1124 }
1125 #endif
1126 
1127 #endif /* WINPR_UTILS_STREAM_H */