// File: adamjanovsky[P]PA193_test_parser_monero/src/tools.cpp
// Function: tools::read_varint(std::istream&, unsigned long&)
int tools::read_varint(std::istream & in, unsigned long & val) {
    
    // We will load the varint into a vector and then deserialize it
    std::vector<unsigned char> ser_vect;
    unsigned char c;
    
    // 10 bytes is maximum for the varint to fit in 64 bit int
    // and the last serialized val must be 0x01 so that the int does not overflow
    // because each byte contains 7 bits and 9 * 7 + 1 = 63 + 1 = 64
    for (int i = 0; i < 10; i++) {
        in.read((char *)&c, 1);
        
        // Check for overflow
        if (i == 9 and c != 0x01) {
            std::cerr << "Read varint: Varint overflow." << std::endl;
            return ERR_READV_OVERFLOW;
        }
        
        // Check for EOF
        if (!in.good()) {
            std::cerr << "Read varint: Unexpected end of stream." << std::endl;
            return ERR_READV_UNEXPECTED_EOF;
        }
        
        // Strip the first bit and save it into the vector
        ser_vect.push_back(c & 0x7f);
        
        if ((c & 0x80) == 0x00) {
            // we have read the last byte
            break;
        }

    }
    
    val = 0;
    int last_index = static_cast<int>(ser_vect.size()) - 1;
    
    for (int i = last_index; i >= 0; i--) {
        val <<= 7;
        val |= ser_vect.at(i);
    }
    
    return OK;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x80, %rsp
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
leaq -0x30(%rbp), %rdi
callq 0x2860
movl $0x0, -0x38(%rbp)
cmpl $0xa, -0x38(%rbp)
jge 0x7afe
movq -0x10(%rbp), %rdi
leaq -0x31(%rbp), %rsi
movl $0x1, %edx
callq 0x21d0
jmp 0x7a01
cmpl $0x9, -0x38(%rbp)
jne 0x7a68
movzbl -0x31(%rbp), %eax
cmpl $0x1, %eax
je 0x7a68
movq 0x55d9(%rip), %rdi      # 0xcff0
leaq 0x1b31(%rip), %rsi      # 0x954f
callq 0x2160
movq %rax, -0x60(%rbp)
jmp 0x7a29
movq -0x60(%rbp), %rdi
movq 0x558c(%rip), %rsi      # 0xcfc0
callq 0x2190
jmp 0x7a3b
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
movl $0x1, -0x48(%rbp)
jmp 0x7b71
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
leaq -0x30(%rbp), %rdi
callq 0x2930
jmp 0x7b86
movq -0x10(%rbp), %rdi
movq (%rdi), %rax
movq -0x18(%rax), %rax
addq %rax, %rdi
callq 0x22a0
movb %al, -0x61(%rbp)
jmp 0x7a80
movb -0x61(%rbp), %al
testb $0x1, %al
jne 0x7ac7
jmp 0x7a89
movq 0x5560(%rip), %rdi      # 0xcff0
leaq 0x1ad6(%rip), %rsi      # 0x956d
callq 0x2160
movq %rax, -0x70(%rbp)
jmp 0x7aa2
movq -0x70(%rbp), %rdi
movq 0x5513(%rip), %rsi      # 0xcfc0
callq 0x2190
jmp 0x7ab4
movl $0xfffffffe, -0x4(%rbp) # imm = 0xFFFFFFFE
movl $0x1, -0x48(%rbp)
jmp 0x7b71
movb -0x31(%rbp), %al
andb $0x7f, %al
movb %al, -0x49(%rbp)
leaq -0x30(%rbp), %rdi
leaq -0x49(%rbp), %rsi
callq 0x8150
jmp 0x7ade
movzbl -0x31(%rbp), %eax
andl $0x80, %eax
cmpl $0x0, %eax
jne 0x7aee
jmp 0x7afe
jmp 0x7af0
movl -0x38(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x38(%rbp)
jmp 0x79e3
movq -0x18(%rbp), %rax
movq $0x0, (%rax)
leaq -0x30(%rbp), %rdi
callq 0x46b0
subl $0x1, %eax
movl %eax, -0x50(%rbp)
movl -0x50(%rbp), %eax
movl %eax, -0x54(%rbp)
cmpl $0x0, -0x54(%rbp)
jl 0x7b63
movq -0x18(%rbp), %rax
movq (%rax), %rcx
shlq $0x7, %rcx
movq %rcx, (%rax)
movslq -0x54(%rbp), %rsi
leaq -0x30(%rbp), %rdi
callq 0x81f0
movq %rax, -0x78(%rbp)
jmp 0x7b45
movq -0x78(%rbp), %rax
movzbl (%rax), %eax
movl %eax, %ecx
movq -0x18(%rbp), %rax
orq (%rax), %rcx
movq %rcx, (%rax)
movl -0x54(%rbp), %eax
addl $-0x1, %eax
movl %eax, -0x54(%rbp)
jmp 0x7b1e
movl $0x0, -0x4(%rbp)
movl $0x1, -0x48(%rbp)
leaq -0x30(%rbp), %rdi
callq 0x2930
movl -0x4(%rbp), %eax
addq $0x80, %rsp
popq %rbp
retq
movq -0x40(%rbp), %rdi
callq 0x22d0
nop