Browse Source

Added preliminary doxygen documentation

tags/v0.9.3
Michael Brown 19 years ago
parent
commit
a2915ad06d
1 changed files with 117 additions and 16 deletions
  1. 117
    16
      src/core/buffer.c

+ 117
- 16
src/core/buffer.c View File

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
  * Some protocols do not provide a mechanism for us to know the size
9
  * Some protocols do not provide a mechanism for us to know the size
6
  * of the file before we happen to receive a particular block
10
  * of the file before we happen to receive a particular block
14
  * which assemble a file into a single contiguous block.  The whole
18
  * which assemble a file into a single contiguous block.  The whole
15
  * block is then passed to the image loader.
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
  * Note that the rather convoluted way of manipulating the buffer
56
  * Note that the rather convoluted way of manipulating the buffer
19
  * descriptors (using copy_{to,from}_phys rather than straightforward
57
  * descriptors (using copy_{to,from}_phys rather than straightforward
28
 #include "io.h"
66
 #include "io.h"
29
 #include "buffer.h"
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
 void init_buffer ( struct buffer *buffer ) {
81
 void init_buffer ( struct buffer *buffer ) {
42
 	DBG ( "BUFFER [%x,%x) initialised\n", buffer->start, buffer->end );
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
 static void split_free_block ( struct buffer_free_block *desc,
114
 static void split_free_block ( struct buffer_free_block *desc,
71
 	copy_to_phys ( block, desc, sizeof ( *desc ) );
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
 static inline void unfree_block ( struct buffer *buffer,
151
 static inline void unfree_block ( struct buffer *buffer,
99
 	copy_to_phys ( prev_block, &prev_desc, sizeof ( prev_desc ) );
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
 int fill_buffer ( struct buffer *buffer, const void *data,
212
 int fill_buffer ( struct buffer *buffer, const void *data,
113
 		  off_t offset, size_t len ) {
213
 		  off_t offset, size_t len ) {
125
 	if ( data_end > buffer->end ) {
225
 	if ( data_end > buffer->end ) {
126
 		DBG ( "BUFFER [%x,%x) too small for data!\n",
226
 		DBG ( "BUFFER [%x,%x) too small for data!\n",
127
 		      buffer->start, buffer->end );
227
 		      buffer->start, buffer->end );
228
+		errno = ENOMEM;
128
 		return 0;
229
 		return 0;
129
 	}
230
 	}
130
 
231
 

Loading…
Cancel
Save