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

package io.netty.util;

import io.netty.util.internal.SWARUtil;
import io.netty.util.internal.PlatformDependent;

final class AsciiStringUtil
{
    static AsciiString toLowerCase(final AsciiString string) {
        final byte[] byteArray = string.array();
        final int offset = string.arrayOffset();
        final int length = string.length();
        if (!containsUpperCase(byteArray, offset, length)) {
            return string;
        }
        final byte[] newByteArray = PlatformDependent.allocateUninitializedArray(length);
        toLowerCase(byteArray, offset, newByteArray);
        return new AsciiString(newByteArray, false);
    }
    
    private static boolean containsUpperCase(final byte[] byteArray, int offset, final int length) {
        if (!PlatformDependent.isUnaligned()) {
            return linearContainsUpperCase(byteArray, offset, length);
        }
        for (int longCount = length >>> 3, i = 0; i < longCount; ++i) {
            final long word = PlatformDependent.getLong(byteArray, offset);
            if (SWARUtil.containsUpperCase(word)) {
                return true;
            }
            offset += 8;
        }
        return unrolledContainsUpperCase(byteArray, offset, length & 0x7);
    }
    
    private static boolean linearContainsUpperCase(final byte[] byteArray, final int offset, final int length) {
        for (int end = offset + length, idx = offset; idx < end; ++idx) {
            if (isUpperCase(byteArray[idx])) {
                return true;
            }
        }
        return false;
    }
    
    private static boolean unrolledContainsUpperCase(final byte[] byteArray, int offset, final int byteCount) {
        assert byteCount >= 0 && byteCount < 8;
        if ((byteCount & 0x4) != 0x0) {
            final int word = PlatformDependent.getInt(byteArray, offset);
            if (SWARUtil.containsUpperCase(word)) {
                return true;
            }
            offset += 4;
        }
        if ((byteCount & 0x2) != 0x0) {
            if (isUpperCase(PlatformDependent.getByte(byteArray, offset))) {
                return true;
            }
            if (isUpperCase(PlatformDependent.getByte(byteArray, offset + 1))) {
                return true;
            }
            offset += 2;
        }
        return (byteCount & 0x1) != 0x0 && isUpperCase(PlatformDependent.getByte(byteArray, offset));
    }
    
    private static void toLowerCase(final byte[] src, final int srcOffset, final byte[] dst) {
        if (!PlatformDependent.isUnaligned()) {
            linearToLowerCase(src, srcOffset, dst);
            return;
        }
        final int length = dst.length;
        final int longCount = length >>> 3;
        int offset = 0;
        for (int i = 0; i < longCount; ++i) {
            final long word = PlatformDependent.getLong(src, srcOffset + offset);
            PlatformDependent.putLong(dst, offset, SWARUtil.toLowerCase(word));
            offset += 8;
        }
        unrolledToLowerCase(src, srcOffset + offset, dst, offset, length & 0x7);
    }
    
    private static void linearToLowerCase(final byte[] src, final int srcOffset, final byte[] dst) {
        for (int i = 0; i < dst.length; ++i) {
            dst[i] = toLowerCase(src[srcOffset + i]);
        }
    }
    
    private static void unrolledToLowerCase(final byte[] src, final int srcPos, final byte[] dst, final int dstOffset, final int byteCount) {
        assert byteCount >= 0 && byteCount < 8;
        int offset = 0;
        if ((byteCount & 0x4) != 0x0) {
            final int word = PlatformDependent.getInt(src, srcPos + offset);
            PlatformDependent.putInt(dst, dstOffset + offset, SWARUtil.toLowerCase(word));
            offset += 4;
        }
        if ((byteCount & 0x2) != 0x0) {
            final short word2 = PlatformDependent.getShort(src, srcPos + offset);
            final short result = (short)(toLowerCase((byte)(word2 >>> 8)) << 8 | toLowerCase((byte)word2));
            PlatformDependent.putShort(dst, dstOffset + offset, result);
            offset += 2;
        }
        if ((byteCount & 0x1) != 0x0) {
            PlatformDependent.putByte(dst, dstOffset + offset, toLowerCase(PlatformDependent.getByte(src, srcPos + offset)));
        }
    }
    
