// 
// Decompiled by Procyon v0.6.0
// 

package io.netty.handler.codec.compression;

import io.netty.util.internal.PlatformDependent;
import java.nio.ByteBuffer;
import java.util.zip.Adler32;
import java.util.zip.CRC32;
import io.netty.buffer.ByteBuf;
import io.netty.util.internal.ObjectUtil;
import io.netty.util.ByteProcessor;
import java.util.zip.Checksum;

abstract class ByteBufChecksum implements Checksum
{
    private final ByteProcessor updateProcessor;
    
    ByteBufChecksum() {
        this.updateProcessor = new ByteProcessor() {
            @Override
            public boolean process(final byte value) throws Exception {
                ByteBufChecksum.this.update(value);
                return true;
            }
        };
    }
    
    static ByteBufChecksum wrapChecksum(final Checksum checksum) {
        ObjectUtil.checkNotNull(checksum, "checksum");
        if (checksum instanceof ByteBufChecksum) {
            return (ByteBufChecksum)checksum;
        }
        return new JdkByteBufChecksum(checksum);
    }
    
    public void update(final ByteBuf b, final int off, final int len) {
        if (b.hasArray()) {
            this.update(b.array(), b.arrayOffset() + off, len);
        }
        else {
            b.forEachByte(off, len, this.updateProcessor);
        }
    }
    
    private static class JdkByteBufChecksum extends ByteBufChecksum
    {
        protected final Checksum checksum;
        private byte[] scratchBuffer;
        
        JdkByteBufChecksum(final Checksum checksum) {
            this.checksum = checksum;
        }
        
        @Override
        public void update(final int b) {
            this.checksum.update(b);
        }
        
        @Override
        public void update(final ByteBuf b, final int off, final int len) {
            if (b.hasArray()) {
                this.update(b.array(), b.arrayOffset() + off, len);
            }
            else if (this.checksum instanceof CRC32) {
                final ByteBuffer byteBuffer = this.getSafeBuffer(b, off, len);
                ((CRC32)this.checksum).update(byteBuffer);
            }
            else if (this.checksum instanceof Adler32) {
                final ByteBuffer byteBuffer = this.getSafeBuffer(b, off, len);
                ((Adler32)this.checksum).update(byteBuffer);
            }
            else {
                super.update(b, off, len);
            }
        }
        
        private ByteBuffer getSafeBuffer(final ByteBuf b, final int off, final int len) {
            final ByteBuffer byteBuffer = CompressionUtil.safeNioBuffer(b, off, len);
            final int javaVersion = PlatformDependent.javaVersion();
            if (javaVersion >= 22 && javaVersion < 25 && byteBuffer.isDirect()) {
                if (this.scratchBuffer == null || this.scratchBuffer.length < len) {
                    this.scratchBuffer = new byte[len];
                }
                final ByteBuffer copy = ByteBuffer.wrap(this.scratchBuffer, 0, len);
                copy.put(byteBuffer).flip();
                return copy;
            }
            return byteBuffer;
        }
        
        @Override
        public void update(final byte[] b, final int off, final int len) {
            this.checksum.update(b, off, len);
        }
        
        @Override
        public long getValue() {
            return this.checksum.getValue();
        }
        
        @Override
        public void reset() {
            this.checksum.reset();
        }
    }
}
