1
1
/*
2
- * Copyright (c) 2006-2023, RT-Thread Development Team
2
+ * Copyright (c) 2006-2025 RT-Thread Development Team
3
3
*
4
4
* SPDX-License-Identifier: Apache-2.0
5
5
*
18
18
#define PAGE_SIZE 4096
19
19
#endif
20
20
21
+ /**
22
+ * @brief Handle buffer overflow condition in sequence file
23
+ *
24
+ * @param[in,out] seq Pointer to sequence file structure
25
+ *
26
+ * @details Sets the count to size to indicate buffer is full
27
+ */
21
28
static void dfs_seq_overflow (struct dfs_seq_file * seq )
22
29
{
23
30
seq -> count = seq -> size ;
24
31
}
25
32
33
+ /**
34
+ * @brief Allocate memory for sequence file operations
35
+ *
36
+ * @param[in] size Size of memory to allocate in bytes
37
+ *
38
+ * @return void* Pointer to allocated memory, or NULL if allocation fails
39
+ */
26
40
static void * dfs_seq_alloc (unsigned long size )
27
41
{
28
42
return rt_calloc (1 , size );
29
43
}
30
44
45
+ /**
46
+ * @brief Initialize and open a sequence file
47
+ *
48
+ * @param[in] file Pointer to the file structure to be initialized
49
+ * @param[in] ops Pointer to sequence operations structure containing callback functions
50
+ *
51
+ * @return int 0 on success, negative error code on failure:
52
+ * -EINVAL if ops is NULL
53
+ * -ENOMEM if memory allocation fails
54
+ */
31
55
int dfs_seq_open (struct dfs_file * file , const struct dfs_seq_ops * ops )
32
56
{
33
57
struct dfs_seq_file * seq ;
@@ -57,6 +81,21 @@ int dfs_seq_open(struct dfs_file *file, const struct dfs_seq_ops *ops)
57
81
return 0 ;
58
82
}
59
83
84
+ /**
85
+ * @brief Traverse sequence file data with specified offset
86
+ *
87
+ * This function traverses the sequence file data starting from the specified offset.
88
+ * It handles buffer overflow conditions by dynamically resizing the buffer when needed.
89
+ *
90
+ * @param[in,out] seq Pointer to sequence file structure
91
+ * @param[in] offset Position to start traversing from
92
+ *
93
+ * @return int 0 on success, negative error code on failure:
94
+ * -ENOMEM if memory allocation fails
95
+ * -EAGAIN if buffer needs to be resized
96
+ *
97
+ * @note Data output loop: start() -> show() -> next() -> show() -> ... -> next() -> stop()
98
+ */
60
99
static int dfs_seq_traverse (struct dfs_seq_file * seq , off_t offset )
61
100
{
62
101
off_t pos = 0 ;
@@ -111,6 +150,28 @@ static int dfs_seq_traverse(struct dfs_seq_file *seq, off_t offset)
111
150
return !seq -> buf ? - ENOMEM : - EAGAIN ;
112
151
}
113
152
153
+ /**
154
+ * @brief Read data from sequence file
155
+ *
156
+ * @param[in] file Pointer to the file structure
157
+ * @param[out] buf Buffer to store the read data
158
+ * @param[in] size Size of the buffer in bytes
159
+ * @param[in,out] pos Current file position (updated after read)
160
+ *
161
+ * @return ssize_t Number of bytes read on success, negative error code on failure:
162
+ * -EFAULT if buffer error occurs
163
+ * -ENOMEM if memory allocation fails
164
+ * 0 if size is 0
165
+ *
166
+ * @details This function implements the core sequence file reading logic with following steps:
167
+ * 1. Reset iterator if reading from start
168
+ * 2. Synchronize position if needed
169
+ * 3. Allocate buffer if not exists
170
+ * 4. Copy remaining data from previous read
171
+ * 5. Start iteration and fill buffer with new data
172
+ * 6. Handle buffer overflow by doubling size
173
+ * 7. Copy data to user buffer and update positions
174
+ */
114
175
ssize_t dfs_seq_read (struct dfs_file * file , void * buf , size_t size , off_t * pos )
115
176
{
116
177
struct dfs_seq_file * seq = file -> data ;
@@ -160,7 +221,7 @@ ssize_t dfs_seq_read(struct dfs_file *file, void *buf, size_t size, off_t *pos)
160
221
if (!seq -> buf )
161
222
goto Enomem ;
162
223
}
163
- // something left in the buffer - copy it out first
224
+ /* something left in the buffer - copy it out first */
164
225
if (seq -> count )
165
226
{
166
227
n = seq -> count > size ? size : seq -> count ;
@@ -169,27 +230,27 @@ ssize_t dfs_seq_read(struct dfs_file *file, void *buf, size_t size, off_t *pos)
169
230
seq -> count -= n ;
170
231
seq -> from += n ;
171
232
copied += n ;
172
- if (seq -> count ) // hadn't managed to copy everything
233
+ if (seq -> count ) /* hadn't managed to copy everything */
173
234
goto Done ;
174
235
}
175
- // get a non-empty record in the buffer
236
+ /* get a non-empty record in the buffer */
176
237
seq -> from = 0 ;
177
238
p = seq -> ops -> start (seq , & seq -> index );
178
239
while (p )
179
240
{
180
241
err = seq -> ops -> show (seq , p );
181
- if (err < 0 ) // hard error
242
+ if (err < 0 ) /* hard error */
182
243
break ;
183
- if (err ) // ->show() says "skip it"
244
+ if (err ) /* ->show() says "skip it" */
184
245
seq -> count = 0 ;
185
246
if (!seq -> count )
186
- { // empty record
247
+ { /* empty record */
187
248
p = seq -> ops -> next (seq , p , & seq -> index );
188
249
continue ;
189
250
}
190
- if (!dfs_seq_is_full (seq )) // got it
251
+ if (!dfs_seq_is_full (seq )) /* got it */
191
252
goto Fill ;
192
- // need a bigger buffer
253
+ /* need a bigger buffer */
193
254
seq -> ops -> stop (seq , p );
194
255
rt_free (seq -> buf );
195
256
seq -> count = 0 ;
@@ -198,14 +259,14 @@ ssize_t dfs_seq_read(struct dfs_file *file, void *buf, size_t size, off_t *pos)
198
259
goto Enomem ;
199
260
p = seq -> ops -> start (seq , & seq -> index );
200
261
}
201
- // EOF or an error
262
+ /* EOF or an error */
202
263
seq -> ops -> stop (seq , p );
203
264
seq -> count = 0 ;
204
265
goto Done ;
205
266
Fill :
206
- // one non-empty record is in the buffer; if they want more,
207
- // try to fit more in, but in any case we need to advance
208
- // the iterator once for every record shown.
267
+ /* one non-empty record is in the buffer; if they want more, */
268
+ /* try to fit more in, but in any case we need to advance */
269
+ /* the iterator once for every record shown. */
209
270
while (1 )
210
271
{
211
272
size_t offs = seq -> count ;
@@ -217,13 +278,13 @@ ssize_t dfs_seq_read(struct dfs_file *file, void *buf, size_t size, off_t *pos)
217
278
LOG_W (".next function %p did not update position index\n" , seq -> ops -> next );
218
279
seq -> index ++ ;
219
280
}
220
- if (!p ) // no next record for us
281
+ if (!p ) /* no next record for us */
221
282
break ;
222
283
if (seq -> count >= size )
223
284
break ;
224
285
err = seq -> ops -> show (seq , p );
225
286
if (err > 0 )
226
- { // ->show() says "skip it"
287
+ { /* ->show() says "skip it" */
227
288
seq -> count = offs ;
228
289
}
229
290
else if (err || dfs_seq_is_full (seq ))
@@ -256,6 +317,17 @@ ssize_t dfs_seq_read(struct dfs_file *file, void *buf, size_t size, off_t *pos)
256
317
goto Done ;
257
318
}
258
319
320
+ /**
321
+ * @brief Reposition the file offset for sequence file
322
+ *
323
+ * @param[in] file Pointer to the file structure
324
+ * @param[in] offset Offset value according to whence
325
+ * @param[in] whence Reference position for offset:
326
+ * - SEEK_SET: from file beginning
327
+ * - SEEK_CUR: from current position
328
+ * @return off_t New file offset on success, negative error code on failure:
329
+ * -EINVAL for invalid parameters
330
+ */
259
331
off_t dfs_seq_lseek (struct dfs_file * file , off_t offset , int whence )
260
332
{
261
333
struct dfs_seq_file * seq = file -> data ;
@@ -295,6 +367,13 @@ off_t dfs_seq_lseek(struct dfs_file *file, off_t offset, int whence)
295
367
return retval ;
296
368
}
297
369
370
+ /**
371
+ * @brief Release resources associated with a sequence file
372
+ *
373
+ * @param[in] file Pointer to the file structure to be released
374
+ *
375
+ * @return int Always returns 0 indicating success
376
+ */
298
377
int dfs_seq_release (struct dfs_file * file )
299
378
{
300
379
struct dfs_seq_file * seq = file -> data ;
@@ -312,6 +391,17 @@ int dfs_seq_release(struct dfs_file *file)
312
391
return 0 ;
313
392
}
314
393
394
+ /**
395
+ * @brief Format and write data to sequence file buffer using variable arguments
396
+ *
397
+ * @param[in,out] seq Pointer to sequence file structure
398
+ * @param[in] f Format string (printf-style)
399
+ * @param[in] args Variable arguments list
400
+ *
401
+ * @details This function:
402
+ * - Formats data using vsnprintf
403
+ * - Triggers overflow if buffer is full
404
+ */
315
405
void dfs_seq_vprintf (struct dfs_seq_file * seq , const char * f , va_list args )
316
406
{
317
407
int len ;
@@ -328,6 +418,13 @@ void dfs_seq_vprintf(struct dfs_seq_file *seq, const char *f, va_list args)
328
418
dfs_seq_overflow (seq );
329
419
}
330
420
421
+ /**
422
+ * @brief Format and print data to sequence file buffer (printf-style)
423
+ *
424
+ * @param[in,out] seq Pointer to sequence file structure
425
+ * @param[in] f Format string (printf-style)
426
+ * @param[in] ... Variable arguments matching format string
427
+ */
331
428
void dfs_seq_printf (struct dfs_seq_file * seq , const char * f , ...)
332
429
{
333
430
va_list args ;
@@ -338,7 +435,10 @@ void dfs_seq_printf(struct dfs_seq_file *seq, const char *f, ...)
338
435
}
339
436
340
437
/**
341
- * write char to buffer
438
+ * @brief Write a single character to sequence file buffer
439
+ *
440
+ * @param[in,out] seq Pointer to sequence file structure
441
+ * @param[in] c Character to be written
342
442
*/
343
443
void dfs_seq_putc (struct dfs_seq_file * seq , char c )
344
444
{
@@ -349,7 +449,10 @@ void dfs_seq_putc(struct dfs_seq_file *seq, char c)
349
449
}
350
450
351
451
/**
352
- * write string to buffer
452
+ * @brief Write a string to sequence file buffer
453
+ *
454
+ * @param[in,out] seq Pointer to sequence file structure
455
+ * @param[in] s Null-terminated string to be written
353
456
*/
354
457
void dfs_seq_puts (struct dfs_seq_file * seq , const char * s )
355
458
{
@@ -365,7 +468,13 @@ void dfs_seq_puts(struct dfs_seq_file *seq, const char *s)
365
468
}
366
469
367
470
/**
368
- * write arbitrary data to buffer
471
+ * @brief Write arbitrary binary data to sequence file buffer
472
+ *
473
+ * @param[in,out] seq Pointer to sequence file structure
474
+ * @param[in] data Pointer to data to be written
475
+ * @param[in] len Length of data in bytes
476
+ *
477
+ * @return int 0 on success, -1 if buffer overflow occurs
369
478
*/
370
479
int dfs_seq_write (struct dfs_seq_file * seq , const void * data , size_t len )
371
480
{
@@ -380,7 +489,10 @@ int dfs_seq_write(struct dfs_seq_file *seq, const void *data, size_t len)
380
489
}
381
490
382
491
/**
383
- * write padding spaces to buffer
492
+ * @brief Pad the sequence file buffer with spaces and optionally append a character
493
+ *
494
+ * @param[in,out] seq Pointer to sequence file structure
495
+ * @param[in] c Optional character to append after padding (if not '\0')
384
496
*/
385
497
void dfs_seq_pad (struct dfs_seq_file * seq , char c )
386
498
{
@@ -401,4 +513,4 @@ void dfs_seq_pad(struct dfs_seq_file *seq, char c)
401
513
{
402
514
dfs_seq_putc (seq , c );
403
515
}
404
- }
516
+ }
0 commit comments