working on avi parsers

This commit is contained in:
2021-02-22 21:08:07 +01:00
parent 2e281f6d26
commit 2b35a340f9
5 changed files with 307 additions and 11 deletions

View File

@@ -31,22 +31,21 @@ public:
uint32_t written = 0;
LBA512 addrLBA = addr / SEC_SIZE; // LBA address
uint16_t offset = (addr - addrLBA*SEC_SIZE);// 0 when addr is SEC_SIZE-byte aligned
uint8_t buf[SEC_SIZE];
while(size) {
if (offset || size < SEC_SIZE) { // non-aligned / non-full-block write
// read the whole sector
if (!readBlock(addrLBA, buf)) {return written;}
if (!readBlockToCache(addrLBA)) {return written;}
// merge in the new data
const uint32_t toModify = min(SEC_SIZE-offset, size);
for (uint16_t i = 0; i < toModify; ++i) {buf[i+offset] = src[i+written];}
for (uint16_t i = 0; i < toModify; ++i) {cache.buf[i+offset] = src[i+written];}
offset = 0;
// write back the modified sector
if (!writeBlock(addrLBA, buf)) {return written;}
if (!writeBlock(addrLBA, cache.buf)) {return written;}
++addrLBA;
size -= toModify;
@@ -57,6 +56,9 @@ public:
// write a full block
if (!writeBlock(addrLBA, &src[written])) {return written;}
// written block was in cache? -> drop
if (addrLBA == cache.lba) {cache.lba = 0xFFFFFFFF;}
++addrLBA;
size -= SEC_SIZE;
written += SEC_SIZE;
@@ -92,7 +94,9 @@ public:
} else { // full block read
if (!readBlock(addrLBA, &dst[read])) {return read;}
//if (!readBlock(addrLBA, &dst[read])) {return read;}
if (!readBlockToCache(addrLBA)) {return read;}
memcpy(&dst[read], cache.buf, SEC_SIZE);
++addrLBA;
size -= SEC_SIZE;
read += SEC_SIZE;
@@ -105,17 +109,27 @@ public:
}
/** read a single block of SEC_SIZE bytes. addr = byteAddr/512 */
bool readBlock(LBA512 addr, uint8_t* dst) {
return dev.readBlock(addr, dst);
struct Cache {
LBA512 lba = 0xFFFFFFFF;
uint8_t buf[SEC_SIZE];
} cache;
/** read a single block of SEC_SIZE bytes into the CACHE. addr = byteAddr/512 */
bool readBlockToCache(LBA512 addr) {
if (cache.lba == addr) {return true;} // already cached
if (dev.readBlock(addr, cache.buf)) {
cache.lba = addr;
return true;
}
return false;
}
/** read a single block of SEC_SIZE bytes. addr = byteAddr/512, write only a fraction of the 512 bytes into dst (skip+len) */
bool readBlock(LBA512 addr, uint8_t* dst, uint16_t skip, uint16_t len) {
uint8_t buf[SEC_SIZE];
if (!dev.readBlock(addr, buf)) {return false;}
if (!readBlockToCache(addr)) {return false;}
for (int i = 0; i < len; ++i) {
*dst = buf[i+skip];
*dst = cache.buf[i+skip];
++dst;
}
return true;