// File: 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
movq %rsp, %rbp
subq $0x100, %rsp            # imm = 0x100
movq %rdi, -0x10(%rbp)
movq -0x10(%rbp), %rdi
movq %rdi, -0xc0(%rbp)
addq $0x98, %rdi
callq 0xb560
movq %rax, -0x18(%rbp)
movq -0xc0(%rbp), %rdi
addq $0x98, %rdi
callq 0xae30
movq %rax, -0x20(%rbp)
leaq -0x18(%rbp), %rdi
leaq -0x20(%rbp), %rsi
callq 0xb360
testb $0x1, %al
jne 0xd567
jmp 0xd7a3
movl $0x0, -0x24(%rbp)
movl -0x24(%rbp), %eax
movl %eax, -0xc4(%rbp)
leaq -0x18(%rbp), %rdi
callq 0xb440
movq %rax, %rcx
movl -0xc4(%rbp), %eax
cmpl 0x98(%rcx), %eax
jae 0xd793
movq -0xc0(%rbp), %rdi
callq 0xa980
movb %al, -0x25(%rbp)
leaq -0x60(%rbp), %rdi
callq 0xa110
movzbl -0x25(%rbp), %eax
movl %eax, -0x60(%rbp)
movzbl -0x25(%rbp), %eax
decl %eax
movl %eax, %ecx
movq %rcx, -0xd0(%rbp)
subl $0x5, %eax
ja 0xd748
movq -0xd0(%rbp), %rax
leaq 0x5b46(%rip), %rcx      # 0x13120
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movq -0xc0(%rbp), %rdi
callq 0xa970
movl %eax, -0xd4(%rbp)
jmp 0xd5f7
movl -0xd4(%rbp), %eax
movl %eax, -0x38(%rbp)
jmp 0xd75e
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x78(%rbp)
movl %eax, -0x7c(%rbp)
leaq -0x60(%rbp), %rdi
callq 0xb2d0
jmp 0xd961
movq -0xc0(%rbp), %rdi
callq 0xad70
movsd %xmm0, -0xe0(%rbp)
jmp 0xd635
movsd -0xe0(%rbp), %xmm0
movsd %xmm0, -0x70(%rbp)
movsd -0x70(%rbp), %xmm0
movsd %xmm0, -0x30(%rbp)
jmp 0xd75e
jmp 0xd653
movq -0xc0(%rbp), %rdi
callq 0xa980
movb %al, -0xe1(%rbp)
jmp 0xd667
movb -0xe1(%rbp), %al
movb %al, -0x61(%rbp)
movsbl %al, %eax
cmpl $0x0, %eax
je 0xd689
movsbl -0x61(%rbp), %esi
leaq -0x58(%rbp), %rdi
callq 0xa6e0
jmp 0xd687
jmp 0xd653
jmp 0xd75e
movq -0xc0(%rbp), %rdi
callq 0xa970
movl %eax, -0xe8(%rbp)
jmp 0xd6a2
movl -0xe8(%rbp), %eax
movl %eax, -0x38(%rbp)
movq -0xc0(%rbp), %rdi
callq 0xa980
movb %al, -0xe9(%rbp)
jmp 0xd6bf
movb -0xe9(%rbp), %al
movb %al, -0x61(%rbp)
movsbl %al, %eax
cmpl $0x0, %eax
je 0xd6e1
movsbl -0x61(%rbp), %esi
leaq -0x58(%rbp), %rdi
callq 0xa6e0
jmp 0xd6df
jmp 0xd6ab
jmp 0xd75e
movq -0xc0(%rbp), %rdi
callq 0xad70
movsd %xmm0, -0xf8(%rbp)
jmp 0xd6f9
movsd -0xf8(%rbp), %xmm0
movsd %xmm0, -0x70(%rbp)
movsd -0x70(%rbp), %xmm0
movsd %xmm0, -0x30(%rbp)
movq -0xc0(%rbp), %rdi
callq 0xa980
movb %al, -0xf9(%rbp)
jmp 0xd724
movb -0xf9(%rbp), %al
movb %al, -0x61(%rbp)
movsbl %al, %eax
cmpl $0x0, %eax
je 0xd746
movsbl -0x61(%rbp), %esi
leaq -0x58(%rbp), %rdi
callq 0xa6e0
jmp 0xd744
jmp 0xd710
jmp 0xd75e
movzbl -0x25(%rbp), %esi
leaq 0x59e8(%rip), %rdi      # 0x1313b
xorl %eax, %eax
callq 0xa070
jmp 0xd75c
jmp 0xd75e
leaq -0x18(%rbp), %rdi
callq 0xb440
movq %rax, %rdi
addq $0xa8, %rdi
leaq -0x60(%rbp), %rsi
callq 0xa9a0
jmp 0xd77c
leaq -0x60(%rbp), %rdi
callq 0xb2d0
movl -0x24(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x24(%rbp)
jmp 0xd56e
jmp 0xd795
leaq -0x18(%rbp), %rdi
callq 0xa520
jmp 0xd53a
movq -0xc0(%rbp), %rdi
addq $0x98, %rdi
callq 0xb560
movq -0xc0(%rbp), %rdi
movq %rax, -0x88(%rbp)
addq $0x98, %rdi
callq 0xae30
movq %rax, -0x90(%rbp)
movq -0x88(%rbp), %rdi
movq -0x90(%rbp), %rsi
callq 0xb390
movq -0xc0(%rbp), %rax
movq $0x0, -0xa0(%rbp)
cmpq $0x0, 0x2138(%rax)
jne 0xd82f
movq -0xc0(%rbp), %rax
testb $0x1, 0x2140(%rax)
jne 0xd824
movq -0xc0(%rbp), %rdi
callq 0xb500
jmp 0xd82d
movb $0x0, -0x1(%rbp)
jmp 0xd953
jmp 0xd82f
movq $0x0, -0xa0(%rbp)
movq -0xc0(%rbp), %rcx
movq -0xa0(%rbp), %rax
movl 0x8c(%rcx), %ecx
cmpq %rcx, %rax
jae 0xd94f
movq -0xc0(%rbp), %rdi
addq $0x98, %rdi
callq 0xb560
movq %rax, -0xa8(%rbp)
movq -0xc0(%rbp), %rdi
addq $0x98, %rdi
callq 0xae30
movq %rax, -0xb0(%rbp)
leaq -0xa8(%rbp), %rdi
leaq -0xb0(%rbp), %rsi
callq 0xb360
testb $0x1, %al
jne 0xd8a7
jmp 0xd936
leaq -0xa8(%rbp), %rdi
callq 0xb440
cmpl $0x0, 0x24(%rax)
jbe 0xd923
leaq -0xa8(%rbp), %rdi
callq 0xb440
movq -0xc0(%rbp), %rdi
movl 0x24(%rax), %eax
movl %eax, %esi
callq 0xb140
movl %eax, -0xb4(%rbp)
leaq -0xa8(%rbp), %rdi
callq 0xb440
cmpl $0x0, 0x28(%rax)
je 0xd909
leaq -0xa8(%rbp), %rdi
callq 0xb440
movl 0x28(%rax), %eax
addl -0xb4(%rbp), %eax
movl %eax, -0xb4(%rbp)
movq -0xc0(%rbp), %rdi
addq $0xc8, %rdi
leaq -0xb4(%rbp), %rsi
callq 0xa160
jmp 0xd925
leaq -0xa8(%rbp), %rdi
callq 0xa520
jmp 0xd871
jmp 0xd938
movq -0xa0(%rbp), %rax
addq $0x1, %rax
movq %rax, -0xa0(%rbp)
jmp 0xd83a
movb $0x1, -0x1(%rbp)
movb -0x1(%rbp), %al
andb $0x1, %al
addq $0x100, %rsp            # imm = 0x100
popq %rbp
retq
movq -0x78(%rbp), %rdi
callq 0xb340
nopw (%rax,%rax)