Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- n_t Sm::decompress(byte_t* dest, Reader& r)
- try
- {
- const byte_t* const begin_dest(dest), *const end_dest(dest + capacity);
- for (;;)
- {
- byte_t byte(r.READ());
- if (byte == 0xFF)
- break;
- unsigned size(1), type(byte >> 5);
- if (type != 7)
- size += byte & 0x1F;
- else
- {
- type = byte >> 2 & 7;
- size += (byte & 3) << 8 | r.READ();
- }
- switch (type)
- {
- // Direct copy
- case 0:
- r.READ(dest, size);
- break;
- // Byte fill
- case 1:
- std::fill_n(dest, size, r.READ());
- break;
- // Word fill
- case 2:
- {
- std::array<byte_t, 2> filler{r.READ(), r.READ()};
- for (index_t i{}; i < size; ++i)
- dest[i] = filler[i & 1];
- break;
- }
- // Incrementing fill
- case 3:
- std::iota(dest, dest + size, r.READ());
- break;
- // Dictionary copy
- case 4:
- {
- // Note that std::copy/memcpy with overlapping ranges is UB
- word_t offset(r.get<word_t>());
- for (index_t i{}; i < size; ++i)
- dest[i] = begin_dest[offset + i];
- break;
- }
- // Inverted dictionary copy
- case 5:
- {
- word_t offset(r.get<word_t>());
- for (index_t i{}; i < size; ++i)
- dest[i] = ~begin_dest[offset + i];
- break;
- }
- // Sliding dictionary copy
- case 6:
- {
- // Note that std::copy/memcpy with overlapping ranges is UB
- byte_t offset(r.READ());
- for (index_t i{}; i < size; ++i)
- dest[i] = dest[i - offset];
- break;
- }
- // Inverted sliding dictionary copy
- case 7:
- {
- byte_t offset(r.READ());
- for (index_t i{}; i < size; ++i)
- dest[i] = ~dest[i - offset];
- break;
- }
- }
- dest += size;
- }
- return dest - begin_dest;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement