// File: night-shift[P]Srl/src/lib/PSrl.cpp
// Function: Srl::PSrl::write(Srl::Value const&, Srl::Lib::MemBlock const&, Srl::Lib::Out&)
void PSrl::write(const Value& value, const MemBlock& name, Out& out)
{
    auto flag = build_flag(value);

    if(!flag) {
        out.write_byte(0);

        assert(this->scope_stack.size() > 0);
        this->pop_scope();
        return;
    }

    this->write_head(flag, name, out);

    auto type = value.type();
    /* scope-starts carry no additional information */
    if(TpTools::is_scope(type)) {
        this->push_scope(type);

        return;
    }

    /* do nothing on null-type, flag already carries bool value */
    if(type == Type::Null || type == Type::Bool) {
        return;
    }

    if(type == Type::FP32) {
        out.write(value.pblock().fp32);

    } else if(type == Type::FP64) {
        out.write(value.pblock().fp64);

    } else if(TpTools::is_integral(type)) {

        uint64_t integer = TpTools::is_signed(type) && value.pblock().i64 < 0
            ? -value.pblock().i64
            : value.pblock().ui64;

        encode_integer(integer, out);

    } else {
        assert(type == Type::Binary || type == Type::String);

        encode_integer(value.size(), out);
        out.write(value.data(), value.size());
    }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x70, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movq %rcx, -0x20(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x38(%rbp)
movq -0x10(%rbp), %rdi
callq 0x5ce40
movb %al, -0x21(%rbp)
cmpb $0x0, -0x21(%rbp)
jne 0x5cc9f
movq -0x20(%rbp), %rdi
xorl %esi, %esi
callq 0x366f0
movq -0x38(%rbp), %rdi
addq $0x78, %rdi
callq 0x36180
cmpq $0x0, %rax
jbe 0x5cc72
jmp 0x5cc91
leaq 0xce4c(%rip), %rdi      # 0x69ac5
leaq 0xd139(%rip), %rsi      # 0x69db9
movl $0xb5, %edx
leaq 0xd13e(%rip), %rcx      # 0x69dca
callq 0x349a0
movq -0x38(%rbp), %rdi
callq 0x38740
jmp 0x5ce38
movq -0x38(%rbp), %rdi
movb -0x21(%rbp), %al
movq -0x18(%rbp), %rdx
movq -0x20(%rbp), %rcx
movzbl %al, %esi
callq 0x359c0
movq -0x10(%rbp), %rdi
callq 0x35b80
movb %al, -0x22(%rbp)
movzbl -0x22(%rbp), %edi
callq 0x35db0
testb $0x1, %al
jne 0x5ccd1
jmp 0x5cce3
movq -0x38(%rbp), %rdi
movzbl -0x22(%rbp), %esi
callq 0x383c0
jmp 0x5ce38
cmpb $0xb, -0x22(%rbp)
je 0x5ccef
cmpb $0x0, -0x22(%rbp)
jne 0x5ccf4
jmp 0x5ce38
cmpb $0x9, -0x22(%rbp)
jne 0x5cd1c
movq -0x20(%rbp), %rax
movq %rax, -0x40(%rbp)
movq -0x10(%rbp), %rdi
callq 0x34bd0
movq -0x40(%rbp), %rdi
movq %rax, %rsi
callq 0x35420
jmp 0x5ce38
cmpb $0xa, -0x22(%rbp)
jne 0x5cd44
movq -0x20(%rbp), %rax
movq %rax, -0x48(%rbp)
movq -0x10(%rbp), %rdi
callq 0x34bd0
movq -0x48(%rbp), %rdi
movq %rax, %rsi
callq 0x386e0
jmp 0x5ce36
movzbl -0x22(%rbp), %edi
callq 0x38ca0
testb $0x1, %al
jne 0x5cd53
jmp 0x5cdb2
movzbl -0x22(%rbp), %edi
callq 0x34960
testb $0x1, %al
jne 0x5cd62
jmp 0x5cd88
movq -0x10(%rbp), %rdi
callq 0x34bd0
cmpq $0x0, (%rax)
jge 0x5cd88
movq -0x10(%rbp), %rdi
callq 0x34bd0
movq %rax, %rcx
xorl %eax, %eax
subq (%rcx), %rax
movq %rax, -0x50(%rbp)
jmp 0x5cd98
movq -0x10(%rbp), %rdi
callq 0x34bd0
movq (%rax), %rax
movq %rax, -0x50(%rbp)
movq -0x50(%rbp), %rax
movq %rax, -0x30(%rbp)
movq -0x30(%rbp), %rdi
movq -0x20(%rbp), %rsi
callq 0x5c900
jmp 0x5ce34
movb $0x1, %al
cmpb $0xd, -0x22(%rbp)
movb %al, -0x51(%rbp)
je 0x5cdc7
cmpb $0xc, -0x22(%rbp)
sete %al
movb %al, -0x51(%rbp)
movb -0x51(%rbp), %al
testb $0x1, %al
jne 0x5cdd0
jmp 0x5cdd2
jmp 0x5cdf1
leaq 0xd037(%rip), %rdi      # 0x69e10
leaq 0xcfd9(%rip), %rsi      # 0x69db9
movl $0xd8, %edx
leaq 0xcfde(%rip), %rcx      # 0x69dca
callq 0x349a0
movq -0x10(%rbp), %rdi
callq 0x34510
movq %rax, %rdi
movq -0x20(%rbp), %rsi
callq 0x5c900
movq -0x20(%rbp), %rax
movq %rax, -0x68(%rbp)
movq -0x10(%rbp), %rdi
callq 0x36770
movq %rax, -0x60(%rbp)
movq -0x10(%rbp), %rdi
callq 0x34510
movq -0x68(%rbp), %rdi
movq -0x60(%rbp), %rsi
movq %rax, %rdx
callq 0x364e0
jmp 0x5ce36
jmp 0x5ce38
addq $0x70, %rsp
popq %rbp
retq
nop