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