Explorar el Código

Added preliminary doxygen documentation

tags/v0.9.3
Michael Brown hace 19 años
padre
commit
a2915ad06d
Se han modificado 1 ficheros con 117 adiciones y 16 borrados
  1. 117
    16
      src/core/buffer.c

+ 117
- 16
src/core/buffer.c Ver fichero

@@ -1,6 +1,10 @@
1
-/*
2
- * Routines for filling a buffer with data received piecemeal, where
3
- * the size of the data is not necessarily known in advance.
1
+/** @file
2
+ *
3
+ * Buffers for loading files.
4
+ *
5
+ * This file provides routines for filling a buffer with data received
6
+ * piecemeal, where the size of the data is not necessarily known in
7
+ * advance.
4 8
  *
5 9
  * Some protocols do not provide a mechanism for us to know the size
6 10
  * of the file before we happen to receive a particular block
@@ -14,6 +18,40 @@
14 18
  * which assemble a file into a single contiguous block.  The whole
15 19
  * block is then passed to the image loader.
16 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_end) into which we want
31
+ *   // to load a file, where buf_start and buf_end are physical addresses.
32
+ *   buffer->start = buf_start;
33
+ *   buffer->end = buf_end;
34
+ *   init_buffer ( &buffer );
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 ) ) {
40
+ *       // An error occurred
41
+ *       return 0;
42
+ *     }
43
+ *     ...
44
+ *   }
45
+ *   ...
46
+ *   // The whole file is now present at [buf_start,buf_start+filesize),
47
+ *   // where buf_start is a physical address.  The struct buffer can simply
48
+ *   // be discarded; there is no done_buffer() call.
49
+ *
50
+ * @endcode
51
+ *
52
+ */
53
+
54
+/** @package Internals
17 55
  *
18 56
  * Note that the rather convoluted way of manipulating the buffer
19 57
  * descriptors (using copy_{to,from}_phys rather than straightforward
@@ -28,8 +66,16 @@
28 66
 #include "io.h"
29 67
 #include "buffer.h"
30 68
 
31
-/*
32
- * Initialise a buffer
69
+/**
70
+ * Initialise a buffer.
71
+ *
72
+ * @v buffer		The buffer to be initialised
73
+ * @ret None
74
+ * @err None
75
+ *
76
+ * Set @c buffer->start and @c buffer->end before calling init_buffer().
77
+ * init_buffer() will initialise the buffer to the state of being
78
+ * empty.
33 79
  *
34 80
  */
35 81
 void init_buffer ( struct buffer *buffer ) {
@@ -42,8 +88,27 @@ void init_buffer ( struct buffer *buffer ) {
42 88
 	DBG ( "BUFFER [%x,%x) initialised\n", buffer->start, buffer->end );
43 89
 }
44 90
 
45
-/*
46
- * Split a free block
91
+/**
92
+ * Split a free block.
93
+ *
94
+ * @v desc		A descriptor for the free block
95
+ * @v block		Start address of the block
96
+ * @v split		Address at which to split the block
97
+ * @ret None
98
+ * @err None
99
+ *
100
+ * Split a free block into two separate free blocks.  If the split
101
+ * point lies outside the block, no action is taken; this is not an
102
+ * error.
103
+ *
104
+ * @b NOTE: It is the reponsibility of the caller to ensure that there
105
+ * is enough room in each of the two portions for a free block
106
+ * descriptor (a @c struct @c buffer_free_block, except in the case of
107
+ * a tail block which requires only a one byte descriptor).  If the
108
+ * caller fails to do this, data corruption will occur.
109
+ *
110
+ * In practice, this means that the granularity at which blocks are
111
+ * split must be at least @c sizeof(struct @c buffer_free_block).
47 112
  *
48 113
  */
49 114
 static void split_free_block ( struct buffer_free_block *desc,
@@ -71,8 +136,16 @@ static void split_free_block ( struct buffer_free_block *desc,
71 136
 	copy_to_phys ( block, desc, sizeof ( *desc ) );
72 137
 }
73 138
 
74
-/*
75
- * Mark a free block as used
139
+/**
140
+ * Mark a free block as used.
141
+ *
142
+ * @v buffer		The buffer containing the block
143
+ * @v desc		A descriptor for the free block
144
+ * @v prev_block	Address of the previous block
145
+ * @ret None
146
+ * @err None
147
+ *
148
+ * Marks a free block as used, i.e. removes it from the free list.
76 149
  *
77 150
  */
78 151
 static inline void unfree_block ( struct buffer *buffer,
@@ -99,15 +172,42 @@ static inline void unfree_block ( struct buffer *buffer,
99 172
 	copy_to_phys ( prev_block, &prev_desc, sizeof ( prev_desc ) );
100 173
 }
101 174
 
102
-/*
103
- * Write data into a buffer
175
+/**
176
+ * Write data into a buffer.
177
+ *
178
+ * @v buffer		The buffer into which to write the data
179
+ * @v data		The data to be written
180
+ * @v offset		Offset within the buffer at which to write the data
181
+ * @v len		Length of data to be written
182
+ * @ret True		Data was successfully written
183
+ * @ret False		Data was not written
184
+ * @err ENOMEM		Buffer is too small to contain the data
185
+ *
186
+ * Writes a block of data into the buffer.  The block need not be
187
+ * aligned to any particular boundary, or be of any particular size,
188
+ * and it may overlap blocks already in the buffer (i.e. duplicate
189
+ * calls to fill_buffer() are explicitly permitted).
190
+ *
191
+ * @c buffer->fill will be updated to indicate the fill level of the
192
+ * buffer, i.e. the offset to the first gap within the buffer.  If the
193
+ * filesize is known (e.g. as with the SLAM protocol), you can test
194
+ * for end-of-file by checking for @c buffer->fill==filesize.  If the
195
+ * filesize is not known, but there is a well-defined end-of-file test
196
+ * (e.g. as with the TFTP protocol), you can read @c buffer->fill to
197
+ * determine the final filesize.  If blocks are known to be delivered
198
+ * in a strictly sequential order with no packet loss or duplication,
199
+ * then you can pass in @c offset==buffer->fill.
200
+ *
201
+ * @b NOTE: It is the caller's responsibility to ensure that the
202
+ * boundaries between data blocks are more than @c sizeof(struct @c
203
+ * buffer_free_block) apart.  If this condition is not satisfied, data
204
+ * corruption will occur.  (See split_free_block() for details.)
104 205
  *
105
- * It is the caller's responsibility to ensure that the boundaries
106
- * between data blocks are more than sizeof(struct buffer_free_block)
107
- * apart.  If this condition is not satisfied, data corruption will
108
- * occur.
206
+ * @att In practice this is not a problem.  Callers of fill_buffer()
207
+ * will be download protocols such as TFTP, and very few protocols
208
+ * have a block size smaller than @c sizeof(struct @c
209
+ * buffer_free_block).
109 210
  *
110
- * Returns 1 for success, 0 for failure (e.g. buffer too small).
111 211
  */
112 212
 int fill_buffer ( struct buffer *buffer, const void *data,
113 213
 		  off_t offset, size_t len ) {
@@ -125,6 +225,7 @@ int fill_buffer ( struct buffer *buffer, const void *data,
125 225
 	if ( data_end > buffer->end ) {
126 226
 		DBG ( "BUFFER [%x,%x) too small for data!\n",
127 227
 		      buffer->start, buffer->end );
228
+		errno = ENOMEM;
128 229
 		return 0;
129 230
 	}
130 231
 

Loading…
Cancelar
Guardar