From 13c5188c0198ae45dace6ad80e49b04eeeefa975 Mon Sep 17 00:00:00 2001 From: Pompolic <pompolic@special-circumstanc.es> Date: Fri, 14 Feb 2020 17:52:05 +0100 Subject: [PATCH] Semantic action for a85 group (4 bytes) Also bytes aren't bits --- pdf.c | 38 +++++++++++++++++++++++++++++++------- 1 file changed, 31 insertions(+), 7 deletions(-) diff --git a/pdf.c b/pdf.c index 5c8dc7f..de83c95 100644 --- a/pdf.c +++ b/pdf.c @@ -240,18 +240,42 @@ act_ahextruncated(const HParseResult *p, void *u) HParsedToken * act_a85zero(const HParseResult *p, void *u) { - uint8_t nybble = 0; - /* Remember, this only represents 4 bytes. */ - return H_MAKE_UINT(nybble); + uint8_t b = 0; + return H_MAKE_UINT(b); } HParsedToken * -act_a85digit(const HParseResult *p void *u) +act_a85digit(const HParseResult *p, void *u) { - uint8_t nybble = H_CAST_UINT(p->ast); - nybble -= '!'; + uint8_t b = H_CAST_UINT(p->ast); + b -= '!'; - return H_MAKE_UINT(nybble); + /* At this point we have the base85 value of one byte out of 5 */ + return H_MAKE_UINT(b); +} + +HParsedToken * +act_a85group(const HParseResult *p, void *u) +{ + uint64_t b = 0; + HCountedArray *seq = H_CAST_SEQ(p->ast); + HParsedToken **digits = h_seq_elements(p->ast); + + /* 2^32-1, the max value the group can hold as per spec */ + #define A85GRPMAX 4294967296 + + /* Only for groups that do not need to padded to 5 */ + assert(seq->used == 5); + b += H_CAST_UINT(digits[0]) * ((uint64_t) pow(85,4)); + b += H_CAST_UINT(digits[1]) * ((uint64_t) pow(85,3)); + b += H_CAST_UINT(digits[2]) * ((uint64_t) pow(85,2)); + b += H_CAST_UINT(digits[3]) * ((uint64_t) pow(85,1)); + b += H_CAST_UINT(digits[4]); + + assert(b <= A85GRPMAX); + // TODO: make it generic with H_ACT_APPLY + + return H_MAKE_UINT(b); } HParsedToken * -- GitLab