* @brief Traverse sequence file data with specified offset * * This function traverses the sequence file data starting from the specified offset. * It handles buffer overflow conditions by dynamically resizing the buffer when needed. * * @param[in,out] seq Pointer to sequence file structure * @param[in] offset Position to start traversing from * * @return int 0 on success, negative error c
| 97 | * @note Data output loop: start() -> show() -> next() -> show() -> ... -> next() -> stop() |
| 98 | */ |
| 99 | static int dfs_seq_traverse(struct dfs_seq_file *seq, off_t offset) |
| 100 | { |
| 101 | off_t pos = 0; |
| 102 | int error = 0; |
| 103 | void *p; |
| 104 | |
| 105 | seq->index = 0; |
| 106 | seq->count = seq->from = 0; |
| 107 | if (!offset) |
| 108 | return 0; |
| 109 | |
| 110 | if (!seq->buf) |
| 111 | { |
| 112 | seq->buf = dfs_seq_alloc(seq->size = PAGE_SIZE); |
| 113 | if (!seq->buf) |
| 114 | return -ENOMEM; |
| 115 | } |
| 116 | p = seq->ops->start(seq, &seq->index); |
| 117 | while (p) |
| 118 | { |
| 119 | error = seq->ops->show(seq, p); |
| 120 | if (error < 0) |
| 121 | break; |
| 122 | if (error) |
| 123 | { |
| 124 | error = 0; |
| 125 | seq->count = 0; |
| 126 | } |
| 127 | if (dfs_seq_is_full(seq)) |
| 128 | goto Eoverflow; |
| 129 | |
| 130 | p = seq->ops->next(seq, p, &seq->index); |
| 131 | if (pos + seq->count > offset) |
| 132 | { |
| 133 | seq->from = offset - pos; |
| 134 | seq->count -= seq->from; |
| 135 | break; |
| 136 | } |
| 137 | pos += seq->count; |
| 138 | seq->count = 0; |
| 139 | if (pos == offset) |
| 140 | break; |
| 141 | } |
| 142 | seq->ops->stop(seq, p); |
| 143 | return error; |
| 144 | |
| 145 | Eoverflow: |
| 146 | seq->ops->stop(seq, p); |
| 147 | rt_free(seq->buf); |
| 148 | seq->count = 0; |
| 149 | seq->buf = dfs_seq_alloc(seq->size <<= 1); |
| 150 | return !seq->buf ? -ENOMEM : -EAGAIN; |
| 151 | } |
| 152 | |
| 153 | /** |
| 154 | * @brief Read data from sequence file |
no test coverage detected