// File: /workspace/github_c_makefile_star2_O3/sszllzss[P]webSocket_Libevent_ThreadPool/ev_websocket.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;
    int count, ret;
    unsigned int i, len = 0, dataStart = 2;
    if(dataLen < 2)
        return WCT_ERR;

    ret = webSocket_getInType(data);
    if(ret == WCT_ERR) 
        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
subq $0x18, %rsp
movl $0x0, -0x2c(%rbp)
movl $0xfffffffe, %r13d      # imm = 0xFFFFFFFE
cmpl $0x2, %esi
jb 0x4be8
movq %r8, %rbx
movq %rdx, %r14
movl %esi, %r15d
movq %rdi, %r12
movl %ecx, -0x30(%rbp)
callq 0x4ab5
cmpl $-0x2, %eax
jne 0x4bfa
movl %r13d, %eax
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movl %eax, %r8d
movq %rbx, -0x38(%rbp)
movzbl 0x1(%r12), %eax
movl %eax, %ecx
shrl $0x5, %ecx
andl $-0x4, %ecx
movl %eax, %ebx
andl $0x7f, %ebx
cmpl $0x7f, %ebx
je 0x4c6d
cmpl $0x7e, %ebx
jne 0x4ce3
cmpl $0x4, %r15d
jb 0x4be8
movzwl 0x2(%r12), %edx
rolw $0x8, %dx
movzwl %dx, %ebx
addl %ebx, %ecx
addl $0x4, %ecx
cmpl %r15d, %ecx
ja 0x4be8
movl $0x4, %ecx
testb %al, %al
jns 0x4d2d
movb 0x4(%r12), %cl
movb %cl, -0x2c(%rbp)
movl $0x8, %ecx
movl $0x7, %edx
movl $0x6, %esi
movl $0x5, %edi
jmp 0x4d16
cmpl $0xa, %r15d
jb 0x4be8
cmpb $0x0, 0x2(%r12)
jne 0x4be8
cmpb $0x0, 0x3(%r12)
jne 0x4be8
cmpb $0x0, 0x4(%r12)
jne 0x4be8
cmpb $0x0, 0x5(%r12)
jne 0x4be8
movl 0x6(%r12), %ebx
bswapl %ebx
addl %ebx, %ecx
addl $0xa, %ecx
cmpl %r15d, %ecx
ja 0x4be8
movl $0xa, %ecx
testb %al, %al
jns 0x4d2d
movb 0xa(%r12), %cl
movb %cl, -0x2c(%rbp)
movl $0xe, %ecx
movl $0xd, %edx
movl $0xc, %esi
movl $0xb, %edi
jmp 0x4d16
addl %ebx, %ecx
addl $0x2, %ecx
cmpl %r15d, %ecx
ja 0x4be8
movl $0x2, %ecx
testb %al, %al
jns 0x4d2d
movb 0x2(%r12), %cl
movb %cl, -0x2c(%rbp)
movl $0x6, %ecx
movl $0x5, %edx
movl $0x4, %esi
movl $0x3, %edi
movb (%r12,%rdi), %dil
movb %dil, -0x2b(%rbp)
movb (%r12,%rsi), %sil
movb %sil, -0x2a(%rbp)
movb (%r12,%rdx), %dl
movb %dl, -0x29(%rbp)
leal (%rcx,%rbx), %edx
cmpl %r15d, %edx
seta %dl
leal 0x1(%rbx), %esi
cmpl -0x30(%rbp), %esi
seta %sil
orb %dl, %sil
jne 0x4be8
testb %al, %al
js 0x4d6e
movl %ecx, %eax
addq %rax, %r12
movl %ebx, %r15d
movq %r14, %rdi
movq %r12, %rsi
movq %r15, %rdx
movl %r8d, %r12d
callq 0x3350
movl %r12d, %r8d
addq %r15, %r14
jmp 0x4d9b
testl %ebx, %ebx
je 0x4d9b
movl %ebx, %eax
xorl %edx, %edx
xorl %esi, %esi
movslq %esi, %rsi
movl %ecx, %edi
movb (%r12,%rdi), %dil
xorb -0x2c(%rbp,%rsi), %dil
movb %dil, (%r14)
incq %r14
incl %esi
cmpl $0x4, %esi
cmovael %edx, %esi
incl %ecx
decq %rax
jne 0x4d78
movb $0x0, (%r14)
movq -0x38(%rbp), %rax
movl %ebx, (%rax)
movl %r8d, %r13d
jmp 0x4be8