]> git.sur5r.net Git - freertos/blob - FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOS_Stream_Buffer.h
Update to MIT licensed FreeRTOS V10.0.0 - see https://www.freertos.org/History.txt
[freertos] / FreeRTOS-Plus / Source / FreeRTOS-Plus-TCP / include / FreeRTOS_Stream_Buffer.h
1 /*\r
2  * FreeRTOS+TCP V2.0.0\r
3  * Copyright (C) 2017 Amazon.com, Inc. or its affiliates.  All Rights Reserved.\r
4  *\r
5  * Permission is hereby granted, free of charge, to any person obtaining a copy of\r
6  * this software and associated documentation files (the "Software"), to deal in\r
7  * the Software without restriction, including without limitation the rights to\r
8  * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of\r
9  * the Software, and to permit persons to whom the Software is furnished to do so,\r
10  * subject to the following conditions:\r
11  *\r
12  * The above copyright notice and this permission notice shall be included in all\r
13  * copies or substantial portions of the Software. If you wish to use our Amazon\r
14  * FreeRTOS name, please do so in a fair use way that does not cause confusion.\r
15  *\r
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS\r
18  * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR\r
19  * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER\r
20  * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
21  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r
22  *\r
23  * http://www.FreeRTOS.org\r
24  * http://aws.amazon.com/freertos\r
25  *\r
26  * 1 tab == 4 spaces!\r
27  */\r
28 \r
29 /*\r
30  *      FreeRTOS_Stream_Buffer.h\r
31  *\r
32  *      A cicular character buffer\r
33  *      An implementation of a circular buffer without a length field\r
34  *      If LENGTH defines the size of the buffer, a maximum of (LENGT-1) bytes can be stored\r
35  *      In order to add or read data from the buffer, memcpy() will be called at most 2 times\r
36  */\r
37 \r
38 #ifndef FREERTOS_STREAM_BUFFER_H\r
39 #define FREERTOS_STREAM_BUFFER_H\r
40 \r
41 #ifdef __cplusplus\r
42 extern "C" {\r
43 #endif\r
44 \r
45 typedef struct xSTREAM_BUFFER {\r
46         volatile size_t uxTail;         /* next item to read */\r
47         volatile size_t uxMid;          /* iterator within the valid items */\r
48         volatile size_t uxHead;         /* next position store a new item */\r
49         volatile size_t uxFront;        /* iterator within the free space */\r
50         size_t LENGTH;                          /* const value: number of reserved elements */\r
51         uint8_t ucArray[ sizeof( size_t ) ];\r
52 } StreamBuffer_t;\r
53 \r
54 static portINLINE void vStreamBufferClear( StreamBuffer_t *pxBuffer );\r
55 static portINLINE void vStreamBufferClear( StreamBuffer_t *pxBuffer )\r
56 {\r
57         /* Make the circular buffer empty */\r
58         pxBuffer->uxHead = 0u;\r
59         pxBuffer->uxTail = 0u;\r
60         pxBuffer->uxFront = 0u;\r
61         pxBuffer->uxMid = 0u;\r
62 }\r
63 /*-----------------------------------------------------------*/\r
64 \r
65 static portINLINE size_t uxStreamBufferSpace( const StreamBuffer_t *pxBuffer, const size_t uxLower, const size_t uxUpper );\r
66 static portINLINE size_t uxStreamBufferSpace( const StreamBuffer_t *pxBuffer, const size_t uxLower, const size_t uxUpper )\r
67 {\r
68 /* Returns the space between uxLower and uxUpper, which equals to the distance minus 1 */\r
69 size_t uxCount;\r
70 \r
71         uxCount = pxBuffer->LENGTH + uxUpper - uxLower - 1u;\r
72         if( uxCount >= pxBuffer->LENGTH )\r
73         {\r
74                 uxCount -= pxBuffer->LENGTH;\r
75         }\r
76 \r
77         return uxCount;\r
78 }\r
79 /*-----------------------------------------------------------*/\r
80 \r
81 static portINLINE size_t uxStreamBufferDistance( const StreamBuffer_t *pxBuffer, const size_t uxLower, const size_t uxUpper );\r
82 static portINLINE size_t uxStreamBufferDistance( const StreamBuffer_t *pxBuffer, const size_t uxLower, const size_t uxUpper )\r
83 {\r
84 /* Returns the distance between uxLower and uxUpper */\r
85 size_t uxCount;\r
86 \r
87         uxCount = pxBuffer->LENGTH + uxUpper - uxLower;\r
88         if ( uxCount >= pxBuffer->LENGTH )\r
89         {\r
90                 uxCount -= pxBuffer->LENGTH;\r
91         }\r
92 \r
93         return uxCount;\r
94 }\r
95 /*-----------------------------------------------------------*/\r
96 \r
97 static portINLINE size_t uxStreamBufferGetSpace( const StreamBuffer_t *pxBuffer );\r
98 static portINLINE size_t uxStreamBufferGetSpace( const StreamBuffer_t *pxBuffer )\r
99 {\r
100 /* Returns the number of items which can still be added to uxHead\r
101 before hitting on uxTail */\r
102 size_t uxHead = pxBuffer->uxHead;\r
103 size_t uxTail = pxBuffer->uxTail;\r
104 \r
105         return uxStreamBufferSpace( pxBuffer, uxHead, uxTail );\r
106 }\r
107 /*-----------------------------------------------------------*/\r
108 \r
109 static portINLINE size_t uxStreamBufferFrontSpace( const StreamBuffer_t *pxBuffer );\r
110 static portINLINE size_t uxStreamBufferFrontSpace( const StreamBuffer_t *pxBuffer )\r
111 {\r
112 /* Distance between uxFront and uxTail\r
113 or the number of items which can still be added to uxFront,\r
114 before hitting on uxTail */\r
115 \r
116 size_t uxFront = pxBuffer->uxFront;\r
117 size_t uxTail = pxBuffer->uxTail;\r
118 \r
119         return uxStreamBufferSpace( pxBuffer, uxFront, uxTail );\r
120 }\r
121 /*-----------------------------------------------------------*/\r
122 \r
123 static portINLINE size_t uxStreamBufferGetSize( const StreamBuffer_t *pxBuffer );\r
124 static portINLINE size_t uxStreamBufferGetSize( const StreamBuffer_t *pxBuffer )\r
125 {\r
126 /* Returns the number of items which can be read from uxTail\r
127 before reaching uxHead */\r
128 size_t uxHead = pxBuffer->uxHead;\r
129 size_t uxTail = pxBuffer->uxTail;\r
130 \r
131         return uxStreamBufferDistance( pxBuffer, uxTail, uxHead );\r
132 }\r
133 /*-----------------------------------------------------------*/\r
134 \r
135 static portINLINE size_t uxStreamBufferMidSpace( const StreamBuffer_t *pxBuffer );\r
136 static portINLINE size_t uxStreamBufferMidSpace( const StreamBuffer_t *pxBuffer )\r
137 {\r
138 /* Returns the distance between uxHead and uxMid */\r
139 size_t uxHead = pxBuffer->uxHead;\r
140 size_t uxMid = pxBuffer->uxMid;\r
141 \r
142         return uxStreamBufferDistance( pxBuffer, uxMid, uxHead );\r
143 }\r
144 /*-----------------------------------------------------------*/\r
145 \r
146 static portINLINE void vStreamBufferMoveMid( StreamBuffer_t *pxBuffer, size_t uxCount );\r
147 static portINLINE void vStreamBufferMoveMid( StreamBuffer_t *pxBuffer, size_t uxCount )\r
148 {\r
149 /* Increment uxMid, but no further than uxHead */\r
150 size_t uxSize = uxStreamBufferMidSpace( pxBuffer );\r
151 \r
152         if( uxCount > uxSize )\r
153         {\r
154                 uxCount = uxSize;\r
155         }\r
156         pxBuffer->uxMid += uxCount;\r
157         if( pxBuffer->uxMid >= pxBuffer->LENGTH )\r
158         {\r
159                 pxBuffer->uxMid -= pxBuffer->LENGTH;\r
160         }\r
161 }\r
162 /*-----------------------------------------------------------*/\r
163 static portINLINE BaseType_t xStreamBufferIsEmpty( const StreamBuffer_t *pxBuffer );\r
164 static portINLINE BaseType_t xStreamBufferIsEmpty( const StreamBuffer_t *pxBuffer )\r
165 {\r
166 BaseType_t xReturn;\r
167 \r
168         /* True if no item is available */\r
169         if( pxBuffer->uxHead == pxBuffer->uxTail )\r
170         {\r
171                 xReturn = pdTRUE;\r
172         }\r
173         else\r
174         {\r
175                 xReturn = pdFALSE;\r
176         }\r
177         return xReturn;\r
178 }\r
179 /*-----------------------------------------------------------*/\r
180 \r
181 static portINLINE BaseType_t xStreamBufferIsFull( const StreamBuffer_t *pxBuffer );\r
182 static portINLINE BaseType_t xStreamBufferIsFull( const StreamBuffer_t *pxBuffer )\r
183 {\r
184         /* True if the available space equals zero. */\r
185         return ( BaseType_t ) ( uxStreamBufferGetSpace( pxBuffer ) == 0u );\r
186 }\r
187 /*-----------------------------------------------------------*/\r
188 \r
189 static portINLINE BaseType_t xStreamBufferLessThenEqual( const StreamBuffer_t *pxBuffer, const size_t uxLeft, const size_t uxRight );\r
190 static portINLINE BaseType_t xStreamBufferLessThenEqual( const StreamBuffer_t *pxBuffer, const size_t uxLeft, const size_t uxRight )\r
191 {\r
192 BaseType_t xReturn;\r
193 size_t uxTail = pxBuffer->uxTail;\r
194 \r
195         /* Returns true if ( uxLeft < uxRight ) */\r
196         if( ( uxLeft < uxTail ) ^ ( uxRight < uxTail ) )\r
197         {\r
198                 if( uxRight < uxTail )\r
199                 {\r
200                         xReturn = pdTRUE;\r
201                 }\r
202                 else\r
203                 {\r
204                         xReturn = pdFALSE;\r
205                 }\r
206         }\r
207         else\r
208         {\r
209                 if( uxLeft <= uxRight )\r
210                 {\r
211                         xReturn = pdTRUE;\r
212                 }\r
213                 else\r
214                 {\r
215                         xReturn = pdFALSE;\r
216                 }\r
217         }\r
218         return xReturn;\r
219 }\r
220 /*-----------------------------------------------------------*/\r
221 \r
222 static portINLINE size_t uxStreamBufferGetPtr( StreamBuffer_t *pxBuffer, uint8_t **ppucData );\r
223 static portINLINE size_t uxStreamBufferGetPtr( StreamBuffer_t *pxBuffer, uint8_t **ppucData )\r
224 {\r
225 size_t uxNextTail = pxBuffer->uxTail;\r
226 size_t uxSize = uxStreamBufferGetSize( pxBuffer );\r
227 \r
228         *ppucData = pxBuffer->ucArray + uxNextTail;\r
229 \r
230         return FreeRTOS_min_uint32( uxSize, pxBuffer->LENGTH - uxNextTail );\r
231 }\r
232 \r
233 /*\r
234  * Add bytes to a stream buffer.\r
235  *\r
236  * pxBuffer -   The buffer to which the bytes will be added.\r
237  * uxOffset -   If uxOffset > 0, data will be written at an offset from uxHead\r
238  *                              while uxHead will not be moved yet.\r
239  * pucData -    A pointer to the data to be added.\r
240  * uxCount -    The number of bytes to add.\r
241  */\r
242 size_t uxStreamBufferAdd( StreamBuffer_t *pxBuffer, size_t uxOffset, const uint8_t *pucData, size_t uxCount );\r
243 \r
244 /*\r
245  * Read bytes from a stream buffer.\r
246  *\r
247  * pxBuffer -   The buffer from which the bytes will be read.\r
248  * uxOffset -   Can be used to read data located at a certain offset from 'uxTail'.\r
249  * pucData -    A pointer to the buffer into which data will be read.\r
250  * uxMaxCount - The number of bytes to read.\r
251  * xPeek -              If set to pdTRUE the data will remain in the buffer.\r
252  */\r
253 size_t uxStreamBufferGet( StreamBuffer_t *pxBuffer, size_t uxOffset, uint8_t *pucData, size_t uxMaxCount, BaseType_t xPeek );\r
254 \r
255 #ifdef __cplusplus\r
256 } /* extern "C" */\r
257 #endif\r
258 \r
259 #endif  /* !defined( FREERTOS_STREAM_BUFFER_H ) */\r