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