// File: /workspace/github_cpp_makefile_star2_O3/brunokeymolen[P]ssdp/src/ssdptools.cpp
// Function: ParseUSN(unsigned char*, unsigned int, ssdpuuid*)
int ParseUSN(u8* uuidraw, u32 len, ssdpuuid *uuid){
    int ret = 0;
    int colon1 = 0;
    int colon2 = 0;
    int tel;
    int skip=0;

//    int lenleft;

    //Sanity
    if(uuid == NULL || len == 0){
        return -1;
    }
    if(memcmp(uuidraw, "uuid", 4) != 0){
        return -2;
    }

    memset(uuid, 0, sizeof(ssdpuuid));

//    lenleft = len;

    //uuid
    colon1 = getchar(uuidraw, len, ':', 1);
    colon2 = getchar(uuidraw, len, ':', 2);
    if(colon1<0 || colon1+1>=(int)len){ ret = -1;goto EXIT;}
    if(colon2<0){
        uuid->uuid=uuidraw;//+colon1+1;
        uuid->uuidlen=len;//-colon1-1;
        //uuid->uuidlen=len-colon1-1;
        goto EXIT;
    }else{
        uuid->uuid=uuidraw;//+colon1+1;
        uuid->uuidlen=colon2;
//        uuid->uuidlen=colon2-colon1-1;
    }

    //Sanity, there must be a double colon
    //Find the first '::' sequence and compute the number of semicolons to it
    //store it in the skip variable, which is used for offsetting subsequent searches
    //this is needed for some devices that have a semicolon in the name
    colon1 = getchar(uuidraw, len, ':', 2);
    colon2 = -1;
    while (colon1 < (int)len && colon2 == -1) {
        colon2 = getchar(uuidraw, len, ':', 2+skip+1);
        if (colon2-colon1 == 1) {
            uuid->uuidlen=colon1;
            colon1 = colon2;
        } else {
            colon1 = colon2;
            colon2 = -1;
            skip++;
        }
    }
    if(colon2 == -1){
        ret = -2;
        goto EXIT;
    }


    //upnp, isroot 
    colon1 = getchar(uuidraw, len, ':', 3+skip);
    if((len-colon1)>=15 && memcmp(uuidraw+colon1+1, "upnp:rootdevice", 15)==0 ){
        uuid->isrootdevice = 1;
        uuid->isdevice = 1;
        uuid->type = uuidraw+colon1+1;
        uuid->typelen = 15;
        goto EXIT;
    }

    //Sanity, there must be 4 colons after
    for(tel=4+skip;tel<=7+skip;tel++){
        colon1 = getchar(uuidraw, len, ':', tel);
        if(colon1 < 0){
            ret = -3;
            goto EXIT;
        }
    }


    //urn
    colon1 = getchar(uuidraw, len, ':', 3+skip);
    colon2 = getchar(uuidraw, len, ':', 4+skip);
    if((colon2-colon1)>=3 && memcmp(uuidraw+colon1+1, "urn", 3)!=0 ){
        ret = -4;
        goto EXIT;
    }
    uuid->fullurn = uuidraw+colon1+1;
    uuid->fullurnlen = len-colon1-1;

    colon1 = getchar(uuidraw, len, ':', 4+skip);
    colon2 = getchar(uuidraw, len, ':', 5+skip);
    uuid->urn=uuidraw+colon1+1;
    uuid->urnlen=colon2-colon1-1;



    //Device or service
    colon1 = getchar(uuidraw, len, ':', 5+skip);
    colon2 = getchar(uuidraw, len, ':', 6+skip);
    if( (colon2-colon1)>=6 && memcmp(uuidraw+colon1+1, "device", 6)==0){
        //device
        uuid->isdevice = 1;
    }else if((colon2-colon1)>=7 && memcmp(uuidraw+colon1+1, "service", 7)==0){
        //service
        uuid->isservice = 1;
    }else{
        ret = -5;
        goto EXIT;
    }


    //servicetype / devicetype
    colon1 = getchar(uuidraw, len, ':', 6+skip);
    colon2 = getchar(uuidraw, len, ':', 7+skip);
    uuid->type = uuidraw+colon1+1;
    uuid->typelen=colon2-colon1-1;

    //Workaround for MusicPal bug
    if(uuid->typelen==16 && memcmp(uuid->type, "RenderingControl", 16) == 0){
        uuid->isdevice = 0;
        uuid->isrootdevice = 0;
        uuid->isservice = 1;
    }

    //version
    uuid->version = uuidraw+colon2+1;
    uuid->versionlen=len-colon2-1;

EXIT:

    return ret;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
pushq %rax
testq %rdx, %rdx
sete %al
testl %esi, %esi
sete %cl
orb %al, %cl
movl $0xffffffff, %r13d      # imm = 0xFFFFFFFF
jne 0x78c8
movq %rdi, %r14
cmpl $0x64697575, (%rdi)     # imm = 0x64697575
je 0x7648
movl $0xfffffffe, %r13d      # imm = 0xFFFFFFFE
jmp 0x78c8
movq %rdx, %rbx
movl %esi, %ebp
pxor %xmm0, %xmm0
movdqu %xmm0, 0x40(%rdx)
movdqu %xmm0, 0x30(%rdx)
movdqu %xmm0, 0x20(%rdx)
movdqu %xmm0, 0x10(%rdx)
movdqu %xmm0, (%rdx)
movq %r14, %rdi
movl $0x3a, %edx
movl $0x1, %ecx
callq 0x38e5
movl %eax, %r15d
movq %r14, %rdi
movl %ebp, %esi
movl $0x3a, %edx
movl $0x2, %ecx
callq 0x38e5
testl %r15d, %r15d
setns %cl
incl %r15d
cmpl %ebp, %r15d
setl %dl
andb %cl, %dl
cmpb $0x1, %dl
jne 0x78c8
movq %r14, (%rbx)
testl %eax, %eax
js 0x78c2
movl %eax, 0x8(%rbx)
movq %r14, %rdi
movl %ebp, %esi
movl $0x3a, %edx
movl $0x2, %ecx
callq 0x38e5
cmpl %ebp, %eax
jge 0x763d
movl %eax, %r12d
xorl %r15d, %r15d
leal 0x3(%r15), %ecx
movq %r14, %rdi
movl %ebp, %esi
movl $0x3a, %edx
callq 0x38e5
movl %eax, %ecx
subl %r12d, %ecx
cmpl $0x1, %ecx
jne 0x7705
movl %r12d, 0x8(%rbx)
cmpl $-0x1, %eax
sete %cl
jmp 0x770a
incl %r15d
movb $0x1, %cl
cmpl %ebp, %eax
jge 0x7715
movl %eax, %r12d
testb %cl, %cl
jne 0x76dc
movl $0xfffffffe, %r13d      # imm = 0xFFFFFFFE
testb %cl, %cl
jne 0x78c8
leal 0x3(%r15), %r13d
movq %r14, %rdi
movl %ebp, %esi
movl $0x3a, %edx
movl %r13d, %ecx
callq 0x38e5
movl %ebp, %ecx
subl %eax, %ecx
cmpl $0xf, %ecx
jb 0x776b
cltq
movabsq $0x6f6f723a706e7075, %rcx # imm = 0x6F6F723A706E7075
xorq 0x1(%r14,%rax), %rcx
movabsq $0x656369766564746f, %rdx # imm = 0x656369766564746F
xorq 0x8(%r14,%rax), %rdx
orq %rcx, %rdx
je 0x78e2
leal 0x4(%r15), %eax
movl %eax, (%rsp)
leal 0x7(%r15), %r12d
movl %r13d, 0x4(%rsp)
incl %r13d
movq %r14, %rdi
movl %ebp, %esi
movl $0x3a, %edx
movl %r13d, %ecx
callq 0x38e5
testl %eax, %eax
js 0x78da
cmpl %r12d, %r13d
jl 0x777b
movq %r14, %rdi
movl %ebp, %esi
movl $0x3a, %edx
movl 0x4(%rsp), %ecx
callq 0x38e5
movl %eax, %r13d
movq %r14, %rdi
movl %ebp, %esi
movl $0x3a, %edx
movl (%rsp), %ecx
callq 0x38e5
subl %r13d, %eax
movslq %r13d, %rcx
cmpl $0x3, %eax
jl 0x77f3
movzwl 0x1(%r14,%rcx), %eax
xorl $0x7275, %eax           # imm = 0x7275
movzbl 0x3(%r14,%rcx), %edx
xorl $0x6e, %edx
orw %ax, %dx
movl $0xfffffffc, %r13d      # imm = 0xFFFFFFFC
jne 0x78c8
leaq (%r14,%rcx), %rax
incq %rax
movq %rax, 0x10(%rbx)
notl %ecx
addl %ebp, %ecx
movl %ecx, 0x18(%rbx)
movq %r14, %rdi
movl %ebp, %esi
movl $0x3a, %edx
movl (%rsp), %ecx
callq 0x38e5
movl %eax, (%rsp)
leal 0x5(%r15), %r13d
movq %r14, %rdi
movl %ebp, %esi
movl $0x3a, %edx
movl %r13d, %ecx
callq 0x38e5
movslq (%rsp), %rcx
leaq (%r14,%rcx), %rdx
incq %rdx
movq %rdx, 0x20(%rbx)
notl %ecx
addl %eax, %ecx
movl %ecx, 0x28(%rbx)
movq %r14, %rdi
movl %ebp, %esi
movl $0x3a, %edx
movl %r13d, %ecx
callq 0x38e5
movl %eax, %r13d
addl $0x6, %r15d
movq %r14, %rdi
movl %ebp, %esi
movl $0x3a, %edx
movl %r15d, %ecx
callq 0x38e5
movl %r13d, %ecx
subl %r13d, %eax
movl $0xfffffffb, %r13d      # imm = 0xFFFFFFFB
cmpl $0x6, %eax
jl 0x78c8
movslq %ecx, %rcx
movl $0x69766564, %edx       # imm = 0x69766564
xorl 0x1(%r14,%rcx), %edx
movzwl 0x5(%r14,%rcx), %esi
xorl $0x6563, %esi           # imm = 0x6563
orl %edx, %esi
je 0x78fb
cmpl $0x6, %eax
je 0x78c8
movl $0x76726573, %eax       # imm = 0x76726573
xorl 0x1(%r14,%rcx), %eax
movl $0x65636976, %edx       # imm = 0x65636976
xorl 0x4(%r14,%rcx), %edx
orl %eax, %edx
jne 0x78c8
movb $0x1, 0x2e(%rbx)
jmp 0x78ff
movl %ebp, 0x8(%rbx)
xorl %r13d, %r13d
movl %r13d, %eax
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movl $0xfffffffd, %r13d      # imm = 0xFFFFFFFD
jmp 0x78c8
addq %r14, %rax
incq %rax
movw $0x101, 0x2c(%rbx)      # imm = 0x101
movq %rax, 0x30(%rbx)
movl $0xf, 0x38(%rbx)
jmp 0x78c5
movb $0x1, 0x2c(%rbx)
movq %r14, %rdi
movl %ebp, %esi
movl $0x3a, %edx
movl %r15d, %ecx
callq 0x38e5
movl %eax, %r15d
movq %r14, %rdi
movl %ebp, %esi
movl $0x3a, %edx
movl %r12d, %ecx
callq 0x38e5
movslq %r15d, %rdx
leaq (%r14,%rdx), %rcx
incq %rcx
movq %rcx, 0x30(%rbx)
notl %edx
addl %eax, %edx
movl %edx, 0x38(%rbx)
cmpl $0x10, %edx
jne 0x7962
movdqu (%rcx), %xmm0
pcmpeqb 0xd14(%rip), %xmm0      # 0x8660
pmovmskb %xmm0, %ecx
cmpl $0xffff, %ecx           # imm = 0xFFFF
jne 0x7962
movw $0x0, 0x2c(%rbx)
movb $0x1, 0x2e(%rbx)
movslq %eax, %rcx
addq %r14, %rcx
incq %rcx
movq %rcx, 0x40(%rbx)
notl %eax
addl %ebp, %eax
movl %eax, 0x48(%rbx)
jmp 0x78c5