// File: /workspace/github_c_makefile_star2_O2/sszllzss[P]webSocket_Libevent_ThreadPool/ev_websocket.c
// Function: webSocket_enPackage(unsigned char*, unsigned int, unsigned char*, unsigned int, bool, Websocket_CommunicationType)
int webSocket_enPackage(unsigned char *data, unsigned int dataLen, unsigned char *package, unsigned int packageMaxLen, bool isMask, Websocket_CommunicationType type)
{
    unsigned char maskKey[4] = {0};    // 掩码
    unsigned char temp1, temp2;
    int count;
    unsigned int i, len = 0;

    if(packageMaxLen < 2)
        return -1;

    if(type == WCT_MINDATA)
        *package++ = 0x00;
    else if(type == WCT_TXTDATA)
        *package++ = 0x81;
    else if(type == WCT_BINDATA)
        *package++ = 0x82;
    else if(type == WCT_DISCONN)
        *package++ = 0x88;
    else if(type == WCT_PING)
        *package++ = 0x89;
    else if(type == WCT_PONG)
        *package++ = 0x8A;
    else
        return -1;
    //
    if(isMask)
        *package = 0x80;
    len += 1;
    //
    if(dataLen < 126)
    {
        *package++ |= (dataLen&0x7F);
        len += 1;
    }
    else if(dataLen < 65536)
    {
        if(packageMaxLen < 4)
            return -1;
        *package++ |= 0x7E;
        *package++ = (char)((dataLen >> 8) & 0xFF);
        *package++ = (unsigned char)((dataLen >> 0) & 0xFF);
        len += 3;
    }
    else if(dataLen < 0xFFFFFFFF)
    {
        if(packageMaxLen < 10)
            return -1;
        *package++ |= 0x7F;
        *package++ = 0; //(char)((dataLen >> 56) & 0xFF);   // 数据长度变量是 unsigned int dataLen, 暂时没有那么多数据
        *package++ = 0; //(char)((dataLen >> 48) & 0xFF);
        *package++ = 0; //(char)((dataLen >> 40) & 0xFF);
        *package++ = 0; //(char)((dataLen >> 32) & 0xFF);
        *package++ = (char)((dataLen >> 24) & 0xFF);        // 到这里就够传4GB数据了
        *package++ = (char)((dataLen >> 16) & 0xFF);
        *package++ = (char)((dataLen >> 8) & 0xFF);
        *package++ = (char)((dataLen >> 0) & 0xFF);
        len += 9;
    }
    //
    if(isMask)    // 数据使用掩码时, 使用异或解码, maskKey[4]依次和数据异或运算, 逻辑如下
    {
        if(packageMaxLen < len + dataLen + 4)
            return -1;
        webSocket_getRandomString(maskKey, sizeof(maskKey));    // 随机生成掩码
        *package++ = maskKey[0];
        *package++ = maskKey[1];
        *package++ = maskKey[2];
        *package++ = maskKey[3];
        len += 4;
        for(i = 0, count = 0; i < dataLen; i++)
        {
            temp1 = maskKey[count];
            temp2 = data[i];
            *package++ = (char)(((~temp1)&temp2) | (temp1&(~temp2)));  // 异或运算后得到数据
            count += 1;
            if((unsigned)count >= sizeof(maskKey))    // maskKey[4]循环使用
                count = 0;
        }
        len += i;
        *package = '\0';
    }
    else    // 数据没使用掩码, 直接复制数据段
    {
        if(packageMaxLen < len + dataLen)
            return -1;
        memcpy(package, data, dataLen);
        package[dataLen] = '\0';
        len += dataLen;
    }
    //
    return len;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x18, %rsp
andl $0x0, -0x34(%rbp)
pushq $-0x1
popq %rax
cmpl $0x2, %ecx
jb 0x40a3
addl $0x14, %r9d
cmpl $0x5, %r9d
ja 0x40a3
movl %ecx, %r10d
movq %rdi, %rbx
movq %rsi, -0x30(%rbp)
shll $0x3, %r9d
movabsq $0x8a8988828100, %rsi   # imm = 0x8A8988828100
movl %r9d, %ecx
shrq %cl, %rsi
movb %sil, (%rdx)
leaq 0x1(%rdx), %r14
testb %r8b, %r8b
je 0x3f77
movb $-0x80, (%r14)
movq -0x30(%rbp), %rcx
cmpl $0x7d, %ecx
ja 0x400d
orb %cl, 0x1(%rdx)
addq $0x2, %rdx
pushq $0x2
popq %r12
movq %rdx, %r14
testb %r8b, %r8b
je 0x4034
movq %rcx, %r13
addl %r12d, %ecx
addl $0x4, %ecx
cmpl %r10d, %ecx
ja 0x40a3
leaq -0x34(%rbp), %r15
pushq $0x4
popq %rsi
movq %r15, %rdi
callq 0x3c00
movb (%r15), %al
movb %al, (%r14)
movb 0x1(%r15), %al
movb %al, 0x1(%r14)
movb 0x2(%r15), %al
movb %al, 0x2(%r14)
movb 0x3(%r15), %al
movb %al, 0x3(%r14)
addq $0x4, %r14
movl %r13d, %ecx
xorl %edx, %edx
xorl %eax, %eax
xorl %esi, %esi
cmpq %rax, %rcx
je 0x408e
movslq %esi, %rsi
movb (%rbx,%rax), %dil
xorb -0x34(%rbp,%rsi), %dil
movb %dil, (%r14,%rax)
incl %esi
cmpl $0x4, %esi
cmovael %edx, %esi
incq %rax
jmp 0x3fe7
cmpl $0xffff, %ecx           # imm = 0xFFFF
ja 0x4052
cmpl $0x4, %r10d
jb 0x40a3
orb $0x7e, 0x1(%rdx)
movb %ch, 0x2(%rdx)
movb %cl, 0x3(%rdx)
addq $0x4, %rdx
pushq $0x4
jmp 0x3f8d
addl %ecx, %r12d
cmpl %r10d, %r12d
ja 0x40a3
movl %ecx, %r15d
movq %r14, %rdi
movq %rbx, %rsi
movq %r15, %rdx
callq 0x3360
addq %r15, %r14
jmp 0x409c
cmpl $-0x1, %ecx
je 0x40b2
cmpl $0xa, %r10d
jb 0x40a3
orb $0x7f, 0x1(%rdx)
movq -0x30(%rbp), %rcx
shrl $0x18, %ecx
andl $0x0, 0x2(%rdx)
movb %cl, 0x6(%rdx)
movq -0x30(%rbp), %rcx
shrl $0x10, %ecx
movb %cl, 0x7(%rdx)
movq -0x30(%rbp), %rcx
movb %ch, 0x8(%rdx)
movb %cl, 0x9(%rdx)
addq $0xa, %rdx
pushq $0xa
jmp 0x3f8d
movq -0x30(%rbp), %rcx
addl %ecx, %r12d
addl $0x4, %r12d
addq %rax, %r14
movb $0x0, (%r14)
movl %r12d, %eax
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
pushq $0x1
popq %r12
jmp 0x3f92