// File: /workspace/github_cpp_makefile_star2_O3/devinsmith[P]qvdreader/QvdFile.cpp
// Function: QvdFile::parseSymbolAndData()
bool QvdFile::parseSymbolAndData()
{
  for (std::vector<QvdField>::iterator it = _hdr.Fields.begin();
      it != _hdr.Fields.end(); ++it) {
    DEBUG(printf("Parsing symbols for %s, need to read %d symbols\n",
            it->FieldName.c_str(), it->NoOfSymbols););

    for (unsigned int i = 0; i < it->NoOfSymbols; i++) {
      unsigned char typeByte = static_cast<unsigned char>(readByte());
      QvdSymbol symbol;

      char stringByte;
      double d;

      symbol.Type = typeByte;
      switch (typeByte) {
      case 0x01: // INT (4 bytes)
        symbol.IntValue = readInt32();
        break;
      case 0x02: // NUMERIC (double 8 bytes)
        // XXX: Not endian safe.
        d = readDouble();
        symbol.DoubleValue = d;
        break;
      case 0x04: // String value (0 terminated)
        while ((stringByte = readByte()) != 0) {
          symbol.StringValue += stringByte;
        }
        break;
      case 0x05: // Dual (INT format) 4 bytes, followed by string format.
        symbol.IntValue = readInt32();
        while ((stringByte = readByte()) != 0) {
          symbol.StringValue += stringByte;
        }
        break;
      case 0x06: // DUAL (Double format) 8 bytes followed by string format.
        // XXX: Not endian safe.
        d = readDouble();
        symbol.DoubleValue = d;

        // Read string.
        while ((stringByte = readByte()) != 0) {
          symbol.StringValue += stringByte;
        }
        break;
      default:
        printf("Unknown byte: 0x%02x\n", typeByte);
      }

      it->Symbols.push_back(symbol);
    }
  }

  // Sort fields by BitOffset
  std::sort(_hdr.Fields.begin(), _hdr.Fields.end(), less_than_bitOffset());

  DEBUG(printf("Total number of rows: %d\n", _hdr.NoOfRecords););
  size_t rowNumber = 0;

  DEBUG(
   printf("[\n");
   printf("  {\n"););

  if (_bufLen == 0) {
    if (!_eof) {
      readBytes();
    } else {
      return 0; // throw an error.
    }
  }
  DEBUG(dump_hex(0, _dataPtrStart, _bufLen););

  for (rowNumber = 0; rowNumber < _hdr.NoOfRecords; rowNumber++) {
    DEBUG(printf("==== ROW: %d ====\n", (int)rowNumber););
    // Read first row now;
    for (std::vector<QvdField>::iterator it = _hdr.Fields.begin();
        it != _hdr.Fields.end(); ++it) {
      if (it->BitWidth > 0) {
        DEBUG(printf("Parsing data for %s (%d), need to read %d bits for this field\n",
                     it->FieldName.c_str(), it->BitOffset, it->BitWidth););

        int idx = get_bits_index(it->BitWidth);
        if (it->Bias != 0)
          idx += it->Bias;
        DEBUG(printf("> Index = %d\n", idx););
        _hdr.Indices.push_back(idx);
        DEBUG(
        if (idx == -2) {
          printf("NULL\n");
          continue;
        });

        DEBUG(
        if (it->Symbols.size() == 0) {
          printf("NULL\n");
          continue;
        });

        DEBUG(
        QvdSymbol sym = it->Symbols[idx];
        switch (sym.Type) {
        case 0x01:
          printf("%d\n", sym.IntValue);
          break;
        case 0x02:
          printf("%f\n", sym.DoubleValue);
          break;
        case 0x04:
          printf("%s\n", sym.StringValue.c_str());
          break;
        case 0x05:
          printf("%u (%s)\n", (unsigned int)sym.IntValue, sym.StringValue.c_str());
          break;
        case 0x06:
          printf("%f (%s)\n", sym.DoubleValue, sym.StringValue.c_str());
          break;
        default:
          printf("Unknown value\n");
          break;
        });
      }

    }
  }
  DEBUG(
  printf("  }\n");
  printf("]\n"););
  return true;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x48, %rsp
movq %rdi, %rbx
movq 0x98(%rdi), %r14
movq 0xa0(%rdi), %rbp
cmpq %rbp, %r14
je 0x5672
leaq 0x18(%rsp), %r15
leaq 0x28(%rsp), %r13
cmpl $0x0, 0x98(%r14)
je 0x565b
leaq 0xa8(%r14), %rbp
xorl %r12d, %r12d
movq %rbx, %rdi
callq 0x42a0
movq %r13, 0x18(%rsp)
xorl %ecx, %ecx
movq %rcx, 0x20(%rsp)
movb $0x0, 0x28(%rsp)
movl $0x0, 0x38(%rsp)
movq %rcx, 0x40(%rsp)
movzbl %al, %esi
movl %esi, 0x10(%rsp)
leal -0x1(%rsi), %eax
cmpl $0x5, %eax
ja 0x5578
leaq 0x4bd8(%rip), %rcx      # 0xa120
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movq %rbx, %rdi
callq 0x4290
movl %eax, 0x38(%rsp)
jmp 0x55b2
movq %rbx, %rdi
callq 0x42a0
testb %al, %al
je 0x55b2
movsbl %al, %esi
movq %r15, %rdi
callq 0x42b0
jmp 0x555f
leaq 0x4bd4(%rip), %rdi      # 0xa153
xorl %eax, %eax
callq 0x4030
jmp 0x55b2
xorl %r13d, %r13d
movq %rbx, %rdi
callq 0x42a0
movb %al, 0x8(%rsp,%r13)
incq %r13
cmpq $0x8, %r13
jne 0x558b
movsd 0x8(%rsp), %xmm0
movsd %xmm0, 0x40(%rsp)
leaq 0x28(%rsp), %r13
movq %rbp, %rdi
leaq 0x10(%rsp), %rsi
callq 0x42c0
movq 0x18(%rsp), %rdi
cmpq %r13, %rdi
je 0x55d6
movq 0x28(%rsp), %rsi
incq %rsi
callq 0x4360
incl %r12d
cmpl 0x98(%r14), %r12d
jb 0x550c
jmp 0x5654
movq %rbx, %rdi
callq 0x4290
movl %eax, 0x38(%rsp)
movq %rbx, %rdi
callq 0x42a0
testb %al, %al
je 0x55b2
movsbl %al, %esi
movq %r15, %rdi
callq 0x42b0
jmp 0x55f4
xorl %r13d, %r13d
movq %rbx, %rdi
callq 0x42a0
movb %al, 0x8(%rsp,%r13)
incq %r13
cmpq $0x8, %r13
jne 0x5610
movsd 0x8(%rsp), %xmm0
movsd %xmm0, 0x40(%rsp)
leaq 0x28(%rsp), %r13
movq %rbx, %rdi
callq 0x42a0
testb %al, %al
je 0x55b2
movsbl %al, %esi
movq %r15, %rdi
callq 0x42b0
jmp 0x5637
movq 0xa0(%rbx), %rbp
addq $0xc0, %r14
cmpq %rbp, %r14
jne 0x54f4
movq 0x98(%rbx), %r14
cmpq %rbp, %r14
je 0x56b2
movq %rbp, %rax
subq %r14, %rax
sarq $0x6, %rax
movabsq $-0x5555555555555555, %rcx # imm = 0xAAAAAAAAAAAAAAAB
imulq %rax, %rcx
bsrq %rcx, %rdx
xorl $0x3f, %edx
addl %edx, %edx
xorq $0x7e, %rdx
movq %r14, %rdi
movq %rbp, %rsi
callq 0x41d0
movq %r14, %rdi
movq %rbp, %rsi
callq 0x4340
cmpq $0x0, 0x2138(%rbx)
jne 0x5709
cmpb $0x0, 0x2140(%rbx)
je 0x56cc
xorl %ebp, %ebp
jmp 0x57ac
leaq 0x130(%rbx), %r14
movq 0x128(%rbx), %rcx
movl $0x1, %esi
movl $0x2000, %edx           # imm = 0x2000
movq %r14, %rdi
callq 0x44b0
cmpq $0x1fff, %rax           # imm = 0x1FFF
ja 0x56fb
movb $0x1, 0x2140(%rbx)
movq %r14, 0x2130(%rbx)
movq %rax, 0x2138(%rbx)
movl 0x8c(%rbx), %ecx
movb $0x1, %bpl
testl %ecx, %ecx
je 0x57ac
leaq 0xc8(%rbx), %r14
movq 0xa0(%rbx), %rax
xorl %r12d, %r12d
leaq 0x10(%rsp), %r15
movq 0x98(%rbx), %r13
cmpq %rax, %r13
je 0x57a2
movl 0x24(%r13), %esi
testq %rsi, %rsi
je 0x5790
movq %rbx, %rdi
callq 0x4510
movl %eax, 0x10(%rsp)
movl 0x28(%r13), %ecx
testl %ecx, %ecx
je 0x575f
addl %ecx, %eax
movl %eax, 0x10(%rsp)
movq 0xd0(%rbx), %rsi
cmpq 0xd8(%rbx), %rsi
je 0x577e
movl %eax, (%rsi)
addq $0x4, %rsi
movq %rsi, 0xd0(%rbx)
jmp 0x5789
movq %r14, %rdi
movq %r15, %rdx
callq 0x40e0
movq 0xa0(%rbx), %rax
addq $0xc0, %r13
cmpq %rax, %r13
jne 0x573c
movl 0x8c(%rbx), %ecx
incq %r12
movl %ecx, %edx
cmpq %rdx, %r12
jb 0x5730
movl %ebp, %eax
addq $0x48, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
jmp 0x57c3
jmp 0x57c3
jmp 0x57c3
movq %rax, %rbx
movq 0x18(%rsp), %rdi
cmpq %r13, %rdi
je 0x57dd
movq 0x28(%rsp), %rsi
incq %rsi
callq 0x4360
movq %rbx, %rdi
callq 0x45b0
nop