// File: zeeev[P]DASVC/bamtools/src/api/internal/io/HostAddress_p.cpp
// Function: BamTools::Internal::ParseIp6(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&, unsigned char*)
static
bool ParseIp6(const string& address, uint8_t* maybeIp6 ) {

    string tmp = address;

    // look for '%' char (if found, lop off that part of address)
    // we're going to ignore any link-local zone index, for now at least
    const size_t percentFound = tmp.rfind('%');
    if ( percentFound != string::npos )
        tmp = tmp.substr(0, percentFound);

    // split IP address into string fields
    vector<string> fields = Split(tmp, ':');
    const uint8_t numFields = fields.size();
    if ( numFields < 3 || numFields > 8 )
        return false;

    // get number of '::' separators
    const uint8_t numColonColons = CountHits(tmp, "::");
    if ( numFields == 8 && numColonColons > 1 )
        return false;

    // check valid IPv6 'compression'
    // must be valid 'pure' IPv6 or mixed IPv4/6 notation
    const size_t dotFound = tmp.find('.');
    const bool isMixed = ( dotFound != string::npos );
    if ( numColonColons != 1 && (numFields < (isMixed ? 7 : 8)) )
        return false;

    // iterate over provided fields
    size_t index = 16;
    size_t fillCount = 9 - numFields;
    for ( int8_t i = numFields - 1; i >= 0; --i ) {
        if ( index == 0 )
            return false;
        const string& field = fields.at(i);

        // if field empty
        if ( field.empty() ) {

            // if last field empty
            if ( i == numFields - 1 ) {
                const string& previousField = fields.at(i-1);
                if ( previousField.empty() )
                    return false;
                maybeIp6[--index] = 0;
                maybeIp6[--index] = 0;
            }

            // if first field empty
            else if ( i == 0 ) {
                // make sure ':' isn't first character
                const string& nextField = fields.at(i+1);
                if ( nextField.empty() ) return false;
                maybeIp6[--index] = 0;
                maybeIp6[--index] = 0;
            }

            // fill in 'compressed' 0s
            else {
                for ( uint8_t j = 0; j < fillCount; ++j ) {
                    if ( index == 0 ) return false;
                    maybeIp6[--index] = 0;
                    maybeIp6[--index] = 0;
                }
            }
        }

        // field has data
        else {
            uint32_t value = static_cast<uint32_t>( strtoul(field.c_str(), 0, 16) );

            if ( value <= 0xffff ) {
                maybeIp6[--index] =  value       & 0xff;
                maybeIp6[--index] = (value >> 8) & 0xff;
            }

            // possible mixed IPv4/6 notation
            else {

                // mixed field must be last
                if ( i != numFields - 1 )
                    return false;

                // parse the IPv4 section
                uint32_t maybeIp4;
                if ( !ParseIp4(field, maybeIp4) )
                    return false;

                // store IPv4 fields in IPv6 container
                maybeIp6[--index] =  maybeIp4        & 0xff;
                maybeIp6[--index] = (maybeIp4 >> 8)  & 0xff;
                maybeIp6[--index] = (maybeIp4 >> 16) & 0xff;
                maybeIp6[--index] = (maybeIp4 >> 24) & 0xff;
                --fillCount;
            }
        }
    }

    // should have parsed OK, return success
    return true;
}

