// File: /workspace/github_cpp_makefile_star2_O3/salleaffaire[P]MXFParser/klv.cpp
// Function: klv_parser::get_klv_item(klv_item&, bit_extractor&)
bool klv_parser::get_klv_item(klv_item &klvi, bit_extractor &be) {
   bool rval = true;
   
   // Read Key
   // ------------------------------------------------------------------------------
   // Test for enough byte for a LU Key
   if (be.get_bytes_left() >= 16) {
      for (int i=0;i<16;++i) {
         klvi.mKey[i] = be.get_bits(8);
      }
   }
   else {
      std::cout << "Need 16 bytes for a KLV Key but only " << be.get_bytes_left()
                << " bytes left in the file." << std::endl;
      rval = false;
   }
   
   uint8_t l0;
   if (rval && (be.get_bytes_left() >= 1)) {
      // Read Length (BER encoded)
      l0 = be.get_bits(8);
   }
   else {
      std::cout << "Need 1 byte for a BER first byte file is empty" << std::endl;
      rval = false;
   }
   
   if (rval) {
      // Short form
      if (!(l0 & 0x80)) {
         klvi.mLength = l0;
      } 
      // Long form
      else {
         int num_of_octets = l0 & 0x7F;
         if (be.get_bytes_left() >= num_of_octets) {
            if (num_of_octets > 4) {
               std::cout << " Error : This library doesn't support BER long form with number of octets "
                         << "bigger than 4." << std::endl;
            }
            int i;
            klvi.mLength = 0;
            for (i=num_of_octets-1;i>=0;--i) {
               uint32_t o = be.get_bits(8);
               klvi.mLength |= (o << (i*8));
            }
         }
         else {
            std::cout << "Need " << num_of_octets
                      << " bytes for a KLV Length BER but only " << be.get_bytes_left()
                      << " bytes left in the file." << std::endl;
            rval = false;
         }
      }
      
   }
   
   if (rval && (be.get_bytes_left() >= klvi.mLength)) {
      klvi.mValue = be.get_buffer();
      be.skip_n_bytes(klvi.mLength);
   }
   else {
      std::cout << "Need " << klvi.mLength
                << " bytes for a KLV Value but only " << be.get_bytes_left()
                << " bytes left in the file." << std::endl;
      rval = false;
   }

   if (rval)  {
      klvi.parse_value();
   }
   
   return rval;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
pushq %rax
movq %rdx, %rbx
movq %rsi, %r14
movl 0x8(%rdx), %eax
subl 0x10(%rdx), %eax
cmpl $0x10, %eax
jb 0x29e9
xorl %r15d, %r15d
movq %rbx, %rdi
movl $0x8, %esi
callq 0x3b9c
movzbl 0xc(%rbx), %ecx
movl %ecx, %edx
addl $0x8, %edx
shrl $0x3, %edx
addl %edx, 0x10(%rbx)
andb $0x7, %cl
movb %cl, 0xc(%rbx)
movb %al, (%r14,%r15)
incq %r15
cmpq $0x10, %r15
jne 0x2971
movl 0x8(%rbx), %eax
cmpl 0x10(%rbx), %eax
je 0x2a50
movq %rbx, %rdi
movl $0x8, %esi
callq 0x3b9c
movl %eax, %r15d
movzbl 0xc(%rbx), %eax
movl %eax, %edx
addl $0x8, %edx
shrl $0x3, %edx
addl 0x10(%rbx), %edx
movl %edx, 0x10(%rbx)
andb $0x7, %al
movb %al, 0xc(%rbx)
movzbl %r15b, %eax
cmpl $0x7f, %eax
ja 0x2b2d
movl %eax, 0x10(%r14)
jmp 0x2c66
movq 0x75e8(%rip), %r15      # 0x9fd8
leaq 0x47f2(%rip), %rsi      # 0x71e9
movl $0x25, %edx
movq %r15, %rdi
callq 0x21a0
movl 0x8(%rbx), %esi
subl 0x10(%rbx), %esi
movq %r15, %rdi
callq 0x20d0
movq %rax, %r15
leaq 0x47f3(%rip), %rsi      # 0x720f
movl $0x18, %edx
movq %rax, %rdi
callq 0x21a0
movq (%r15), %rax
movq -0x18(%rax), %rdi
addq %r15, %rdi
movl $0xa, %esi
callq 0x2150
movsbl %al, %esi
movq %r15, %rdi
callq 0x2040
movq %rax, %rdi
callq 0x20e0
movq 0x7581(%rip), %r15      # 0x9fd8
leaq 0x47ca(%rip), %rsi      # 0x7228
movl $0x2e, %edx
movq %r15, %rdi
callq 0x21a0
movq (%r15), %rax
movq -0x18(%rax), %rdi
addq %r15, %rdi
movl $0xa, %esi
callq 0x2150
movsbl %al, %esi
movq %r15, %rdi
callq 0x2040
movq %rax, %rdi
callq 0x20e0
movq 0x753f(%rip), %r15      # 0x9fd8
leaq 0x4811(%rip), %rsi      # 0x72b1
movl $0x5, %edx
movq %r15, %rdi
callq 0x21a0
movl 0x10(%r14), %esi
movq %r15, %rdi
callq 0x20d0
movq %rax, %r14
leaq 0x481a(%rip), %rsi      # 0x72dd
movl $0x20, %edx
movq %rax, %rdi
callq 0x21a0
movl 0x8(%rbx), %esi
subl 0x10(%rbx), %esi
movq %r14, %rdi
callq 0x20d0
movq %rax, %rbx
leaq 0x4727(%rip), %rsi      # 0x720f
movl $0x18, %edx
movq %rax, %rdi
callq 0x21a0
movq (%rbx), %rax
movq -0x18(%rax), %rdi
addq %rbx, %rdi
movl $0xa, %esi
callq 0x2150
movsbl %al, %esi
movq %rbx, %rdi
callq 0x2040
movq %rax, %rdi
callq 0x20e0
xorl %eax, %eax
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
andl $0x7f, %r15d
movl 0x8(%rbx), %eax
subl %edx, %eax
cmpl %r15d, %eax
jae 0x2b9d
movq 0x7496(%rip), %r12      # 0x9fd8
leaq 0x4768(%rip), %rsi      # 0x72b1
movl $0x5, %edx
movq %r12, %rdi
callq 0x21a0
movq %r12, %rdi
movl %r15d, %esi
callq 0x2230
movq %rax, %r15
leaq 0x474c(%rip), %rsi      # 0x72b7
movl $0x25, %edx
movq %rax, %rdi
callq 0x21a0
movl 0x8(%rbx), %esi
subl 0x10(%rbx), %esi
movq %r15, %rdi
callq 0x20d0
movq %rax, %r15
leaq 0x467f(%rip), %rsi      # 0x720f
movl $0x18, %edx
movq %rax, %rdi
jmp 0x2a66
cmpl $0x5, %r15d
jb 0x2c08
movq 0x742e(%rip), %r12      # 0x9fd8
leaq 0x46a6(%rip), %rsi      # 0x7257
movl $0x4a, %edx
movq %r12, %rdi
callq 0x21a0
leaq 0x46dd(%rip), %rsi      # 0x72a2
movl $0xe, %edx
movq %r12, %rdi
callq 0x21a0
movq (%r12), %rax
movq -0x18(%rax), %rdi
addq %r12, %rdi
movl $0xa, %esi
callq 0x2150
movsbl %al, %esi
movq %r12, %rdi
callq 0x2040
movq %rax, %rdi
callq 0x20e0
leaq 0x10(%r14), %r12
movl $0x0, 0x10(%r14)
jmp 0x2c19
movl $0x0, 0x10(%r14)
testl %r15d, %r15d
je 0x2c90
leaq 0x10(%r14), %r12
movl %r15d, %r13d
incl %r13d
leal -0x8(,%r15,8), %ebp
movq %rbx, %rdi
movl $0x8, %esi
callq 0x3b9c
movzbl 0xc(%rbx), %esi
movl %esi, %edx
addl $0x8, %edx
shrl $0x3, %edx
addl 0x10(%rbx), %edx
movl %edx, 0x10(%rbx)
movl %ebp, %ecx
shll %cl, %eax
andb $0x7, %sil
movb %sil, 0xc(%rbx)
orl (%r12), %eax
movl %eax, (%r12)
decl %r13d
addl $-0x8, %ebp
cmpl $0x1, %r13d
ja 0x2c27
movl 0x8(%rbx), %ecx
subl %edx, %ecx
cmpl %eax, %ecx
jb 0x2a92
movl %edx, %ecx
addq (%rbx), %rcx
movq %rcx, 0x18(%r14)
addl %edx, %eax
movl %eax, 0x10(%rbx)
movq %r14, %rdi
callq 0x27c8
movb $0x1, %al
jmp 0x2b1e
movl 0x10(%rbx), %edx
xorl %eax, %eax
jmp 0x2c73
nop