// File: /workspace/github_c_makefile_star2_O3/sszllzss[P]webSocket_Libevent_ThreadPool/websocket_common.c
// Function: webSocket_dePackage(unsigned char*, unsigned int, unsigned char*, unsigned int, unsigned int*)
int webSocket_dePackage(unsigned char *data, unsigned int dataLen, unsigned char *package, unsigned int packageMaxLen, unsigned int *packageLen)
{
    unsigned char maskKey[4] = {0};    // 掩码
    unsigned char temp1, temp2;
    char Mask = 0, type;
    int count, ret;
    unsigned int i, len = 0, dataStart = 2;
    if(dataLen < 2)
        return -1;

    type = data[0]&0x0F;

    if((data[0]&0x80) == 0x80)
    {
        if(type == 0x01) 
            ret = WCT_TXTDATA;
        else if(type == 0x02) 
            ret = WCT_BINDATA;
        else if(type == 0x08) 
            ret = WCT_DISCONN;
        else if(type == 0x09) 
            ret = WCT_PING;
        else if(type == 0x0A) 
            ret = WCT_PONG;
        else 
            return WCT_ERR;
    }
    else if(type == 0x00) 
        ret = WCT_MINDATA;
    else
        return WCT_ERR;
    //
    if((data[1] & 0x80) == 0x80)
    {
        Mask = 1;
        count = 4;
    }
    else
    {
        Mask = 0;
        count = 0;
    }
    //
    len = data[1] & 0x7F;
    //
    if(len == 126)
    {
        if(dataLen < 4)
            return WCT_ERR;
        len = data[2];
        len = (len << 8) + data[3];
        if(dataLen < len + 4 + count)
            return WCT_ERR;
        if(Mask)
        {
            maskKey[0] = data[4];
            maskKey[1] = data[5];
            maskKey[2] = data[6];
            maskKey[3] = data[7];
            dataStart = 8;
        }
        else
            dataStart = 4;
    }
    else if(len == 127)
    {
        if(dataLen < 10)
            return WCT_ERR;
        if(data[2] != 0 || data[3] != 0 || data[4] != 0 || data[5] != 0)    // 使用8个字节存储长度时, 前4位必须为0, 装不下那么多数据...
            return WCT_ERR;
        len = data[6];
        len = (len << 8) + data[7];
        len = (len << 8) + data[8];
        len = (len << 8) + data[9];
        if(dataLen < len + 10 + count)
            return WCT_ERR;
        if(Mask)
        {
            maskKey[0] = data[10];
            maskKey[1] = data[11];
            maskKey[2] = data[12];
            maskKey[3] = data[13];
            dataStart = 14;
        }
        else
            dataStart = 10;
    }
    else
    {
        if(dataLen < len + 2 + count)
            return WCT_ERR;
        if(Mask)
        {
            maskKey[0] = data[2];
            maskKey[1] = data[3];
            maskKey[2] = data[4];
            maskKey[3] = data[5];
            dataStart = 6;
        }
        else
            dataStart = 2;
    }
    //
    if(dataLen < len + dataStart)
        return WCT_ERR;
    //
    if(packageMaxLen < len + 1)
        return WCT_ERR;
    //
    if(Mask)    // 解包数据使用掩码时, 使用异或解码, maskKey[4]依次和数据异或运算, 逻辑如下
    {
        //printf("depackage : len/%d\r\n", len);
        for(i = 0, count = 0; i < len; i++)
        {
            temp1 = maskKey[count];
            temp2 = data[i + dataStart];
            *package++ =  (char)(((~temp1)&temp2) | (temp1&(~temp2)));  // 异或运算后得到数据
            count += 1;
            if((unsigned)count >= sizeof(maskKey))    // maskKey[4]循环使用
                count = 0;
            //printf("%.2X|%.2X|%.2X, ", temp1, temp2, *(package-1));
        }
        *package = '\0';
    }
    else    // 解包数据没使用掩码, 直接复制数据段
    {
        memcpy(package, &data[dataStart], len);
        package[len] = '\0';
    }
    *packageLen = len;
    //
    return ret;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
pushq %rax
movl $0x0, -0x2c(%rbp)
movl $0xffffffff, %eax       # imm = 0xFFFFFFFF
cmpl $0x2, %esi
jb 0x2eec
movq %r8, %rbx
movq %rdx, %r14
movq %rdi, %rdx
movb (%rdi), %r8b
movl %r8d, %edi
andb $0xf, %dil
testb %r8b, %r8b
js 0x2d01
testb %dil, %dil
jne 0x2eec
movl $0xffffffec, %r12d      # imm = 0xFFFFFFEC
jmp 0x2d2d
decb %dil
cmpb $0xa, %dil
jae 0x2eec
movzbl %dil, %edi
movl $0x383, %r8d            # imm = 0x383
btl %edi, %r8d
jae 0x2eec
leaq 0x27bf(%rip), %r8       # 0x54e8
movl (%r8,%rdi,4), %r12d
movzbl 0x1(%rdx), %edi
movl %edi, %r8d
shrl $0x5, %r8d
andl $-0x4, %r8d
movl %edi, %r13d
andl $0x7f, %r13d
cmpl $0x7f, %r13d
je 0x2dae
cmpl $0x7e, %r13d
jne 0x2e23
cmpl $0x4, %esi
jb 0x2eec
movzwl 0x2(%rdx), %r9d
rolw $0x8, %r9w
movzwl %r9w, %r13d
addl %r13d, %r8d
addl $0x4, %r8d
cmpl %esi, %r8d
ja 0x2eec
movl $0x4, %r8d
testb %dil, %dil
jns 0x2e76
movb 0x4(%rdx), %r8b
movb %r8b, -0x2c(%rbp)
movl $0x8, %r8d
movl $0x7, %r9d
movl $0x6, %r10d
movl $0x5, %r11d
jmp 0x2e5e
cmpl $0xa, %esi
jb 0x2eec
cmpb $0x0, 0x2(%rdx)
jne 0x2eec
cmpb $0x0, 0x3(%rdx)
jne 0x2eec
cmpb $0x0, 0x4(%rdx)
jne 0x2eec
cmpb $0x0, 0x5(%rdx)
jne 0x2eec
movl 0x6(%rdx), %r13d
bswapl %r13d
addl %r13d, %r8d
addl $0xa, %r8d
cmpl %esi, %r8d
ja 0x2eec
movl $0xa, %r8d
testb %dil, %dil
jns 0x2e76
movb 0xa(%rdx), %r8b
movb %r8b, -0x2c(%rbp)
movl $0xe, %r8d
movl $0xd, %r9d
movl $0xc, %r10d
movl $0xb, %r11d
jmp 0x2e5e
addl %r13d, %r8d
addl $0x2, %r8d
cmpl %esi, %r8d
ja 0x2eec
movl $0x2, %r8d
testb %dil, %dil
jns 0x2e76
movb 0x2(%rdx), %r8b
movb %r8b, -0x2c(%rbp)
movl $0x6, %r8d
movl $0x5, %r9d
movl $0x4, %r10d
movl $0x3, %r11d
movb (%rdx,%r11), %r11b
movb %r11b, -0x2b(%rbp)
movb (%rdx,%r10), %r10b
movb %r10b, -0x2a(%rbp)
movb (%rdx,%r9), %r9b
movb %r9b, -0x29(%rbp)
leal (%r8,%r13), %r9d
cmpl %esi, %r9d
seta %sil
leal 0x1(%r13), %r9d
cmpl %ecx, %r9d
seta %cl
orb %sil, %cl
jne 0x2eec
testb %dil, %dil
js 0x2eb1
movl %r8d, %eax
addq %rax, %rdx
movl %r13d, %r15d
movq %r14, %rdi
movq %rdx, %rsi
movq %r15, %rdx
callq 0x2180
addq %r15, %r14
jmp 0x2ee2
testl %r13d, %r13d
je 0x2ee2
movl %r13d, %eax
xorl %ecx, %ecx
xorl %esi, %esi
movslq %esi, %rsi
movl %r8d, %edi
movb (%rdx,%rdi), %dil
xorb -0x2c(%rbp,%rsi), %dil
movb %dil, (%r14)
incq %r14
incl %esi
cmpl $0x4, %esi
cmovael %ecx, %esi
incl %r8d
decq %rax
jne 0x2ebd
movb $0x0, (%r14)
movl %r13d, (%rbx)
movl %r12d, %eax
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq