#include #include #define Z_EROFS_LI_D0_CBLKCNT 0x800U #define Z_EROFS_LCLUSTER_TYPE_NONHEAD 2U static unsigned int compact_head_nblocks(const uint16_t *values, const uint8_t *types, int index) { unsigned int blocks, value; blocks = 0; while (index > 0) { --index; value = values[index]; if (types[index] == Z_EROFS_LCLUSTER_TYPE_NONHEAD) { if ((value & Z_EROFS_LI_D0_CBLKCNT) != 0) { --index; blocks += value & ~Z_EROFS_LI_D0_CBLKCNT; continue; } if (value <= 1) return (UINT32_MAX); index -= value - 2; continue; } ++blocks; } return (blocks); } int main(void) { uint16_t values[16] = { 0 }; uint8_t types[16] = { 0 }; unsigned int blocks; values[0] = Z_EROFS_LI_D0_CBLKCNT | 1U; types[0] = Z_EROFS_LCLUSTER_TYPE_NONHEAD; values[4] = 5U; types[4] = Z_EROFS_LCLUSTER_TYPE_NONHEAD; blocks = compact_head_nblocks(values, types, 5); if (blocks != 1U) { fprintf(stderr, "compact HEAD finalization blocks=%u expected=1\n", blocks); return (1); } return (0); }