]> git.sur5r.net Git - freertos/blob - FreeRTOS-Labs/Source/FreeRTOS-Plus-TCP/include/FreeRTOS_Stream_Buffer.h
Update TCP to last release versions in preparation for kernel V10.3.0 release.
[freertos] / FreeRTOS-Labs / Source / FreeRTOS-Plus-TCP / include / FreeRTOS_Stream_Buffer.h
1 /*\r
2  * FreeRTOS+TCP 2.2.x Labs copy\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.\r
14  *\r
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS\r
17  * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR\r
18  * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER\r
19  * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
20  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r
21  *\r
22  * http://aws.amazon.com/freertos\r
23  * http://www.FreeRTOS.org\r
24  */\r
25 \r
26 /*\r
27  *      FreeRTOS_Stream_Buffer.h\r
28  *\r
29  *      A cicular character buffer\r
30  *      An implementation of a circular buffer without a length field\r
31  *      If LENGTH defines the size of the buffer, a maximum of (LENGT-1) bytes can be stored\r
32  *      In order to add or read data from the buffer, memcpy() will be called at most 2 times\r
33  */\r
34 \r
35 #ifndef FREERTOS_STREAM_BUFFER_H\r
36 #define FREERTOS_STREAM_BUFFER_H\r
37 \r
38 #ifdef __cplusplus\r
39 extern "C" {\r
40 #endif\r
41 \r
42 typedef struct xSTREAM_BUFFER {\r
43         volatile size_t uxTail;         /* next item to read */\r
44         volatile size_t uxMid;          /* iterator within the valid items */\r
45         volatile size_t uxHead;         /* next position store a new item */\r
46         volatile size_t uxFront;        /* iterator within the free space */\r
47         size_t LENGTH;                          /* const value: number of reserved elements */\r
48         uint8_t ucArray[ sizeof( size_t ) ];\r
49 } StreamBuffer_t;\r
50 \r
51 static portINLINE void vStreamBufferClear( StreamBuffer_t *pxBuffer );\r
52 static portINLINE void vStreamBufferClear( StreamBuffer_t *pxBuffer )\r
53 {\r
54         /* Make the circular buffer empty */\r
55         pxBuffer->uxHead = 0u;\r
56         pxBuffer->uxTail = 0u;\r
57         pxBuffer->uxFront = 0u;\r
58         pxBuffer->uxMid = 0u;\r
59 }\r
60 /*-----------------------------------------------------------*/\r
61 \r
62 static portINLINE size_t uxStreamBufferSpace( const StreamBuffer_t *pxBuffer, const size_t uxLower, const size_t uxUpper );\r
63 static portINLINE size_t uxStreamBufferSpace( const StreamBuffer_t *pxBuffer, const size_t uxLower, const size_t uxUpper )\r
64 {\r
65 /* Returns the space between uxLower and uxUpper, which equals to the distance minus 1 */\r
66 size_t uxCount;\r
67 \r
68         uxCount = pxBuffer->LENGTH + uxUpper - uxLower - 1u;\r
69         if( uxCount >= pxBuffer->LENGTH )\r
70         {\r
71                 uxCount -= pxBuffer->LENGTH;\r
72         }\r
73 \r
74         return uxCount;\r
75 }\r
76 /*-----------------------------------------------------------*/\r
77 \r
78 static portINLINE size_t uxStreamBufferDistance( const StreamBuffer_t *pxBuffer, const size_t uxLower, const size_t uxUpper );\r
79 static portINLINE size_t uxStreamBufferDistance( const StreamBuffer_t *pxBuffer, const size_t uxLower, const size_t uxUpper )\r
80 {\r
81 /* Returns the distance between uxLower and uxUpper */\r
82 size_t uxCount;\r
83 \r
84         uxCount = pxBuffer->LENGTH + uxUpper - uxLower;\r
85         if ( uxCount >= pxBuffer->LENGTH )\r
86         {\r
87                 uxCount -= pxBuffer->LENGTH;\r
88         }\r
89 \r
90         return uxCount;\r
91 }\r
92 /*-----------------------------------------------------------*/\r
93 \r
94 static portINLINE size_t uxStreamBufferGetSpace( const StreamBuffer_t *pxBuffer );\r
95 static portINLINE size_t uxStreamBufferGetSpace( const StreamBuffer_t *pxBuffer )\r
96 {\r
97 /* Returns the number of items which can still be added to uxHead\r
98 before hitting on uxTail */\r
99 size_t uxHead = pxBuffer->uxHead;\r
100 size_t uxTail = pxBuffer->uxTail;\r
101 \r
102         return uxStreamBufferSpace( pxBuffer, uxHead, uxTail );\r
103 }\r
104 /*-----------------------------------------------------------*/\r
105 \r
106 static portINLINE size_t uxStreamBufferFrontSpace( const StreamBuffer_t *pxBuffer );\r
107 static portINLINE size_t uxStreamBufferFrontSpace( const StreamBuffer_t *pxBuffer )\r
108 {\r
109 /* Distance between uxFront and uxTail\r
110 or the number of items which can still be added to uxFront,\r
111 before hitting on uxTail */\r
112 \r
113 size_t uxFront = pxBuffer->uxFront;\r
114 size_t uxTail = pxBuffer->uxTail;\r
115 \r
116         return uxStreamBufferSpace( pxBuffer, uxFront, uxTail );\r
117 }\r
118 /*-----------------------------------------------------------*/\r
119 \r
120 static portINLINE size_t uxStreamBufferGetSize( const StreamBuffer_t *pxBuffer );\r
121 static portINLINE size_t uxStreamBufferGetSize( const StreamBuffer_t *pxBuffer )\r
122 {\r
123 /* Returns the number of items which can be read from uxTail\r
124 before reaching uxHead */\r
125 size_t uxHead = pxBuffer->uxHead;\r
126 size_t uxTail = pxBuffer->uxTail;\r
127 \r
128         return uxStreamBufferDistance( pxBuffer, uxTail, uxHead );\r
129 }\r
130 /*-----------------------------------------------------------*/\r
131 \r
132 static portINLINE size_t uxStreamBufferMidSpace( const StreamBuffer_t *pxBuffer );\r
133 static portINLINE size_t uxStreamBufferMidSpace( const StreamBuffer_t *pxBuffer )\r
134 {\r
135 /* Returns the distance between uxHead and uxMid */\r
136 size_t uxHead = pxBuffer->uxHead;\r
137 size_t uxMid = pxBuffer->uxMid;\r
138 \r
139         return uxStreamBufferDistance( pxBuffer, uxMid, uxHead );\r
140 }\r
141 /*-----------------------------------------------------------*/\r
142 \r
143 static portINLINE void vStreamBufferMoveMid( StreamBuffer_t *pxBuffer, size_t uxCount );\r
144 static portINLINE void vStreamBufferMoveMid( StreamBuffer_t *pxBuffer, size_t uxCount )\r
145 {\r
146 /* Increment uxMid, but no further than uxHead */\r
147 size_t uxSize = uxStreamBufferMidSpace( pxBuffer );\r
148 \r
149         if( uxCount > uxSize )\r
150         {\r
151                 uxCount = uxSize;\r
152         }\r
153         pxBuffer->uxMid += uxCount;\r
154         if( pxBuffer->uxMid >= pxBuffer->LENGTH )\r
155         {\r
156                 pxBuffer->uxMid -= pxBuffer->LENGTH;\r
157         }\r
158 }\r
159 /*-----------------------------------------------------------*/\r
160 \r
161 static portINLINE BaseType_t xStreamBufferLessThenEqual( const StreamBuffer_t *pxBuffer, const size_t uxLeft, const size_t uxRight );\r
162 static portINLINE BaseType_t xStreamBufferLessThenEqual( const StreamBuffer_t *pxBuffer, const size_t uxLeft, const size_t uxRight )\r
163 {\r
164 BaseType_t xReturn;\r
165 size_t uxTail = pxBuffer->uxTail;\r
166 \r
167         /* Returns true if ( uxLeft < uxRight ) */\r
168         if( ( uxLeft < uxTail ) ^ ( uxRight < uxTail ) )\r
169         {\r
170                 if( uxRight < uxTail )\r
171                 {\r
172                         xReturn = pdTRUE;\r
173                 }\r
174                 else\r
175                 {\r
176                         xReturn = pdFALSE;\r
177                 }\r
178         }\r
179         else\r
180         {\r
181                 if( uxLeft <= uxRight )\r
182                 {\r
183                         xReturn = pdTRUE;\r
184                 }\r
185                 else\r
186                 {\r
187                         xReturn = pdFALSE;\r
188                 }\r
189         }\r
190         return xReturn;\r
191 }\r
192 /*-----------------------------------------------------------*/\r
193 \r
194 static portINLINE size_t uxStreamBufferGetPtr( StreamBuffer_t *pxBuffer, uint8_t **ppucData );\r
195 static portINLINE size_t uxStreamBufferGetPtr( StreamBuffer_t *pxBuffer, uint8_t **ppucData )\r
196 {\r
197 size_t uxNextTail = pxBuffer->uxTail;\r
198 size_t uxSize = uxStreamBufferGetSize( pxBuffer );\r
199 \r
200         *ppucData = pxBuffer->ucArray + uxNextTail;\r
201 \r
202         return FreeRTOS_min_uint32( uxSize, pxBuffer->LENGTH - uxNextTail );\r
203 }\r
204 \r
205 /*\r
206  * Add bytes to a stream buffer.\r
207  *\r
208  * pxBuffer -   The buffer to which the bytes will be added.\r
209  * uxOffset -   If uxOffset > 0, data will be written at an offset from uxHead\r
210  *                              while uxHead will not be moved yet.\r
211  * pucData -    A pointer to the data to be added.\r
212  * uxCount -    The number of bytes to add.\r
213  */\r
214 size_t uxStreamBufferAdd( StreamBuffer_t *pxBuffer, size_t uxOffset, const uint8_t *pucData, size_t uxCount );\r
215 \r
216 /*\r
217  * Read bytes from a stream buffer.\r
218  *\r
219  * pxBuffer -   The buffer from which the bytes will be read.\r
220  * uxOffset -   Can be used to read data located at a certain offset from 'uxTail'.\r
221  * pucData -    A pointer to the buffer into which data will be read.\r
222  * uxMaxCount - The number of bytes to read.\r
223  * xPeek -              If set to pdTRUE the data will remain in the buffer.\r
224  */\r
225 size_t uxStreamBufferGet( StreamBuffer_t *pxBuffer, size_t uxOffset, uint8_t *pucData, size_t uxMaxCount, BaseType_t xPeek );\r
226 \r
227 #ifdef __cplusplus\r
228 } /* extern "C" */\r
229 #endif\r
230 \r
231 #endif  /* !defined( FREERTOS_STREAM_BUFFER_H ) */\r