b366955c9fcc81e55a690267e69ebe5f0fb3f875
[people/xl0/gpxe.git] / src / include / gpxe / buffer.h
1 #ifndef _GPXE_BUFFER_H
2 #define _GPXE_BUFFER_H
3
4 #include <stdint.h>
5 #include <gpxe/uaccess.h>
6
7 /** @file
8  *
9  * Buffers for loading files.
10  *
11  * This file provides routines for filling a buffer with data received
12  * piecemeal, where the size of the data is not necessarily known in
13  * advance.
14  *
15  * Some protocols do not provide a mechanism for us to know the size
16  * of the file before we happen to receive a particular block
17  * (e.g. the final block in an MTFTP transfer).  In addition, some
18  * protocols (e.g. the multicast protocols) can, in theory, provide
19  * the data in any order.
20  *
21  * Example usage:
22  *
23  * @code
24  *
25  *   struct buffer my_buffer;
26  *   void *data;
27  *   off_t offset;
28  *   size_t len;
29  *   
30  *   // We have an area of memory [buf_start,buf_start+len) into which to
31  *   // load a file, where buf_start is a userptr_t.
32  *   memset ( &buffer, 0, sizeof ( buffer ) );
33  *   buffer->start = buf_start;
34  *   buffer->len = len;
35  *   ...
36  *   while ( get_file_block ( ... ) ) {
37  *     // Downloaded block is stored in [data,data+len), and represents 
38  *     // the portion of the file at offsets [offset,offset+len)
39  *     if ( fill_buffer ( &buffer, data, offset, len ) != 0 ) {
40  *       // An error occurred
41  *     }
42  *     ...
43  *   }
44  *   ...
45  *   // The whole file is now present at [buf_start,buf_start+filesize),
46  *   // where buf_start is a userptr_t.  The struct buffer can simply
47  *   // be discarded.
48  *
49  * @endcode
50  *
51  */
52
53 /**
54  * A data buffer
55  *
56  * A buffer looks something like this:
57  *
58  * @code
59  *
60  *     XXXXXXXXXXXXXXXXX.........XXX..........XXXXXXX........XXXXXX.........
61  *
62  *     ^
63  *     |
64  *   start
65  *
66  *     <----- fill ---->
67  *
68  *     <------------------------ free ---------------------------->
69  *
70  *     <------------------------------ len -------------------------------->
71  *
72  * @endcode
73  *
74  * #start and #len denote the real boundaries of the buffer.  #fill
75  * denotes the offset to the first free block in the buffer.  (If the
76  * buffer is full, #fill, #free and #len will all be equal.)
77  *
78  */
79 struct buffer {
80         /** Start of buffer */
81         userptr_t addr;
82         /** Total length of buffer */
83         size_t len;
84         /** Offset to first free block within buffer */
85         size_t fill;
86         /** Offset to last free block within buffer */
87         size_t free;
88         /** Expand data buffer
89          *
90          * @v buffer            Data buffer
91          * @v new_len           New length
92          * @ret rc              Return status code
93          *
94          * Expand the data buffer to accommodate more data.  This
95          * method is optional; if it is @c NULL then the buffer will
96          * not be expandable.
97          */
98         int ( * expand ) ( struct buffer *buffer, size_t new_len );
99 };
100
101 extern int fill_buffer ( struct buffer *buffer, const void *data,
102                          size_t offset, size_t len );
103
104 #endif /* _GPXE_BUFFER_H */