summaryrefslogtreecommitdiffstats
path: root/include/freerdp/utils/ringbuffer.h
blob: 3de191c81bb479ed612e6b57ceee0736d22b578e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
/**
 * FreeRDP: A Remote Desktop Protocol Implementation
 *
 * Copyright 2014 Thincast Technologies GmbH
 * Copyright 2014 Hardening <contact@hardening-consulting.com>
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef FREERDP_UTILS_RINGBUFFER_H
#define FREERDP_UTILS_RINGBUFFER_H

#include <winpr/wtypes.h>
#include <freerdp/api.h>

#ifdef __cplusplus
extern "C"
{
#endif

	/** @brief ring buffer meta data */
	typedef struct
	{
		size_t initialSize;
		size_t freeSize;
		size_t size;
		size_t readPtr;
		size_t writePtr;
		BYTE* buffer;
	} RingBuffer;

	/** @brief a piece of data in the ring buffer, exactly like a glibc iovec */
	typedef struct
	{
		size_t size;
		const BYTE* data;
	} DataChunk;

	/**
	 * initialise a ringbuffer
	 *
	 * @param initialSize the initial capacity of the ringBuffer
	 * @return if the initialisation was successful
	 */
	FREERDP_API BOOL ringbuffer_init(RingBuffer* rb, size_t initialSize);

	/**
	 * destroys internal data used by this ringbuffer
	 *
	 * @param ringbuffer A pointer to the ringbuffer
	 */
	FREERDP_API void ringbuffer_destroy(RingBuffer* ringbuffer);

	/**
	 * computes the space used in this ringbuffer
	 *
	 * @param ringbuffer A pointer to the ringbuffer
	 * @return the number of bytes stored in that ringbuffer
	 */
	FREERDP_API size_t ringbuffer_used(const RingBuffer* ringbuffer);

	/** returns the capacity of the ring buffer
	 *
	 * @param ringbuffer A pointer to the ringbuffer
	 * @return the capacity of this ring buffer
	 */
	FREERDP_API size_t ringbuffer_capacity(const RingBuffer* ringbuffer);

	/** writes some bytes in the ringbuffer, if the data doesn't fit, the ringbuffer
	 * is resized automatically
	 *
	 * @param rb the ringbuffer
	 * @param ptr a pointer on the data to add
	 * @param sz the size of the data to add
	 * @return if the operation was successful, it could fail in case of OOM during realloc()
	 */
	FREERDP_API BOOL ringbuffer_write(RingBuffer* rb, const BYTE* ptr, size_t sz);

	/** ensures that we have sz bytes available at the write head, and return a pointer
	 * on the write head
	 *
	 * @param rb the ring buffer
	 * @param sz the size to ensure
	 * @return a pointer on the write head, or NULL in case of OOM
	 */
	FREERDP_API BYTE* ringbuffer_ensure_linear_write(RingBuffer* rb, size_t sz);

	/** move ahead the write head in case some byte were written directly by using
	 * a pointer retrieved via ringbuffer_ensure_linear_write(). This function is
	 * used to commit the written bytes. The provided size should not exceed the
	 * size ensured by ringbuffer_ensure_linear_write()
	 *
	 * @param rb the ring buffer
	 * @param sz the number of bytes that have been written
	 * @return if the operation was successful, FALSE is sz is too big
	 */
	FREERDP_API BOOL ringbuffer_commit_written_bytes(RingBuffer* rb, size_t sz);

	/** peeks the buffer chunks for sz bytes and returns how many chunks are filled.
	 * Note that the sum of the resulting chunks may be smaller than sz.
	 *
	 * @param rb the ringbuffer
	 * @param chunks an array of data chunks that will contain data / size of chunks
	 * @param sz the requested size
	 * @return the number of chunks used for reading sz bytes
	 */
	FREERDP_API int ringbuffer_peek(const RingBuffer* rb, DataChunk chunks[2], size_t sz);

	/** move ahead the read head in case some byte were read using ringbuffer_peek()
	 * This function is used to commit the bytes that were effectively consumed.
	 *
	 * @param rb the ring buffer
	 * @param sz the number of bytes to read
	 */
	FREERDP_API void ringbuffer_commit_read_bytes(RingBuffer* rb, size_t sz);

#ifdef __cplusplus
}
#endif

#endif /* FREERDP_UTILS_RINGBUFFER_H */