Fix bug in new cps code

Fixed some bugs in the write and insert functions of the new cps format
functions, currently available only on libc implementations.
Add unit test to ensure that no regressions happen.

TG-428
pull/68/head
Niccolò Izzo 2022-04-05 16:17:58 +02:00 zatwierdzone przez Silvano Seva
rodzic ae12a2126a
commit 521865f489
3 zmienionych plików z 68 dodań i 48 usunięć

Wyświetl plik

@ -52,31 +52,13 @@ int _writeHeader(cps_header_t header)
int _pushDown(uint32_t offset, uint32_t amount)
{
// Start from the end of the codeplug
cps_header_t header = { 0 };
if (_readHeader(&header))
return -1;
fseek(cps_file,
header.ct_count * sizeof(contact_t) +
header.ch_count * sizeof(channel_t),
SEEK_CUR);
// If banks are present skip those
if (header.b_count != 0) {
fseek(cps_file,
(header.b_count - 1) * sizeof(uint32_t),
SEEK_CUR);
uint32_t b_offset = 0;
bankHdr_t b_header = { 0 };
fread(&b_offset, sizeof(uint32_t), 1, cps_file);
fseek(cps_file, b_offset, SEEK_CUR);
fread(&b_header, sizeof(bankHdr_t), 1, cps_file);
fseek(cps_file, b_header.ch_count * sizeof(uint32_t), SEEK_CUR);
}
// Move data downwards in chunks of fixed size
// Get end of file
fseek(cps_file, 0, SEEK_END);
long end = ftell(cps_file);
// If offset equals end, just return
if (offset == end)
return 0;
// Move data downwards in chunks of fixed size
char buffer[CPS_CHUNK_SIZE] = { 0 };
for(int i = 1; i <= ((end - offset) / CPS_CHUNK_SIZE); i++)
{
@ -162,6 +144,51 @@ int _updateChNumbering(uint16_t pos, bool add)
return 0;
}
/**
* Internal: get bank data offset
*
* @param pos: position of the bank to be read
* @return the offset in the file where the bank data is stored, -1 if error
*/
long _getBankDataOffset(uint16_t pos)
{
cps_header_t header = { 0 };
if (_readHeader(&header))
return -1;
if (pos >= header.b_count + 1)
return -1;
if (pos == header.b_count)
{
// No bank is present, no offset to read
if (header.b_count == 0)
return ftell(cps_file) +
header.ct_count * sizeof(contact_t) +
header.ch_count * sizeof(channel_t) +
sizeof(uint32_t);
// Read last bank offset
fseek(cps_file,
header.ct_count * sizeof(contact_t) +
header.ch_count * sizeof(channel_t) +
(header.b_count - 1) * sizeof(uint32_t),
SEEK_CUR);
uint32_t offset = 0;
fread(&offset, sizeof(uint32_t), 1, cps_file);
long bdata_pos = ftell(cps_file);
bankHdr_t last_bank = { 0 };
cps_readBankHeader(&last_bank, header.b_count - 1);
return bdata_pos + offset + sizeof(bankHdr_t) + last_bank.ch_count * sizeof(uint32_t);
}
fseek(cps_file,
header.ct_count * sizeof(contact_t) +
header.ch_count * sizeof(channel_t) +
pos * sizeof(uint32_t),
SEEK_CUR);
uint32_t offset = 0;
fread(&offset, sizeof(uint32_t), 1, cps_file);
return ftell(cps_file) +
(header.b_count - pos - 1) * sizeof(uint32_t) +
offset;
}
int cps_open(char *cps_name)
{
@ -244,7 +271,7 @@ int cps_readBankHeader(bankHdr_t *b_header, uint16_t pos)
SEEK_CUR);
uint32_t offset = 0;
fread(&offset, sizeof(uint32_t), 1, cps_file);
fseek(cps_file, (header.b_count - pos) * sizeof(uint32_t) + offset, SEEK_CUR);
fseek(cps_file, (header.b_count - pos - 1) * sizeof(uint32_t) + offset, SEEK_CUR);
fread(b_header, sizeof(bankHdr_t), 1, cps_file);
return 0;
}
@ -263,7 +290,7 @@ int32_t cps_readBankData(uint16_t bank_pos, uint16_t pos)
SEEK_CUR);
uint32_t offset = 0;
fread(&offset, sizeof(uint32_t), 1, cps_file);
fseek(cps_file, header.b_count - bank_pos * sizeof(uint32_t) + offset, SEEK_CUR);
fseek(cps_file, (header.b_count - bank_pos - 1) * sizeof(uint32_t) + offset, SEEK_CUR);
bankHdr_t b_header = { 0 };
fread(&b_header, sizeof(bankHdr_t), 1, cps_file);
if (pos >= b_header.ch_count)
@ -334,7 +361,7 @@ int cps_writeBankData(uint32_t ch, uint16_t bank_pos, uint16_t pos)
SEEK_CUR);
uint32_t offset = 0;
fread(&offset, sizeof(uint32_t), 1, cps_file);
fseek(cps_file, header.b_count - bank_pos * sizeof(uint32_t) + offset, SEEK_CUR);
fseek(cps_file, (header.b_count - bank_pos - 1) * sizeof(uint32_t) + offset, SEEK_CUR);
bankHdr_t b_header = { 0 };
fread(&b_header, sizeof(bankHdr_t), 1, cps_file);
if (pos >= b_header.ch_count)
@ -386,16 +413,14 @@ int cps_insertBankHeader(bankHdr_t b_header, uint16_t pos)
return -1;
if (pos >= header.b_count + 1)
return -1;
// Read old offset
uint32_t b_offset = 0;
fseek(cps_file,
header.ct_count * sizeof(contact_t) +
header.ch_count * sizeof(channel_t) +
pos * sizeof(uint32_t),
SEEK_CUR);
long b_offset_pos = ftell(cps_file);
fread(&b_offset, sizeof(uint32_t), 1, cps_file);
// Write new offset
uint32_t b_offset = _getBankDataOffset(pos) - _getBankDataOffset(0);
// Read position of the new offset
_pushDown(b_offset_pos, sizeof(uint32_t));
fwrite(&b_offset, sizeof(uint32_t), 1, cps_file);
// Update all the offsets following the moved bank
@ -408,13 +433,10 @@ int cps_insertBankHeader(bankHdr_t b_header, uint16_t pos)
o += sizeof(bankHdr_t);
fwrite(&o, sizeof(uint32_t), 1, cps_file);
}
// Write new bank
fseek(cps_file, b_offset, SEEK_CUR);
long h_pos = ftell(cps_file);
_pushDown(h_pos, sizeof(bankHdr_t));
fwrite(&b_header, sizeof(bankHdr_t), 1, cps_file);
header.b_count++;
_writeHeader(header);
_pushDown(_getBankDataOffset(pos), sizeof(bankHdr_t));
fwrite(&b_header, sizeof(bankHdr_t), 1, cps_file);
return 0;
}
@ -423,7 +445,7 @@ int cps_insertBankData(uint32_t ch, uint16_t bank_pos, uint16_t pos)
cps_header_t header = { 0 };
if (_readHeader(&header))
return -1;
if (bank_pos >= header.b_count + 1)
if (bank_pos >= header.b_count)
return -1;
fseek(cps_file,
header.ct_count * sizeof(contact_t) +

Wyświetl plik

@ -538,25 +538,24 @@ bool _ui_drawDarkOverlay() {
return true;
}
int _ui_fsm_loadChannel(uint16_t channel_index, bool *sync_rtx) {
int _ui_fsm_loadChannel(int16_t channel_index, bool *sync_rtx) {
channel_t channel;
int32_t selected_channel = channel_index;
// If a bank is active, get index from current bank
if(state.bank_enabled)
{
bankHdr_t bank = { 0 };
cps_readBankHeader(&bank, state.bank);
if((channel_index <= 0) || (channel_index > bank.ch_count))
if((channel_index < 0) || (channel_index >= bank.ch_count))
return -1;
else
// Channel index is 1-based while bank array access is 0-based
channel_index = cps_readBankData(state.bank, channel_index);
channel_index = cps_readBankData(state.bank, channel_index);
}
int result = cps_readChannel(&channel, channel_index);
// Read successful and channel is valid
if(result != -1 && _ui_channel_valid(&channel))
{
// Set new channel index
state.channel_index = channel_index;
state.channel_index = selected_channel;
// Copy channel read to state
state.channel = channel;
*sync_rtx = true;
@ -1349,7 +1348,7 @@ void ui_updateFSM(event_t event, bool *sync_rtx)
if(ui_state.last_main_state == MAIN_VFO)
state.vfo_channel = state.channel;
// Load bank first channel
_ui_fsm_loadChannel(1, sync_rtx);
_ui_fsm_loadChannel(0, sync_rtx);
// Switch to MEM screen
state.ui_screen = MAIN_MEM;
}

Wyświetl plik

@ -117,7 +117,6 @@ int test_createComplexCPS() {
cps_insertBankData(2, 1, 0);
cps_insertBankData(3, 1, 1);
cps_insertBankData(4, 1, 2);
cps_insertBankData(5, 1, 3);
cps_close();
return 0;
}
@ -135,20 +134,20 @@ int test_createOOOCPS() {
channel_t ch5 = { M17, 0, 0, 0, 0, 0, 0, 0, 0, "Test channel 5", "", {0}, {{0}} };
bankHdr_t b1 = { "Test Bank 1", 0 };
bankHdr_t b2 = { "Test Bank 2", 0 };
cps_insertContact(ct2, 0);
cps_insertContact(ct1, 0);
cps_insertBankHeader(b2, 0);
cps_insertContact(ct2, 1);
cps_insertBankHeader(b1, 0);
cps_insertBankHeader(b2, 1);
cps_insertChannel(ch5, 0);
cps_insertBankData(0, 0, 0);
cps_insertBankData(0, 1, 0);
cps_insertChannel(ch4, 0);
cps_insertBankData(0, 0, 1);
cps_insertBankData(0, 1, 0);
cps_insertChannel(ch3, 0);
cps_insertBankData(0, 1, 0);
cps_insertChannel(ch2, 0);
cps_insertBankData(0, 1, 1);
cps_insertBankData(0, 0, 0);
cps_insertChannel(ch1, 0);
cps_insertBankData(0, 1, 2);
cps_insertBankData(0, 0, 0);
cps_close();
return 0;
}