Added lfsr_data_add for more lfsr_data_t manipulation

Also fixed an internal (currently unreachable) bug in lfs_bd_cmp where
the hint could underflow if zero.
This commit is contained in:
Christopher Haster
2023-04-25 01:58:42 -05:00
parent 59552e8f1e
commit c83d8b7abc
+45 -28
View File
@@ -164,6 +164,8 @@ static int lfs_bd_cmp(lfs_t *lfs,
const void *buffer, lfs_size_t size) {
const uint8_t *data = buffer;
lfs_size_t diff = 0;
// make sure our hint is at least as big as our buffer
hint = lfs_max(hint, size);
for (lfs_off_t i = 0; i < size; i += diff) {
uint8_t dat[8];
@@ -1000,6 +1002,21 @@ static inline lfs_size_t lfsr_data_setondisk(lfs_size_t size) {
return size | 0x80000000;
}
static lfsr_data_t lfsr_data_add(lfsr_data_t data, lfs_off_t off) {
// limit our off to data range
lfs_off_t off_ = lfs_min32(off, lfsr_data_size(data));
if (lfsr_data_ondisk(data)) {
data.disk.off += off_;
data.disk.size -= off_;
} else {
data.buf.buffer += off_;
data.buf.size -= off_;
}
return data;
}
// data<->bd interactions
static lfs_ssize_t lfsr_data_read(lfs_t *lfs, lfsr_data_t data,
lfs_off_t off, void *buffer, lfs_size_t size) {
@@ -1023,6 +1040,34 @@ static lfs_ssize_t lfsr_data_read(lfs_t *lfs, lfsr_data_t data,
return size_;
}
static lfs_ssize_t lfsr_data_readle32(lfs_t *lfs, lfsr_data_t data,
lfs_off_t off, uint32_t *word) {
lfs_ssize_t d = lfsr_data_read(lfs, data, off, word, sizeof(uint32_t));
if (d < 0) {
return d;
}
// truncated?
if ((lfs_size_t)d < sizeof(uint32_t)) {
return LFS_ERR_CORRUPT;
}
*word = lfs_fromle32_(word);
return sizeof(uint32_t);
}
static lfs_ssize_t lfsr_data_readleb128(lfs_t *lfs, lfsr_data_t data,
lfs_off_t off, uint32_t *word) {
// for 32-bits we can assume worst-case leb128 size is 5-bytes
uint8_t buf[5];
lfs_ssize_t d = lfsr_data_read(lfs, data, off, buf, 5);
if (d < 0) {
return d;
}
return lfs_fromleb128(word, buf, d);
}
static int lfsr_data_cmp(lfs_t *lfs, lfsr_data_t data,
lfs_off_t off, const void *buffer, lfs_size_t size,
int *cmp) {
@@ -1053,34 +1098,6 @@ static int lfsr_data_cmp(lfs_t *lfs, lfsr_data_t data,
return 0;
}
static lfs_ssize_t lfsr_data_readle32(lfs_t *lfs, lfsr_data_t data,
lfs_off_t off, uint32_t *word) {
lfs_ssize_t d = lfsr_data_read(lfs, data, off, word, sizeof(uint32_t));
if (d < 0) {
return d;
}
// truncated?
if ((lfs_size_t)d < sizeof(uint32_t)) {
return LFS_ERR_CORRUPT;
}
*word = lfs_fromle32_(word);
return sizeof(uint32_t);
}
static lfs_ssize_t lfsr_data_readleb128(lfs_t *lfs, lfsr_data_t data,
lfs_off_t off, uint32_t *word) {
// for 32-bits we can assume worst-case leb128 size is 5-bytes
uint8_t buf[5];
lfs_ssize_t d = lfsr_data_read(lfs, data, off, buf, 5);
if (d < 0) {
return d;
}
return lfs_fromleb128(word, buf, d);
}
static lfs_ssize_t lfsr_bd_progdata(lfs_t *lfs,
lfs_block_t block, lfs_off_t off,
lfsr_data_t data,