// Assembly:
subq $0x188, %rsp            # imm = 0x188
movq %rdi, 0x178(%rsp)
movq %rsi, 0x170(%rsp)
movq 0x178(%rsp), %rsi
leaq 0x150(%rsp), %rdi
movq %rdi, 0x68(%rsp)
callq 0x73370
movq 0x68(%rsp), %rdi
movl $0x25, %esi
movq $-0x1, %rdx
callq 0x7ca70
movq %rax, 0x70(%rsp)
jmp 0xd369e
movq 0x70(%rsp), %rax
movq %rax, 0x148(%rsp)
cmpq $-0x1, 0x148(%rsp)
je 0xd3746
movq 0x148(%rsp), %rcx
xorl %eax, %eax
movl %eax, %edx
leaq 0x118(%rsp), %rdi
leaq 0x150(%rsp), %rsi
callq 0x76c50
jmp 0xd36dd
leaq 0x150(%rsp), %rdi
leaq 0x118(%rsp), %rsi
callq 0x71240
jmp 0xd36f4
leaq 0x118(%rsp), %rdi
callq 0x7cce8
jmp 0xd3703
jmp 0xd3746
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x140(%rsp)
movl %eax, 0x13c(%rsp)
jmp 0xd3e79
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x140(%rsp)
movl %eax, 0x13c(%rsp)
leaq 0x118(%rsp), %rdi
callq 0x7cce8
jmp 0xd3741
jmp 0xd3e79
leaq 0x100(%rsp), %rdi
leaq 0x150(%rsp), %rsi
movl $0x3a, %edx
callq 0xd40a0
jmp 0xd3762
leaq 0x100(%rsp), %rdi
callq 0x7bb00
movq %rax, 0x60(%rsp)
jmp 0xd3776
movq 0x60(%rsp), %rax
movb %al, 0xff(%rsp)
movzbl 0xff(%rsp), %eax
cmpl $0x3, %eax
jl 0xd379c
movzbl 0xff(%rsp), %eax
cmpl $0x8, %eax
jle 0xd37cd
movb $0x0, 0x187(%rsp)
movl $0x1, 0xf8(%rsp)
jmp 0xd3e3b
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x140(%rsp)
movl %eax, 0x13c(%rsp)
jmp 0xd3e68
leaq 0xcf(%rsp), %rdi
movq %rdi, 0x58(%rsp)
callq 0x7b5f0
movq 0x58(%rsp), %rdx
leaq 0x189d0(%rip), %rsi     # 0xec1bb
leaq 0xd0(%rsp), %rdi
callq 0x78e70
jmp 0xd37fa
leaq 0x150(%rsp), %rdi
leaq 0xd0(%rsp), %rsi
callq 0xd4220
movb %al, 0x57(%rsp)
jmp 0xd3815
leaq 0xd0(%rsp), %rdi
callq 0x7cce8
jmp 0xd3824
leaq 0xcf(%rsp), %rdi
callq 0x76f80
movb 0x57(%rsp), %al
movb %al, 0xf7(%rsp)
movzbl 0xff(%rsp), %eax
cmpl $0x8, %eax
jne 0xd38bb
movzbl 0xf7(%rsp), %eax
cmpl $0x1, %eax
jle 0xd38bb
movb $0x0, 0x187(%rsp)
movl $0x1, 0xf8(%rsp)
jmp 0xd3e3b
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x140(%rsp)
movl %eax, 0x13c(%rsp)
jmp 0xd38a9
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x140(%rsp)
movl %eax, 0x13c(%rsp)
leaq 0xd0(%rsp), %rdi
callq 0x7cce8
jmp 0xd38a7
jmp 0xd38a9
leaq 0xcf(%rsp), %rdi
callq 0x76f80
jmp 0xd3e68
xorl %eax, %eax
movl %eax, %edx
leaq 0x150(%rsp), %rdi
movl $0x2e, %esi
callq 0x787f0
movq %rax, 0x48(%rsp)
jmp 0xd38d8
movq 0x48(%rsp), %rax
movq %rax, 0xc0(%rsp)
cmpq $-0x1, 0xc0(%rsp)
setne %al
andb $0x1, %al
movb %al, 0xbf(%rsp)
movzbl 0xf7(%rsp), %eax
cmpl $0x1, %eax
je 0xd3944
movzbl 0xff(%rsp), %eax
movb 0xbf(%rsp), %sil
movl $0x8, %ecx
movl $0x7, %edx
testb $0x1, %sil
cmovnel %edx, %ecx
cmpl %ecx, %eax
jge 0xd3944
movb $0x0, 0x187(%rsp)
movl $0x1, 0xf8(%rsp)
jmp 0xd3e3b
movq $0x10, 0xb0(%rsp)
movzbl 0xff(%rsp), %ecx
movl $0x9, %eax
subl %ecx, %eax
cltq
movq %rax, 0xa8(%rsp)
movzbl 0xff(%rsp), %eax
subl $0x1, %eax
movb %al, 0xa7(%rsp)
movsbl 0xa7(%rsp), %eax
cmpl $0x0, %eax
jl 0xd3e28
cmpq $0x0, 0xb0(%rsp)
jne 0xd39af
movb $0x0, 0x187(%rsp)
movl $0x1, 0xf8(%rsp)
jmp 0xd3e3b
movsbq 0xa7(%rsp), %rsi
leaq 0x100(%rsp), %rdi
callq 0x72720
movq %rax, 0x40(%rsp)
jmp 0xd39cc
movq 0x40(%rsp), %rax
movq %rax, 0x98(%rsp)
movq 0x98(%rsp), %rdi
callq 0x7aba0
movb %al, 0x3f(%rsp)
jmp 0xd39ec
movb 0x3f(%rsp), %al
testb $0x1, %al
jne 0xd39f9
jmp 0xd3c2c
movsbl 0xa7(%rsp), %eax
movzbl 0xff(%rsp), %ecx
subl $0x1, %ecx
cmpl %ecx, %eax
jne 0xd3ac4
movsbl 0xa7(%rsp), %eax
decl %eax
movslq %eax, %rsi
leaq 0x100(%rsp), %rdi
callq 0x72720
movq %rax, 0x30(%rsp)
jmp 0xd3a35
movq 0x30(%rsp), %rax
movq %rax, 0x90(%rsp)
movq 0x90(%rsp), %rdi
callq 0x7aba0
movb %al, 0x2f(%rsp)
jmp 0xd3a55
movb 0x2f(%rsp), %al
testb $0x1, %al
jne 0xd3a5f
jmp 0xd3a77
movb $0x0, 0x187(%rsp)
movl $0x1, 0xf8(%rsp)
jmp 0xd3e3b
movq 0x170(%rsp), %rax
movq 0xb0(%rsp), %rcx
movq %rcx, %rdx
addq $-0x1, %rdx
movq %rdx, 0xb0(%rsp)
movb $0x0, -0x1(%rax,%rcx)
movq 0x170(%rsp), %rax
movq 0xb0(%rsp), %rcx
movq %rcx, %rdx
addq $-0x1, %rdx
movq %rdx, 0xb0(%rsp)
movb $0x0, -0x1(%rax,%rcx)
jmp 0xd3c27
movsbl 0xa7(%rsp), %eax
cmpl $0x0, %eax
jne 0xd3b85
movsbl 0xa7(%rsp), %eax
incl %eax
movslq %eax, %rsi
leaq 0x100(%rsp), %rdi
callq 0x72720
movq %rax, 0x20(%rsp)
jmp 0xd3af6
movq 0x20(%rsp), %rax
movq %rax, 0x88(%rsp)
movq 0x88(%rsp), %rdi
callq 0x7aba0
movb %al, 0x1f(%rsp)
jmp 0xd3b16
movb 0x1f(%rsp), %al
testb $0x1, %al
jne 0xd3b20
jmp 0xd3b38
movb $0x0, 0x187(%rsp)
movl $0x1, 0xf8(%rsp)
jmp 0xd3e3b
movq 0x170(%rsp), %rax
movq 0xb0(%rsp), %rcx
movq %rcx, %rdx
addq $-0x1, %rdx
movq %rdx, 0xb0(%rsp)
movb $0x0, -0x1(%rax,%rcx)
movq 0x170(%rsp), %rax
movq 0xb0(%rsp), %rcx
movq %rcx, %rdx
addq $-0x1, %rdx
movq %rdx, 0xb0(%rsp)
movb $0x0, -0x1(%rax,%rcx)
jmp 0xd3c25
movb $0x0, 0x87(%rsp)
movzbl 0x87(%rsp), %eax
cmpq 0xa8(%rsp), %rax
jae 0xd3c23
cmpq $0x0, 0xb0(%rsp)
jne 0xd3bc6
movb $0x0, 0x187(%rsp)
movl $0x1, 0xf8(%rsp)
jmp 0xd3e3b
movq 0x170(%rsp), %rax
movq 0xb0(%rsp), %rcx
movq %rcx, %rdx
addq $-0x1, %rdx
movq %rdx, 0xb0(%rsp)
movb $0x0, -0x1(%rax,%rcx)
movq 0x170(%rsp), %rax
movq 0xb0(%rsp), %rcx
movq %rcx, %rdx
addq $-0x1, %rdx
movq %rdx, 0xb0(%rsp)
movb $0x0, -0x1(%rax,%rcx)
movb 0x87(%rsp), %al
addb $0x1, %al
movb %al, 0x87(%rsp)
jmp 0xd3b8d
jmp 0xd3c25
jmp 0xd3c27
jmp 0xd3e11
movq 0x98(%rsp), %rdi
callq 0x73020
movq %rax, 0x10(%rsp)
jmp 0xd3c40
movq 0x10(%rsp), %rdi
xorl %eax, %eax
movl %eax, %esi
movl $0x10, %edx
callq 0x729b0
movl %eax, 0x80(%rsp)
cmpl $0xffff, 0x80(%rsp) # imm = 0xFFFF
ja 0xd3cd1
movl 0x80(%rsp), %eax
andl $0xff, %eax
movb %al, %dl
movq 0x170(%rsp), %rax
movq 0xb0(%rsp), %rcx
movq %rcx, %rsi
addq $-0x1, %rsi
movq %rsi, 0xb0(%rsp)
movb %dl, -0x1(%rax,%rcx)
movl 0x80(%rsp), %eax
shrl $0x8, %eax
andl $0xff, %eax
movb %al, %dl
movq 0x170(%rsp), %rax
movq 0xb0(%rsp), %rcx
movq %rcx, %rsi
addq $-0x1, %rsi
movq %rsi, 0xb0(%rsp)
movb %dl, -0x1(%rax,%rcx)
jmp 0xd3e0f
movsbl 0xa7(%rsp), %eax
movzbl 0xff(%rsp), %ecx
subl $0x1, %ecx
cmpl %ecx, %eax
je 0xd3d00
movb $0x0, 0x187(%rsp)
movl $0x1, 0xf8(%rsp)
jmp 0xd3e3b
movq 0x98(%rsp), %rdi
leaq 0x7c(%rsp), %rsi
callq 0xd3ea0
movb %al, 0xf(%rsp)
jmp 0xd3d18
movb 0xf(%rsp), %al
testb $0x1, %al
jne 0xd3d3a
jmp 0xd3d22
movb $0x0, 0x187(%rsp)
movl $0x1, 0xf8(%rsp)
jmp 0xd3e3b
movl 0x7c(%rsp), %eax
andl $0xff, %eax
movb %al, %dl
movq 0x170(%rsp), %rax
movq 0xb0(%rsp), %rcx
movq %rcx, %rsi
addq $-0x1, %rsi
movq %rsi, 0xb0(%rsp)
movb %dl, -0x1(%rax,%rcx)
movl 0x7c(%rsp), %eax
shrl $0x8, %eax
andl $0xff, %eax
movb %al, %dl
movq 0x170(%rsp), %rax
movq 0xb0(%rsp), %rcx
movq %rcx, %rsi
addq $-0x1, %rsi
movq %rsi, 0xb0(%rsp)
movb %dl, -0x1(%rax,%rcx)
movl 0x7c(%rsp), %eax
shrl $0x10, %eax
andl $0xff, %eax
movb %al, %dl
movq 0x170(%rsp), %rax
movq 0xb0(%rsp), %rcx
movq %rcx, %rsi
addq $-0x1, %rsi
movq %rsi, 0xb0(%rsp)
movb %dl, -0x1(%rax,%rcx)
movl 0x7c(%rsp), %eax
shrl $0x18, %eax
andl $0xff, %eax
movb %al, %dl
movq 0x170(%rsp), %rax
movq 0xb0(%rsp), %rcx
movq %rcx, %rsi
addq $-0x1, %rsi
movq %rsi, 0xb0(%rsp)
movb %dl, -0x1(%rax,%rcx)
movq 0xa8(%rsp), %rax
addq $-0x1, %rax
movq %rax, 0xa8(%rsp)
jmp 0xd3e11
jmp 0xd3e13
movb 0xa7(%rsp), %al
addb $-0x1, %al
movb %al, 0xa7(%rsp)
jmp 0xd397b
movb $0x1, 0x187(%rsp)
movl $0x1, 0xf8(%rsp)
leaq 0x100(%rsp), %rdi
callq 0x74e60
jmp 0xd3e4a
leaq 0x150(%rsp), %rdi
callq 0x7cce8
movb 0x187(%rsp), %al
andb $0x1, %al
addq $0x188, %rsp            # imm = 0x188
retq
leaq 0x100(%rsp), %rdi
callq 0x74e60
jmp 0xd3e77
jmp 0xd3e79
leaq 0x150(%rsp), %rdi
callq 0x7cce8
jmp 0xd3e88
jmp 0xd3e8a
movq 0x140(%rsp), %rdi
callq 0x7b550
movq %rax, %rdi
callq 0x88ef0
nop