Move API docs to buffer.h, implementation to buffer.c.
[people/xl0/gpxe.git] / src / include / buffer.h
1 #ifndef BUFFER_H
2 #define BUFFER_H
3
4 #include "etherboot.h"
5
6 /** @file
7  *
8  * Buffers for loading files.
9  *
10  * This file provides routines for filling a buffer with data received
11  * piecemeal, where the size of the data is not necessarily known in
12  * advance.
13  *
14  * Some protocols do not provide a mechanism for us to know the size
15  * of the file before we happen to receive a particular block
16  * (e.g. the final block in an MTFTP transfer).  In addition, some
17  * protocols (all the multicast protocols plus any TCP-based protocol)
18  * can, in theory, provide the data in any order.
19  *
20  * Rather than requiring each protocol to implement its own equivalent
21  * of "dd" to arrange the data into well-sized pieces before handing
22  * off to the image loader, we provide these generic buffer functions
23  * which assemble a file into a single contiguous block.  The whole
24  * block is then passed to the image loader.
25  *
26  * Example usage:
27  *
28  * @code
29  *
30  *   struct buffer my_buffer;
31  *   void *data;
32  *   off_t offset;
33  *   size_t len;
34  *   
35  *   // We have an area of memory [buf_start,buf_end) into which we want
36  *   // to load a file, where buf_start and buf_end are physical addresses.
37  *   buffer->start = buf_start;
38  *   buffer->end = buf_end;
39  *   init_buffer ( &buffer );
40  *   ...
41  *   while ( get_file_block ( ... ) ) {
42  *     // Downloaded block is stored in [data,data+len), and represents 
43  *     // the portion of the file at offsets [offset,offset+len)
44  *     if ( ! fill_buffer ( &buffer, data, offset, len ) ) {
45  *       // An error occurred
46  *       return 0;
47  *     }
48  *     ...
49  *   }
50  *   ...
51  *   // The whole file is now present at [buf_start,buf_start+filesize),
52  *   // where buf_start is a physical address.  The struct buffer can simply
53  *   // be discarded; there is no done_buffer() call.
54  *
55  * @endcode
56  *
57  * For a description of the internal operation, see buffer.c.
58  *
59  */
60
61 /**
62  * A buffer
63  *
64  * @c start and @c end denote the real boundaries of the buffer, and
65  * are physical addresses.  @c fill denotes the offset to the first
66  * free block in the buffer.  (If the buffer is full, @c fill will
67  * equal @c end-start.)
68  *
69  */
70 struct buffer {
71         physaddr_t      start;          /**< Start of buffer in memory */
72         physaddr_t      end;            /**< End of buffer in memory */
73         off_t           fill;           /**< Offset to first gap in buffer */
74 };
75
76 /**
77  * A free block descriptor.
78  *
79  * See buffer.c for a full description of the fields.
80  *
81  */
82 struct buffer_free_block {
83         char            tail;           /**< Tail byte marker */
84         physaddr_t      next_free;      /**< Address of next free block */
85         physaddr_t      end;            /**< End of this block */
86 } __attribute__ (( packed ));
87
88 /* Functions in buffer.c */
89
90 extern void init_buffer ( struct buffer *buffer );
91 extern int fill_buffer ( struct buffer *buffer, const void *data,
92                          off_t offset, size_t len );
93
94 #endif /* BUFFER_H */