cscg24-guacamole

CSCG 2024 Challenge 'Guacamole Mashup'
git clone https://git.sinitax.com/sinitax/cscg24-guacamole
Log | Files | Refs | sfeed.txt

stream.h (15713B)


      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
     33extern "C"
     34{
     35#endif
     36
     37	typedef struct _wStreamPool wStreamPool;
     38
     39	struct _wStream
     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	};
     51	typedef struct _wStream wStream;
     52
     53	WINPR_API BOOL Stream_EnsureCapacity(wStream* s, size_t size);
     54	WINPR_API BOOL Stream_EnsureRemainingCapacity(wStream* s, size_t size);
     55
     56	WINPR_API wStream* Stream_New(BYTE* buffer, size_t size);
     57	WINPR_API void Stream_StaticInit(wStream* s, BYTE* buffer, size_t size);
     58	WINPR_API void Stream_Free(wStream* s, BOOL bFreeBuffer);
     59
     60#define Stream_CheckAndLogRequiredLength(tag, s, len)                                     \
     61	Stream_CheckAndLogRequiredLengthEx(tag, WLOG_WARN, s, len, "%s(%s:%d)", __FUNCTION__, \
     62	                                   __FILE__, __LINE__)
     63	WINPR_API BOOL Stream_CheckAndLogRequiredLengthEx(const char* tag, DWORD level, wStream* s,
     64	                                                  UINT64 len, const char* fmt, ...);
     65	WINPR_API BOOL Stream_CheckAndLogRequiredLengthExVa(const char* tag, DWORD level, wStream* s,
     66	                                                    UINT64 len, const char* fmt, va_list args);
     67	WINPR_API BOOL Stream_CheckAndLogRequiredLengthWLogEx(wLog* log, DWORD level, wStream* s,
     68	                                                      UINT64 len, const char* fmt, ...);
     69	WINPR_API BOOL Stream_CheckAndLogRequiredLengthWLogExVa(wLog* log, DWORD level, wStream* s,
     70	                                                        UINT64 len, const char* fmt,
     71	                                                        va_list args);
     72
     73	static INLINE void Stream_Seek(wStream* s, size_t _offset)
     74	{
     75		s->pointer += (_offset);
     76	}
     77
     78	static INLINE void Stream_Rewind(wStream* s, size_t _offset)
     79	{
     80		s->pointer -= (_offset);
     81	}
     82
     83#define _stream_read_n8(_t, _s, _v, _p)  \
     84	do                                   \
     85	{                                    \
     86		(_v) = (_t)(*(_s)->pointer);     \
     87		if (_p)                          \
     88			Stream_Seek(_s, sizeof(_t)); \
     89	} while (0)
     90
     91#define _stream_read_n16_le(_t, _s, _v, _p)                                      \
     92	do                                                                           \
     93	{                                                                            \
     94		(_v) = (_t)((*(_s)->pointer) + (((UINT16)(*((_s)->pointer + 1))) << 8)); \
     95		if (_p)                                                                  \
     96			Stream_Seek(_s, sizeof(_t));                                         \
     97	} while (0)
     98
     99#define _stream_read_n16_be(_t, _s, _v, _p)                                              \
    100	do                                                                                   \
    101	{                                                                                    \
    102		(_v) = (_t)((((UINT16)(*(_s)->pointer)) << 8) + (UINT16)(*((_s)->pointer + 1))); \
    103		if (_p)                                                                          \
    104			Stream_Seek(_s, sizeof(_t));                                                 \
    105	} while (0)
    106
    107#define _stream_read_n32_le(_t, _s, _v, _p)                                              \
    108	do                                                                                   \
    109	{                                                                                    \
    110		(_v) = (_t)((UINT32)(*(_s)->pointer) + (((UINT32)(*((_s)->pointer + 1))) << 8) + \
    111		            (((UINT32)(*((_s)->pointer + 2))) << 16) +                           \
    112		            ((((UINT32) * ((_s)->pointer + 3))) << 24));                         \
    113		if (_p)                                                                          \
    114			Stream_Seek(_s, sizeof(_t));                                                 \
    115	} while (0)
    116
    117#define _stream_read_n32_be(_t, _s, _v, _p)                                                        \
    118	do                                                                                             \
    119	{                                                                                              \
    120		(_v) = (_t)(((((UINT32) * ((_s)->pointer))) << 24) +                                       \
    121		            (((UINT32)(*((_s)->pointer + 1))) << 16) +                                     \
    122		            (((UINT32)(*((_s)->pointer + 2))) << 8) + (((UINT32)(*((_s)->pointer + 3))))); \
    123		if (_p)                                                                                    \
    124			Stream_Seek(_s, sizeof(_t));                                                           \
    125	} while (0)
    126
    127#define _stream_read_n64_le(_t, _s, _v, _p)                                                       \
    128	do                                                                                            \
    129	{                                                                                             \
    130		(_v) = (_t)(                                                                              \
    131		    (UINT64)(*(_s)->pointer) + (((UINT64)(*((_s)->pointer + 1))) << 8) +                  \
    132		    (((UINT64)(*((_s)->pointer + 2))) << 16) + (((UINT64)(*((_s)->pointer + 3))) << 24) + \
    133		    (((UINT64)(*((_s)->pointer + 4))) << 32) + (((UINT64)(*((_s)->pointer + 5))) << 40) + \
    134		    (((UINT64)(*((_s)->pointer + 6))) << 48) + (((UINT64)(*((_s)->pointer + 7))) << 56)); \
    135		if (_p)                                                                                   \
    136			Stream_Seek(_s, sizeof(_t));                                                          \
    137	} while (0)
    138
    139#define _stream_read_n64_be(_t, _s, _v, _p)                                                       \
    140	do                                                                                            \
    141	{                                                                                             \
    142		(_v) = (_t)(                                                                              \
    143		    (((UINT64)(*((_s)->pointer))) << 56) + (((UINT64)(*((_s)->pointer + 1))) << 48) +     \
    144		    (((UINT64)(*((_s)->pointer + 2))) << 40) + (((UINT64)(*((_s)->pointer + 3))) << 32) + \
    145		    (((UINT64)(*((_s)->pointer + 4))) << 24) + (((UINT64)(*((_s)->pointer + 5))) << 16) + \
    146		    (((UINT64)(*((_s)->pointer + 6))) << 8) + (((UINT64)(*((_s)->pointer + 7)))));        \
    147		if (_p)                                                                                   \
    148			Stream_Seek(_s, sizeof(_t));                                                          \
    149	} while (0)
    150
    151#define Stream_Read_UINT8(_s, _v) _stream_read_n8(UINT8, _s, _v, TRUE)
    152#define Stream_Read_INT8(_s, _v) _stream_read_n8(INT8, _s, _v, TRUE)
    153
    154#define Stream_Read_UINT16(_s, _v) _stream_read_n16_le(UINT16, _s, _v, TRUE)
    155#define Stream_Read_INT16(_s, _v) _stream_read_n16_le(INT16, _s, _v, TRUE)
    156
    157#define Stream_Read_UINT16_BE(_s, _v) _stream_read_n16_be(UINT16, _s, _v, TRUE)
    158#define Stream_Read_INT16_BE(_s, _v) _stream_read_n16_be(INT16, _s, _v, TRUE)
    159
    160#define Stream_Read_UINT32(_s, _v) _stream_read_n32_le(UINT32, _s, _v, TRUE)
    161#define Stream_Read_INT32(_s, _v) _stream_read_n32_le(INT32, _s, _v, TRUE)
    162
    163#define Stream_Read_UINT32_BE(_s, _v) _stream_read_n32_be(UINT32, _s, _v, TRUE)
    164#define Stream_Read_INT32_BE(_s, _v) _stream_read_n32_be(INT32, _s, _v, TRUE)
    165
    166#define Stream_Read_UINT64(_s, _v) _stream_read_n64_le(UINT64, _s, _v, TRUE)
    167#define Stream_Read_INT64(_s, _v) _stream_read_n64_le(INT64, _s, _v, TRUE)
    168
    169#define Stream_Read_UINT64_BE(_s, _v) _stream_read_n64_be(UINT64, _s, _v, TRUE)
    170#define Stream_Read_INT64_BE(_s, _v) _stream_read_n64_be(INT64, _s, _v, TRUE)
    171
    172	static INLINE void Stream_Read(wStream* _s, void* _b, size_t _n)
    173	{
    174		memcpy(_b, (_s->pointer), (_n));
    175		Stream_Seek(_s, _n);
    176	}
    177
    178#define Stream_Peek_UINT8(_s, _v) _stream_read_n8(UINT8, _s, _v, FALSE)
    179#define Stream_Peek_INT8(_s, _v) _stream_read_n8(INT8, _s, _v, FALSE)
    180
    181#define Stream_Peek_UINT16(_s, _v) _stream_read_n16_le(UINT16, _s, _v, FALSE)
    182#define Stream_Peek_INT16(_s, _v) _stream_read_n16_le(INT16, _s, _v, FALSE)
    183
    184#define Stream_Peek_UINT16_BE(_s, _v) _stream_read_n16_be(UINT16, _s, _v, FALSE)
    185#define Stream_Peek_INT16_BE(_s, _v) _stream_read_n16_be(INT16, _s, _v, FALSE)
    186
    187#define Stream_Peek_UINT32(_s, _v) _stream_read_n32_le(UINT32, _s, _v, FALSE)
    188#define Stream_Peek_INT32(_s, _v) _stream_read_n32_le(INT32, _s, _v, FALSE)
    189
    190#define Stream_Peek_UINT32_BE(_s, _v) _stream_read_n32_be(UINT32, _s, _v, FALSE)
    191#define Stream_Peek_INT32_BE(_s, _v) _stream_read_n32_be(INT32, _s, _v, FALSE)
    192
    193#define Stream_Peek_UINT64(_s, _v) _stream_read_n64_le(UINT64, _s, _v, FALSE)
    194#define Stream_Peek_INT64(_s, _v) _stream_read_n64_le(INT64, _s, _v, FALSE)
    195
    196#define Stream_Peek_UINT64_BE(_s, _v) _stream_read_n64_be(UINT64, _s, _v, FALSE)
    197#define Stream_Peek_INT64_BE(_s, _v) _stream_read_n64_be(INT64, _s, _v, FALSE)
    198
    199	static INLINE void Stream_Peek(wStream* _s, void* _b, size_t _n)
    200	{
    201		memcpy(_b, (_s->pointer), (_n));
    202	}
    203
    204	static INLINE void Stream_Write_UINT8(wStream* _s, UINT8 _v)
    205	{
    206		*_s->pointer++ = (UINT8)(_v);
    207	}
    208
    209	static INLINE void Stream_Write_INT16(wStream* _s, INT16 _v)
    210	{
    211		*_s->pointer++ = (_v)&0xFF;
    212		*_s->pointer++ = ((_v) >> 8) & 0xFF;
    213	}
    214
    215	static INLINE void Stream_Write_UINT16(wStream* _s, UINT16 _v)
    216	{
    217		*_s->pointer++ = (_v)&0xFF;
    218		*_s->pointer++ = ((_v) >> 8) & 0xFF;
    219	}
    220
    221	static INLINE void Stream_Write_UINT16_BE(wStream* _s, UINT16 _v)
    222	{
    223		*_s->pointer++ = ((_v) >> 8) & 0xFF;
    224		*_s->pointer++ = (_v)&0xFF;
    225	}
    226
    227	static INLINE void Stream_Write_INT32(wStream* _s, INT32 _v)
    228	{
    229		*_s->pointer++ = (_v)&0xFF;
    230		*_s->pointer++ = ((_v) >> 8) & 0xFF;
    231		*_s->pointer++ = ((_v) >> 16) & 0xFF;
    232		*_s->pointer++ = ((_v) >> 24) & 0xFF;
    233	}
    234
    235	static INLINE void Stream_Write_UINT32(wStream* _s, UINT32 _v)
    236	{
    237		*_s->pointer++ = (_v)&0xFF;
    238		*_s->pointer++ = ((_v) >> 8) & 0xFF;
    239		*_s->pointer++ = ((_v) >> 16) & 0xFF;
    240		*_s->pointer++ = ((_v) >> 24) & 0xFF;
    241	}
    242
    243	static INLINE void Stream_Write_UINT32_BE(wStream* _s, UINT32 _v)
    244	{
    245		Stream_Write_UINT16_BE(_s, ((_v) >> 16 & 0xFFFF));
    246		Stream_Write_UINT16_BE(_s, ((_v)&0xFFFF));
    247	}
    248
    249	static INLINE void Stream_Write_UINT64(wStream* _s, UINT64 _v)
    250	{
    251		*_s->pointer++ = (UINT64)(_v)&0xFF;
    252		*_s->pointer++ = ((UINT64)(_v) >> 8) & 0xFF;
    253		*_s->pointer++ = ((UINT64)(_v) >> 16) & 0xFF;
    254		*_s->pointer++ = ((UINT64)(_v) >> 24) & 0xFF;
    255		*_s->pointer++ = ((UINT64)(_v) >> 32) & 0xFF;
    256		*_s->pointer++ = ((UINT64)(_v) >> 40) & 0xFF;
    257		*_s->pointer++ = ((UINT64)(_v) >> 48) & 0xFF;
    258		*_s->pointer++ = ((UINT64)(_v) >> 56) & 0xFF;
    259	}
    260	static INLINE void Stream_Write(wStream* _s, const void* _b, size_t _n)
    261	{
    262		if (_n > 0)
    263		{
    264			memcpy(_s->pointer, (_b), (_n));
    265			Stream_Seek(_s, _n);
    266		}
    267	}
    268
    269#define Stream_Seek_UINT8(_s) Stream_Seek(_s, 1)
    270#define Stream_Seek_UINT16(_s) Stream_Seek(_s, 2)
    271#define Stream_Seek_UINT32(_s) Stream_Seek(_s, 4)
    272#define Stream_Seek_UINT64(_s) Stream_Seek(_s, 8)
    273
    274#define Stream_Rewind_UINT8(_s) Stream_Rewind(_s, 1)
    275#define Stream_Rewind_UINT16(_s) Stream_Rewind(_s, 2)
    276#define Stream_Rewind_UINT32(_s) Stream_Rewind(_s, 4)
    277#define Stream_Rewind_UINT64(_s) Stream_Rewind(_s, 8)
    278
    279	static INLINE void Stream_Zero(wStream* _s, size_t _n)
    280	{
    281		memset(_s->pointer, '\0', (_n));
    282		Stream_Seek(_s, _n);
    283	}
    284
    285	static INLINE void Stream_Fill(wStream* _s, int _v, size_t _n)
    286	{
    287		memset(_s->pointer, _v, (_n));
    288		Stream_Seek(_s, _n);
    289	}
    290
    291	static INLINE void Stream_Copy(wStream* _src, wStream* _dst, size_t _n)
    292	{
    293		memcpy(_dst->pointer, _src->pointer, _n);
    294		Stream_Seek(_dst, _n);
    295		Stream_Seek(_src, _n);
    296	}
    297
    298	static INLINE BYTE* Stream_Buffer(wStream* _s)
    299	{
    300		return _s->buffer;
    301	}
    302
    303#define Stream_GetBuffer(_s, _b) _b = Stream_Buffer(_s)
    304	static INLINE void Stream_SetBuffer(wStream* _s, BYTE* _b)
    305	{
    306		_s->buffer = _b;
    307	}
    308
    309	static INLINE BYTE* Stream_Pointer(wStream* _s)
    310	{
    311		return _s->pointer;
    312	}
    313
    314#define Stream_GetPointer(_s, _p) _p = Stream_Pointer(_s)
    315	static INLINE void Stream_SetPointer(wStream* _s, BYTE* _p)
    316	{
    317		_s->pointer = _p;
    318	}
    319
    320	static INLINE size_t Stream_Length(wStream* _s)
    321	{
    322		return _s->length;
    323	}
    324
    325#define Stream_GetLength(_s, _l) _l = Stream_Length(_s)
    326	static INLINE void Stream_SetLength(wStream* _s, size_t _l)
    327	{
    328		_s->length = _l;
    329	}
    330
    331	static INLINE size_t Stream_Capacity(wStream* _s)
    332	{
    333		return _s->capacity;
    334	}
    335
    336#define Stream_GetCapacity(_s, _c) _c = Stream_Capacity(_s);
    337	static INLINE void Stream_SetCapacity(wStream* _s, size_t _c)
    338	{
    339		_s->capacity = _c;
    340	}
    341
    342	static INLINE size_t Stream_GetPosition(wStream* _s)
    343	{
    344		return (_s->pointer - _s->buffer);
    345	}
    346
    347	static INLINE void Stream_SetPosition(wStream* _s, size_t _p)
    348	{
    349		_s->pointer = _s->buffer + (_p);
    350	}
    351
    352	static INLINE void Stream_SealLength(wStream* _s)
    353	{
    354		_s->length = (_s->pointer - _s->buffer);
    355	}
    356
    357	static INLINE size_t Stream_GetRemainingCapacity(wStream* _s)
    358	{
    359		return (_s->capacity - (_s->pointer - _s->buffer));
    360	}
    361
    362	static INLINE size_t Stream_GetRemainingLength(wStream* _s)
    363	{
    364		return (_s->length - (_s->pointer - _s->buffer));
    365	}
    366
    367	static INLINE void Stream_Clear(wStream* _s)
    368	{
    369		memset(_s->buffer, 0, _s->capacity);
    370	}
    371
    372	static INLINE BOOL Stream_SafeSeek(wStream* s, size_t size)
    373	{
    374		if (Stream_GetRemainingLength(s) < size)
    375			return FALSE;
    376
    377		Stream_Seek(s, size);
    378		return TRUE;
    379	}
    380
    381	static INLINE BOOL Stream_Read_UTF16_String(wStream* s, WCHAR* dst, size_t length)
    382	{
    383		size_t x;
    384
    385		if (!s || !dst)
    386			return FALSE;
    387
    388		if (Stream_GetRemainingLength(s) / sizeof(WCHAR) < length)
    389			return FALSE;
    390
    391		for (x = 0; x < length; x++)
    392			Stream_Read_UINT16(s, dst[x]);
    393
    394		return TRUE;
    395	}
    396
    397	static INLINE BOOL Stream_Write_UTF16_String(wStream* s, const WCHAR* src, size_t length)
    398	{
    399		size_t x;
    400
    401		if (!s || !src)
    402			return FALSE;
    403
    404		if (Stream_GetRemainingCapacity(s) / sizeof(WCHAR) < length)
    405			return FALSE;
    406
    407		for (x = 0; x < length; x++)
    408			Stream_Write_UINT16(s, src[x]);
    409
    410		return TRUE;
    411	}
    412
    413	/* StreamPool */
    414
    415	struct _wStreamPool
    416	{
    417		int aSize;
    418		int aCapacity;
    419		wStream** aArray;
    420
    421		int uSize;
    422		int uCapacity;
    423		wStream** uArray;
    424
    425		CRITICAL_SECTION lock;
    426		BOOL synchronized;
    427		size_t defaultSize;
    428	};
    429
    430	WINPR_API wStream* StreamPool_Take(wStreamPool* pool, size_t size);
    431	WINPR_API void StreamPool_Return(wStreamPool* pool, wStream* s);
    432
    433	WINPR_API void Stream_AddRef(wStream* s);
    434	WINPR_API void Stream_Release(wStream* s);
    435
    436	WINPR_API wStream* StreamPool_Find(wStreamPool* pool, BYTE* ptr);
    437	WINPR_API void StreamPool_AddRef(wStreamPool* pool, BYTE* ptr);
    438	WINPR_API void StreamPool_Release(wStreamPool* pool, BYTE* ptr);
    439
    440	WINPR_API void StreamPool_Clear(wStreamPool* pool);
    441
    442	WINPR_API wStreamPool* StreamPool_New(BOOL synchronized, size_t defaultSize);
    443	WINPR_API void StreamPool_Free(wStreamPool* pool);
    444
    445#ifdef __cplusplus
    446}
    447#endif
    448
    449#endif /* WINPR_UTILS_STREAM_H */