// File: /workspace/github_cpp_makefile_star2_O2/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 $0x38, %rsp
movq %rdi, %rbx
movq 0x98(%rdi), %rbp
leaq 0x8(%rsp), %r14
leaq 0x2c20(%rip), %r15      # 0x9120
movq 0xa0(%rbx), %rsi
cmpq %rsi, %rbp
je 0x661e
leaq 0xa8(%rbp), %r13
xorl %r12d, %r12d
cmpl 0x98(%rbp), %r12d
jae 0x6612
movq %rbx, %rdi
callq 0x53b0
leaq 0x18(%rsp), %rcx
movq %rcx, 0x8(%rsp)
andq $0x0, 0x10(%rsp)
movb $0x0, 0x18(%rsp)
andl $0x0, 0x28(%rsp)
andq $0x0, 0x30(%rsp)
movzbl %al, %esi
movl %esi, (%rsp)
leal -0x1(%rsi), %eax
cmpl $0x5, %eax
ja 0x658d
movslq (%r15,%rax,4), %rax
addq %r15, %rax
jmpq *%rax
movq %rbx, %rdi
callq 0x53a0
movl %eax, 0x28(%rsp)
jmp 0x65ab
movq %rbx, %rdi
callq 0x53b0
testb %al, %al
je 0x65ab
movsbl %al, %esi
movq %r14, %rdi
callq 0x53c0
jmp 0x6574
leaq 0x2ba7(%rip), %rdi      # 0x913b
xorl %eax, %eax
callq 0x5050
jmp 0x65ab
movq %rbx, %rdi
callq 0x5580
movsd %xmm0, 0x30(%rsp)
movq %r13, %rdi
movq %rsp, %rsi
callq 0x53d0
movq %r14, %rdi
callq 0x5200
incl %r12d
jmp 0x651a
movq %rbx, %rdi
callq 0x53a0
movl %eax, 0x28(%rsp)
movq %rbx, %rdi
callq 0x53b0
testb %al, %al
je 0x65ab
movsbl %al, %esi
movq %r14, %rdi
callq 0x53c0
jmp 0x65d2
movq %rbx, %rdi
callq 0x5580
movsd %xmm0, 0x30(%rsp)
movq %rbx, %rdi
callq 0x53b0
testb %al, %al
je 0x65ab
movsbl %al, %esi
movq %r14, %rdi
callq 0x53c0
jmp 0x65f9
addq $0xc0, %rbp
jmp 0x6500
movq 0x98(%rbx), %rdi
callq 0x50c0
cmpq $0x0, 0x2138(%rbx)
jne 0x6649
cmpb $0x0, 0x2140(%rbx)
je 0x6641
xorl %eax, %eax
jmp 0x66ad
movq %rbx, %rdi
callq 0x5830
leaq 0xc8(%rbx), %r14
xorl %r12d, %r12d
movq %rsp, %r15
movl 0x8c(%rbx), %eax
cmpq %rax, %r12
jae 0x66ab
movq 0x98(%rbx), %r13
cmpq 0xa0(%rbx), %r13
je 0x66a6
movl 0x24(%r13), %esi
testq %rsi, %rsi
je 0x669d
movq %rbx, %rdi
callq 0x56e0
movl %eax, (%rsp)
movl 0x28(%r13), %ecx
testl %ecx, %ecx
je 0x6692
addl %eax, %ecx
movl %ecx, (%rsp)
movq %r14, %rdi
movq %r15, %rsi
callq 0x5090
addq $0xc0, %r13
jmp 0x6668
incq %r12
jmp 0x6656
movb $0x1, %al
addq $0x38, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
jmp 0x66c2
jmp 0x66c2
jmp 0x66c2
movq %rax, %rbx
movq %r14, %rdi
callq 0x5200
movq %rbx, %rdi
callq 0x57c0
nop