blob: 9d472a228c4eabc6bf97edeb6bfb6ea9f22b47fc [file] [log] [blame]
// Copyright 2022 The Wuffs Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
pri func decoder.flush_fast!(dst: base.io_writer) {
var flush_pointer : base.u32[..= 1_048575]
var flush_repeat_count : base.u32[..= 255]
var flush_prev : base.u8
var block_checksum_have : base.u32
var block_size : base.u32
var entry : base.u32
var curr : base.u8
flush_pointer = this.flush_pointer
flush_repeat_count = this.flush_repeat_count
flush_prev = this.flush_prev
block_checksum_have = this.block_checksum_have
block_size = this.block_size
while (block_size > 0) and (args.dst.length() >= 255) {
if flush_repeat_count < 4 {
entry = this.bwt[flush_pointer]
curr = (entry & 0xFF) as base.u8
flush_pointer = entry >> 12
if curr == flush_prev {
flush_repeat_count += 1
} else {
flush_repeat_count = 1
}
block_checksum_have =
REV_CRC32_TABLE[((block_checksum_have >> 24) as base.u8) ^ curr] ^
(block_checksum_have ~mod<< 8)
args.dst.write_u8_fast!(a: curr)
flush_prev = curr
block_size -= 1
} else {
entry = this.bwt[flush_pointer]
curr = (entry & 0xFF) as base.u8
flush_pointer = entry >> 12
flush_repeat_count = curr as base.u32
while flush_repeat_count > 0,
inv block_size > 0,
{
block_checksum_have =
REV_CRC32_TABLE[((block_checksum_have >> 24) as base.u8) ^ flush_prev] ^
(block_checksum_have ~mod<< 8)
if args.dst.length() > 0 {
args.dst.write_u8_fast!(a: flush_prev)
}
flush_repeat_count -= 1
} endwhile
flush_repeat_count = 0
flush_prev = curr
block_size -= 1
}
} endwhile
this.flush_pointer = flush_pointer
this.flush_repeat_count = flush_repeat_count
this.flush_prev = flush_prev
this.block_checksum_have = block_checksum_have
if block_size <= 900000 {
this.block_size = block_size
}
}