xref: /OK3568_Linux_fs/u-boot/include/membuff.h (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun  * Copyright (c) 2015 Google, Inc
3*4882a593Smuzhiyun  * Written by Simon Glass <sjg@chromium.org>
4*4882a593Smuzhiyun  *
5*4882a593Smuzhiyun  * Copyright (c) 1992 Simon Glass
6*4882a593Smuzhiyun  *
7*4882a593Smuzhiyun  * SPDX-License-Identifier:	GPL-2.0+
8*4882a593Smuzhiyun  */
9*4882a593Smuzhiyun 
10*4882a593Smuzhiyun #ifndef _MEMBUFF_H
11*4882a593Smuzhiyun #define _MEMBUFF_H
12*4882a593Smuzhiyun 
13*4882a593Smuzhiyun /**
14*4882a593Smuzhiyun  * @struct membuff: holds the state of a membuff - it is used for input and
15*4882a593Smuzhiyun  * output buffers. The buffer extends from @start to (@start + @size - 1).
16*4882a593Smuzhiyun  * Data in the buffer extends from @tail to @head: it is written in at
17*4882a593Smuzhiyun  * @head and read out from @tail. The membuff is empty when @head == @tail
18*4882a593Smuzhiyun  * and full when adding another character would make @head == @tail. We
19*4882a593Smuzhiyun  * therefore waste one character in the membuff to avoid having an extra flag
20*4882a593Smuzhiyun  * to determine whether (when @head == @tail) the membuff is empty or full.
21*4882a593Smuzhiyun  *
22*4882a593Smuzhiyun  * xxxxxx  data
23*4882a593Smuzhiyun  * ......  empty
24*4882a593Smuzhiyun  *
25*4882a593Smuzhiyun  * .............xxxxxxxxxxxxxxxx.........................
26*4882a593Smuzhiyun  *		^		^
27*4882a593Smuzhiyun  *		tail		head
28*4882a593Smuzhiyun  *
29*4882a593Smuzhiyun  * xxxxxxxxxxxxx................xxxxxxxxxxxxxxxxxxxxxxxxx
30*4882a593Smuzhiyun  *		^		^
31*4882a593Smuzhiyun  *		head		tail
32*4882a593Smuzhiyun  */
33*4882a593Smuzhiyun struct membuff {
34*4882a593Smuzhiyun 	char *start;		/** the start of the buffer */
35*4882a593Smuzhiyun 	char *end;		/** the end of the buffer (start + length) */
36*4882a593Smuzhiyun 	char *head;		/** current buffer head */
37*4882a593Smuzhiyun 	char *tail;		/** current buffer tail */
38*4882a593Smuzhiyun };
39*4882a593Smuzhiyun 
40*4882a593Smuzhiyun /**
41*4882a593Smuzhiyun  * membuff_purge() - reset a membuff to the empty state
42*4882a593Smuzhiyun  *
43*4882a593Smuzhiyun  * Initialise head and tail pointers so that the membuff becomes empty.
44*4882a593Smuzhiyun  *
45*4882a593Smuzhiyun  * @mb: membuff to purge
46*4882a593Smuzhiyun  */
47*4882a593Smuzhiyun void membuff_purge(struct membuff *mb);
48*4882a593Smuzhiyun 
49*4882a593Smuzhiyun /**
50*4882a593Smuzhiyun  * membuff_putraw() - find out where bytes can be written
51*4882a593Smuzhiyun  *
52*4882a593Smuzhiyun  * Work out where in the membuff some data could be written. Return a pointer
53*4882a593Smuzhiyun  * to the address and the number of bytes which can be written there. If
54*4882a593Smuzhiyun  * @update is true, the caller must then write the data immediately, since
55*4882a593Smuzhiyun  * the membuff is updated as if the write has been done,
56*4882a593Smuzhiyun  *
57*4882a593Smuzhiyun  * Note that because the spare space in a membuff may not be contiguous, this
58*4882a593Smuzhiyun  * function may not return @maxlen even if there is enough space in the
59*4882a593Smuzhiyun  * membuff. However, by calling this function twice (with @update == true),
60*4882a593Smuzhiyun  * you will get access to all the spare space.
61*4882a593Smuzhiyun  *
62*4882a593Smuzhiyun  * @mb: membuff to adjust
63*4882a593Smuzhiyun  * @maxlen: the number of bytes we want to write
64*4882a593Smuzhiyun  * @update: true to update the membuff as if the write happened, false to not
65*4882a593Smuzhiyun  * @data: the address data can be written to
66*4882a593Smuzhiyun  * @return number of bytes which can be written
67*4882a593Smuzhiyun  */
68*4882a593Smuzhiyun int membuff_putraw(struct membuff *mb, int maxlen, bool update, char **data);
69*4882a593Smuzhiyun 
70*4882a593Smuzhiyun /**
71*4882a593Smuzhiyun  * membuff_getraw() - find and return a pointer to available bytes
72*4882a593Smuzhiyun  *
73*4882a593Smuzhiyun  * Returns a pointer to any valid input data in the given membuff and
74*4882a593Smuzhiyun  * optionally marks it as read. Note that not all input data may not be
75*4882a593Smuzhiyun  * returned, since data is not necessarily contiguous in the membuff. However,
76*4882a593Smuzhiyun  * if you call this function twice (with @update == true) you are guaranteed
77*4882a593Smuzhiyun  * to get all available data, in at most two installments.
78*4882a593Smuzhiyun  *
79*4882a593Smuzhiyun  * @mb: membuff to adjust
80*4882a593Smuzhiyun  * @maxlen: maximum number of bytes to get
81*4882a593Smuzhiyun  * @update: true to update the membuff as if the bytes have been read (use
82*4882a593Smuzhiyun  * false to check bytes without reading them)
83*4882a593Smuzhiyun  * @data: returns address of data in input membuff
84*4882a593Smuzhiyun  * @return the number of bytes available at *@data
85*4882a593Smuzhiyun  */
86*4882a593Smuzhiyun int membuff_getraw(struct membuff *mb, int maxlen, bool update, char **data);
87*4882a593Smuzhiyun 
88*4882a593Smuzhiyun /**
89*4882a593Smuzhiyun  * membuff_putbyte() - Writes a byte to a membuff
90*4882a593Smuzhiyun  *
91*4882a593Smuzhiyun  * @mb: membuff to adjust
92*4882a593Smuzhiyun  * @ch: byte to write
93*4882a593Smuzhiyun  * @return true on success, false if membuff is full
94*4882a593Smuzhiyun  */
95*4882a593Smuzhiyun bool membuff_putbyte(struct membuff *mb, int ch);
96*4882a593Smuzhiyun 
97*4882a593Smuzhiyun /**
98*4882a593Smuzhiyun  * @mb: membuff to adjust
99*4882a593Smuzhiyun  * membuff_getbyte() - Read a byte from the membuff
100*4882a593Smuzhiyun  * @return the byte read, or -1 if the membuff is empty
101*4882a593Smuzhiyun  */
102*4882a593Smuzhiyun int membuff_getbyte(struct membuff *mb);
103*4882a593Smuzhiyun 
104*4882a593Smuzhiyun /**
105*4882a593Smuzhiyun  * membuff_peekbyte() - check the next available byte
106*4882a593Smuzhiyun  *
107*4882a593Smuzhiyun  * Return the next byte which membuff_getbyte() would return, without
108*4882a593Smuzhiyun  * removing it from the membuff.
109*4882a593Smuzhiyun  *
110*4882a593Smuzhiyun  * @mb: membuff to adjust
111*4882a593Smuzhiyun  * @return the byte peeked, or -1 if the membuff is empty
112*4882a593Smuzhiyun  */
113*4882a593Smuzhiyun int membuff_peekbyte(struct membuff *mb);
114*4882a593Smuzhiyun 
115*4882a593Smuzhiyun /**
116*4882a593Smuzhiyun  * membuff_get() - get data from a membuff
117*4882a593Smuzhiyun  *
118*4882a593Smuzhiyun  * Copies any available data (up to @maxlen bytes) to @buff and removes it
119*4882a593Smuzhiyun  * from the membuff.
120*4882a593Smuzhiyun  *
121*4882a593Smuzhiyun  * @mb: membuff to adjust
122*4882a593Smuzhiyun  * @Buff: address of membuff to transfer bytes to
123*4882a593Smuzhiyun  * @maxlen: maximum number of bytes to read
124*4882a593Smuzhiyun  * @return the number of bytes read
125*4882a593Smuzhiyun  */
126*4882a593Smuzhiyun int membuff_get(struct membuff *mb, char *buff, int maxlen);
127*4882a593Smuzhiyun 
128*4882a593Smuzhiyun /**
129*4882a593Smuzhiyun  * membuff_put() - write data to a membuff
130*4882a593Smuzhiyun  *
131*4882a593Smuzhiyun  * Writes some data to a membuff. Returns the number of bytes added. If this
132*4882a593Smuzhiyun  * is less than @lnehgt, then the membuff got full
133*4882a593Smuzhiyun  *
134*4882a593Smuzhiyun  * @mb: membuff to adjust
135*4882a593Smuzhiyun  * @data: the data to write
136*4882a593Smuzhiyun  * @length: number of bytes to write from 'data'
137*4882a593Smuzhiyun  * @return the number of bytes added
138*4882a593Smuzhiyun  */
139*4882a593Smuzhiyun int membuff_put(struct membuff *mb, const char *buff, int length);
140*4882a593Smuzhiyun 
141*4882a593Smuzhiyun /**
142*4882a593Smuzhiyun  * membuff_isempty() - check if a membuff is empty
143*4882a593Smuzhiyun  *
144*4882a593Smuzhiyun  * @mb: membuff to check
145*4882a593Smuzhiyun  * @return true if empty, else false
146*4882a593Smuzhiyun  */
147*4882a593Smuzhiyun bool membuff_isempty(struct membuff *mb);
148*4882a593Smuzhiyun 
149*4882a593Smuzhiyun /**
150*4882a593Smuzhiyun  * membuff_avail() - check available data in a membuff
151*4882a593Smuzhiyun  *
152*4882a593Smuzhiyun  * @mb: membuff to check
153*4882a593Smuzhiyun  * @return number of bytes of data available
154*4882a593Smuzhiyun  */
155*4882a593Smuzhiyun int membuff_avail(struct membuff *mb);
156*4882a593Smuzhiyun 
157*4882a593Smuzhiyun /**
158*4882a593Smuzhiyun  * membuff_size() - get the size of a membuff
159*4882a593Smuzhiyun  *
160*4882a593Smuzhiyun  * Note that a membuff can only old data up to one byte less than its size.
161*4882a593Smuzhiyun  *
162*4882a593Smuzhiyun  * @mb: membuff to check
163*4882a593Smuzhiyun  * @return total size
164*4882a593Smuzhiyun  */
165*4882a593Smuzhiyun int membuff_size(struct membuff *mb);
166*4882a593Smuzhiyun 
167*4882a593Smuzhiyun /**
168*4882a593Smuzhiyun  * membuff_makecontig() - adjust all membuff data to be contiguous
169*4882a593Smuzhiyun  *
170*4882a593Smuzhiyun  * This places all data in a membuff into a single contiguous lump, if
171*4882a593Smuzhiyun  * possible
172*4882a593Smuzhiyun  *
173*4882a593Smuzhiyun  * @mb: membuff to adjust
174*4882a593Smuzhiyun  * @return true on success
175*4882a593Smuzhiyun  */
176*4882a593Smuzhiyun bool membuff_makecontig(struct membuff *mb);
177*4882a593Smuzhiyun 
178*4882a593Smuzhiyun /**
179*4882a593Smuzhiyun  * membuff_free() - find the number of bytes that can be written to a membuff
180*4882a593Smuzhiyun  *
181*4882a593Smuzhiyun  * @mb: membuff to check
182*4882a593Smuzhiyun  * @return returns the number of bytes free in a membuff
183*4882a593Smuzhiyun  */
184*4882a593Smuzhiyun int membuff_free(struct membuff *mb);
185*4882a593Smuzhiyun 
186*4882a593Smuzhiyun /**
187*4882a593Smuzhiyun  * membuff_readline() - read a line of text from a membuff
188*4882a593Smuzhiyun  *
189*4882a593Smuzhiyun  * Reads a line of text of up to 'maxlen' characters from a membuff and puts
190*4882a593Smuzhiyun  * it in @str. Any character less than @minch is assumed to be the end of
191*4882a593Smuzhiyun  * line character
192*4882a593Smuzhiyun  *
193*4882a593Smuzhiyun  * @mb: membuff to adjust
194*4882a593Smuzhiyun  * @str: Place to put the line
195*4882a593Smuzhiyun  * @maxlen: Maximum line length (excluding terminator)
196*4882a593Smuzhiyun  * @return number of bytes read (including terminator) if a line has been
197*4882a593Smuzhiyun  *	   read, 0 if nothing was there
198*4882a593Smuzhiyun  */
199*4882a593Smuzhiyun int membuff_readline(struct membuff *mb, char *str, int maxlen, int minch);
200*4882a593Smuzhiyun 
201*4882a593Smuzhiyun /**
202*4882a593Smuzhiyun  * membuff_extend_by() - expand a membuff
203*4882a593Smuzhiyun  *
204*4882a593Smuzhiyun  * Extends a membuff by the given number of bytes
205*4882a593Smuzhiyun  *
206*4882a593Smuzhiyun  * @mb: membuff to adjust
207*4882a593Smuzhiyun  * @by: Number of bytes to increase the size by
208*4882a593Smuzhiyun  * @max: Maximum size to allow
209*4882a593Smuzhiyun  * @return 0 if the expand succeeded, -ENOMEM if not enough memory, -E2BIG
210*4882a593Smuzhiyun  * if the the size would exceed @max
211*4882a593Smuzhiyun  */
212*4882a593Smuzhiyun int membuff_extend_by(struct membuff *mb, int by, int max);
213*4882a593Smuzhiyun 
214*4882a593Smuzhiyun /**
215*4882a593Smuzhiyun  * membuff_init() - set up a new membuff using an existing membuff
216*4882a593Smuzhiyun  *
217*4882a593Smuzhiyun  * @mb: membuff to set up
218*4882a593Smuzhiyun  * @buff: Address of buffer
219*4882a593Smuzhiyun  * @size: Size of buffer
220*4882a593Smuzhiyun  */
221*4882a593Smuzhiyun void membuff_init(struct membuff *mb, char *buff, int size);
222*4882a593Smuzhiyun 
223*4882a593Smuzhiyun /**
224*4882a593Smuzhiyun  * membuff_uninit() - clear a membuff so it can no longer be used
225*4882a593Smuzhiyun  *
226*4882a593Smuzhiyun  * @mb: membuff to uninit
227*4882a593Smuzhiyun  */
228*4882a593Smuzhiyun void membuff_uninit(struct membuff *mb);
229*4882a593Smuzhiyun 
230*4882a593Smuzhiyun /**
231*4882a593Smuzhiyun  * membuff_new() - create a new membuff
232*4882a593Smuzhiyun  *
233*4882a593Smuzhiyun  * @mb: membuff to init
234*4882a593Smuzhiyun  * @size: size of membuff to create
235*4882a593Smuzhiyun  * @return 0 if OK, -ENOMEM if out of memory
236*4882a593Smuzhiyun  */
237*4882a593Smuzhiyun int membuff_new(struct membuff *mb, int size);
238*4882a593Smuzhiyun 
239*4882a593Smuzhiyun /**
240*4882a593Smuzhiyun  * membuff_dispose() - free memory allocated to a membuff and uninit it
241*4882a593Smuzhiyun  *
242*4882a593Smuzhiyun  * @mb: membuff to dispose
243*4882a593Smuzhiyun  */
244*4882a593Smuzhiyun void membuff_dispose(struct membuff *mb);
245*4882a593Smuzhiyun 
246*4882a593Smuzhiyun #endif
247