mirror of
https://github.com/Thesola10/umd-livepatch.git
synced 2025-04-19 22:13:22 +00:00
Implementing command parser
This commit is contained in:
parent
0358242b2d
commit
0d1167ce05
106
umdiff/rdiff.c
106
umdiff/rdiff.c
@ -13,26 +13,120 @@
|
||||
#include <librsync.h>
|
||||
#include <prototab.h>
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
typedef struct {
|
||||
enum rs_op_kind kind;
|
||||
|
||||
uint64_t len;
|
||||
uint64_t copy_offset;
|
||||
} _impl_umdiff_RdiffCommand;
|
||||
|
||||
static size_t
|
||||
_impl_umdiff_RdiffCommand_parse(_impl_umdiff_RdiffCommand *cmd, char *buf, size_t len)
|
||||
{
|
||||
rs_prototab_ent_t entry = rs_prototab[*buf];
|
||||
*cmd = (_impl_umdiff_RdiffCommand) {
|
||||
.kind = entry.kind,
|
||||
.len = entry.immediate,
|
||||
.copy_offset = 0
|
||||
};
|
||||
|
||||
if (entry.kind == RS_KIND_LITERAL && entry.immediate)
|
||||
return 1;
|
||||
|
||||
memcpy(&cmd->len, buf+1, entry.len_1);
|
||||
|
||||
if (entry.kind == RS_KIND_COPY) {
|
||||
memcpy(&cmd->copy_offset, buf+1, entry.len_1);
|
||||
memcpy(&cmd->len, buf+entry.len_1+1, entry.len_2);
|
||||
return entry.len_1 + entry.len_2 + 1;
|
||||
} else {
|
||||
memcpy(&cmd->len, buf+1, entry.len_1);
|
||||
return entry.len_1 + 1;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
_impl_umdiff_File_feedData(umdiff_File *file, char *buf, size_t len)
|
||||
{
|
||||
#define _impl_umdiff_Command_bytesLeft$(x) \
|
||||
((x->patch_start + x->patch_sector_count) * ISO_SECTOR_SIZE - file->data_len)
|
||||
|
||||
umdiff_Command *lastCommand = &file->commands[file->hdr.cmd_count - 1];
|
||||
size_t bytesLeft = _impl_umdiff_Command_bytesLeft$(lastCommand);
|
||||
|
||||
if (bytesLeft > len) {
|
||||
memcpy(file->data + file->data_len, buf, len);
|
||||
file->data_len += len;
|
||||
|
||||
return len;
|
||||
} else {
|
||||
memcpy(file->data + file->data_len, buf, bytesLeft);
|
||||
file->data_len += bytesLeft;
|
||||
|
||||
return bytesLeft;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
umdiff_File_feedCommands(umdiff_File *file, char *buf, size_t len)
|
||||
{
|
||||
umdiff_Command *lastCommand;
|
||||
umdiff_Command *lastCommand, *newCommand;
|
||||
_impl_umdiff_RdiffCommand rdiffCommand;
|
||||
|
||||
int ret, progress = 0;
|
||||
|
||||
//TODO:
|
||||
// 1. skip magic number
|
||||
if (file->hdr.cmd_count == 0 && file->data_len == 0
|
||||
&& (int) *buf == RS_DELTA_MAGIC) {
|
||||
buf += sizeof RS_DELTA_MAGIC;
|
||||
len -= sizeof RS_DELTA_MAGIC;
|
||||
}
|
||||
|
||||
#define _impl_umdiff_Command_isUnfinished$(x) \
|
||||
(x->data_source == 0 \
|
||||
&& (x->patch_start + x->patch_sector_count) > (file->data_len / ISO_SECTOR_SIZE))
|
||||
|
||||
if (file->hdr.cmd_count > 0)
|
||||
lastCommand = &file->commands[file->hdr.cmd_count - 1];
|
||||
|
||||
// 2. Update cmd_len on new command
|
||||
// 3. Update data_len otherwise
|
||||
// 4. If data_len < last command's patch area: complete data
|
||||
while (len) {
|
||||
if (_impl_umdiff_Command_isUnfinished$(lastCommand)) {
|
||||
ret = _impl_umdiff_File_feedData(file, buf, len);
|
||||
buf += ret;
|
||||
len -= ret;
|
||||
progress += ret;
|
||||
|
||||
if (len <= 0) break;
|
||||
}
|
||||
|
||||
ret = _impl_umdiff_RdiffCommand_parse(&rdiffCommand, buf, len);
|
||||
len -= ret;
|
||||
buf += ret;
|
||||
progress += ret;
|
||||
|
||||
if (rdiffCommand.len % ISO_SECTOR_SIZE
|
||||
|| rdiffCommand.copy_offset % ISO_SECTOR_SIZE) {
|
||||
dprintf(1, "Misaligned command!\n");
|
||||
exit(4);
|
||||
}
|
||||
|
||||
newCommand = &file->commands[file->hdr.cmd_count];
|
||||
file->hdr.cmd_count += 1;
|
||||
|
||||
newCommand->data_source = (rdiffCommand.kind == RS_KIND_COPY);
|
||||
newCommand->sector_start = lastCommand->sector_start + lastCommand->sector_count;
|
||||
newCommand->sector_count = rdiffCommand.len / ISO_SECTOR_SIZE;
|
||||
newCommand->patch_sector_count = rdiffCommand.len / ISO_SECTOR_SIZE;
|
||||
newCommand->patch_start = (rdiffCommand.kind == RS_KIND_COPY)
|
||||
? (rdiffCommand.copy_offset / ISO_SECTOR_SIZE)
|
||||
: (file->data_len / ISO_SECTOR_SIZE);
|
||||
|
||||
lastCommand = newCommand;
|
||||
}
|
||||
|
||||
return progress;
|
||||
}
|
||||
|
||||
// vim: ft=c.doxygen
|
||||
|
Loading…
x
Reference in New Issue
Block a user