    static AsciiString toUpperCase(final AsciiString string) {
        final byte[] byteArray = string.array();
        final int offset = string.arrayOffset();
        final int length = string.length();
        if (!containsLowerCase(byteArray, offset, length)) {
            return string;
        }
        final byte[] newByteArray = PlatformDependent.allocateUninitializedArray(length);
        toUpperCase(byteArray, offset, newByteArray);
        return new AsciiString(newByteArray, false);
    }
    
    private static boolean containsLowerCase(final byte[] byteArray, int offset, final int length) {
        if (!PlatformDependent.isUnaligned()) {
            return linearContainsLowerCase(byteArray, offset, length);
        }
        for (int longCount = length >>> 3, i = 0; i < longCount; ++i) {
            final long word = PlatformDependent.getLong(byteArray, offset);
            if (SWARUtil.containsLowerCase(word)) {
                return true;
            }
            offset += 8;
        }
        return unrolledContainsLowerCase(byteArray, offset, length & 0x7);
    }
    
    private static boolean linearContainsLowerCase(final byte[] byteArray, final int offset, final int length) {
        for (int end = offset + length, idx = offset; idx < end; ++idx) {
            if (isLowerCase(byteArray[idx])) {
                return true;
            }
        }
        return false;
    }
    
    private static boolean unrolledContainsLowerCase(final byte[] byteArray, int offset, final int byteCount) {
        assert byteCount >= 0 && byteCount < 8;
        if ((byteCount & 0x4) != 0x0) {
            final int word = PlatformDependent.getInt(byteArray, offset);
            if (SWARUtil.containsLowerCase(word)) {
                return true;
            }
            offset += 4;
        }
        if ((byteCount & 0x2) != 0x0) {
            if (isLowerCase(PlatformDependent.getByte(byteArray, offset))) {
                return true;
            }
            if (isLowerCase(PlatformDependent.getByte(byteArray, offset + 1))) {
                return true;
            }
            offset += 2;
        }
        return (byteCount & 0x1) != 0x0 && isLowerCase(PlatformDependent.getByte(byteArray, offset));
    }
    
    private static void toUpperCase(final byte[] src, final int srcOffset, final byte[] dst) {
        if (!PlatformDependent.isUnaligned()) {
            linearToUpperCase(src, srcOffset, dst);
            return;
        }
        final int length = dst.length;
        final int longCount = length >>> 3;
        int offset = 0;
        for (int i = 0; i < longCount; ++i) {
            final long word = PlatformDependent.getLong(src, srcOffset + offset);
            PlatformDependent.putLong(dst, offset, SWARUtil.toUpperCase(word));
            offset += 8;
        }
        unrolledToUpperCase(src, srcOffset + offset, dst, offset, length & 0x7);
    }
    
    private static void linearToUpperCase(final byte[] src, final int srcOffset, final byte[] dst) {
        for (int i = 0; i < dst.length; ++i) {
            dst[i] = toUpperCase(src[srcOffset + i]);
        }
    }
    
    private static void unrolledToUpperCase(final byte[] src, final int srcOffset, final byte[] dst, final int dstOffset, final int byteCount) {
        assert byteCount >= 0 && byteCount < 8;
        int offset = 0;
        if ((byteCount & 0x4) != 0x0) {
            final int word = PlatformDependent.getInt(src, srcOffset + offset);
            PlatformDependent.putInt(dst, dstOffset + offset, SWARUtil.toUpperCase(word));
            offset += 4;
        }
        if ((byteCount & 0x2) != 0x0) {
            final short word2 = PlatformDependent.getShort(src, srcOffset + offset);
            final short result = (short)(toUpperCase((byte)(word2 >>> 8)) << 8 | toUpperCase((byte)word2));
            PlatformDependent.putShort(dst, dstOffset + offset, result);
            offset += 2;
        }
        if ((byteCount & 0x1) != 0x0) {
            PlatformDependent.putByte(dst, dstOffset + offset, toUpperCase(PlatformDependent.getByte(src, srcOffset + offset)));
        }
    }
    
    private static boolean isLowerCase(final byte value) {
        return value >= 97 && value <= 122;
    }
    
    static boolean isUpperCase(final byte value) {
        return value >= 65 && value <= 90;
    }
    
    static byte toLowerCase(final byte value) {
        return isUpperCase(value) ? ((byte)(value + 32)) : value;
    }
    
    static byte toUpperCase(final byte value) {
        return isLowerCase(value) ? ((byte)(value - 32)) : value;
    }
    
    private AsciiStringUtil() {
    }
}
