// File: /workspace/github_cpp_makefile_star2_O1/tsfn[P]doc2txt/src/doc_format.cpp
// Function: doc_format(Storage const&)
bool doc_format(const Storage &st) {
  const uchar *wds, *ts;
  uint wds_size, ts_size;

  // 取得WordDocument Stream (wds)
  if (!st.stream("WordDocument", &wds, &wds_size)) {
    return false;
  }

  // 取得Table Stream (ts)
  ushort flag1 = *(ushort *)((char *)wds + 0xA);
  bool is1Table = (flag1 & 0x0200) == 0x0200;
  if (!st.stream(is1Table ? "1Table" : "0Table", &ts, &ts_size)) {
    return false;
  }

  uint fcPlcfBtePapx = *(uint *)(wds + 258);
  uint lcbPlcfBtePapx = *(uint *)(wds + 258 + 4);
  uint n = (lcbPlcfBtePapx - 4) / 8;

  set< pair<uint, uint> > ranges;
  for (uint i = 0; i < n; ++i) {
    /* 读取PlcBtePapx中的信息（其实PlcBtePapx在Table Stream中） */
    int fc_start = *(int *)(ts + fcPlcfBtePapx + 4 * i);
    int fc_end = *(int *)(ts + fcPlcfBtePapx + 4 * i + 4);
    uint PnBtePapx = *(uint *)(ts + fcPlcfBtePapx + 4 * (n + 1 + i));

    const uchar *PapxFkp = wds + PnBtePapx * 512;
    uchar cpara = *(const uchar *)(PapxFkp + 511);

    for (uint i = 0; i < cpara; ++i) {
      // rgfc确定文本的位置
      uint rgfc_start = *(uint *)(PapxFkp + 4 * i);
      uint rgfc_end = *(uint *)(PapxFkp + 4 * i + 4);

      // bOffset找到PapxInFkp在PapxFkp中的位置
      uchar bOffset = *(uchar *)(PapxFkp + 4 * (cpara + 1) + 13 * i);

      // 找到PapxInFkp其中的cb, grpprlInPapx
      uchar cb = *(uchar *)(PapxFkp + bOffset * 2);

      // 得到GrpPrlAndIstd
      uint lcbGrpPrlAndIstd = 2 * cb - 1;
      const uchar *GrpPrlAndIstd = PapxFkp + bOffset * 2 + 1;
      if (cb == 0) {
        lcbGrpPrlAndIstd = *GrpPrlAndIstd * 2;
        GrpPrlAndIstd += 1;
      }

      // 根据GrpPrlAndIstd得到段落格式（Direct Paragraph Formatting）
      const uchar *grpprl = GrpPrlAndIstd + 2;
      uint lcb = lcbGrpPrlAndIstd - 1;
      static const int operand_size[8] = { 1, 1, 2, 4, 2, 2, -1, 3, };
      for (uint i = 0; i < lcb;) {
        ushort sprm = *(ushort *)(grpprl + i);
        uint spra = sprm / 8192;
        uint operand;
        i += 2;
        if (spra == 6) {
          i += 1 + *(uchar *)(grpprl + i);
        } else {
          if (operand_size[spra] == 1) {
            operand = *(uchar *)(grpprl + i);
          } else if (operand_size[spra] == 2) {
            operand = *(ushort *)(grpprl + i);
          } else if (operand_size[spra] == 3) {
            operand = *(uint *)(grpprl + i) & 0x00FFFFFF;
          } else if (operand_size[spra] == 4) {
            operand = *(uint *)(grpprl + i);
          } else {
            operand = -1;
          }
          i += operand_size[spra];
        }
        if ((sprm == 0x2403 || sprm == 0x2416) && operand == 1) { // 居中
          ranges.insert(make_pair(rgfc_start, rgfc_end));
        }
      }
    }
  }

  /* 合并各个区间 */
  set< pair<uint, uint> >::iterator iter = ranges.begin(), jter, kter;
  while (iter != ranges.end()) {
    jter = iter;
    ++jter;
    while (jter != ranges.end() && iter->second == jter->first) {
      pair<uint, uint> temp = *iter;
      temp.second = jter->second;
      ranges.erase(iter);
      ranges.insert(temp);
      iter = ranges.find(temp);
      kter = jter;
      ++jter;
      ranges.erase(kter);
    }
    iter = jter;
  }

  /*
  FILE *temp_file = fopen("/dev/shm/middle.txt", "wb");
  for (iter = ranges.begin(); iter != ranges.end(); ++iter) {
    printf("range[%u,%u] is in middle\n", iter->first, iter->second);
    for (uint i = iter->first; i < iter->second && i < wds_size; ++i) {
      fputc(wds[i], temp_file);
    }
  }
  fclose(temp_file);
  */
  return true;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0xa8, %rsp
movq %rdi, %rbx
leaq 0x17fe(%rip), %rsi      # 0x4044
leaq -0x38(%rbp), %rdx
leaq -0x98(%rbp), %rcx
callq 0x1a94
testb %al, %al
je 0x2b5a
movq -0x38(%rbp), %rax
movzwl 0xa(%rax), %eax
btl $0x9, %eax
leaq 0x17e7(%rip), %rax      # 0x4058
leaq 0x17d9(%rip), %rsi      # 0x4051
cmovaeq %rax, %rsi
leaq -0x90(%rbp), %rdx
leaq -0x94(%rbp), %rcx
movq %rbx, %rdi
callq 0x1a94
testb %al, %al
je 0x2b5c
movl %eax, -0x3c(%rbp)
movq -0x38(%rbp), %rax
movl 0x102(%rax), %ecx
movq %rcx, -0x58(%rbp)
movl 0x106(%rax), %edx
addl $-0x4, %edx
leaq -0xc0(%rbp), %rcx
movl $0x0, (%rcx)
xorl %eax, %eax
movq %rax, 0x8(%rcx)
movq %rcx, 0x10(%rcx)
movq %rcx, 0x18(%rcx)
movq %rax, 0x20(%rcx)
cmpl $0x8, %edx
jb 0x2a9a
movq %rdx, %rax
shrl $0x3, %eax
leal 0x1(%rax), %ecx
movq %rcx, -0x50(%rbp)
cmpl $0x1, %eax
adcl $0x0, %eax
movq %rax, -0x48(%rbp)
xorl %edx, %edx
movq -0x90(%rbp), %rax
addq -0x58(%rbp), %rax
movq -0x50(%rbp), %rcx
movq %rdx, -0x60(%rbp)
addq %rdx, %rcx
movl (%rax,%rcx,4), %eax
movq -0x38(%rbp), %rsi
shll $0x9, %eax
movzbl 0x1ff(%rsi,%rax), %ecx
testq %rcx, %rcx
je 0x2a89
addq %rax, %rsi
leaq (%rsi,%rcx,4), %rax
addq $0x4, %rax
movq %rax, -0x78(%rbp)
xorl %edi, %edi
movq %rsi, -0x70(%rbp)
movq %rcx, -0x68(%rbp)
leaq (%rdi,%rdi,2), %rax
leaq (%rdi,%rax,4), %rax
movq -0x78(%rbp), %rcx
movzbl (%rcx,%rax), %eax
leaq (%rsi,%rax,2), %rax
movzbl (%rax), %ecx
testl %ecx, %ecx
je 0x2969
leal -0x1(,%rcx,2), %r13d
movl $0x1, %ecx
jmp 0x2976
movzbl 0x1(%rax), %r13d
addl %r13d, %r13d
movl $0x2, %ecx
decl %r13d
movq %rdi, -0x80(%rbp)
je 0x2a71
movl (%rsi,%rdi,4), %edx
movl 0x4(%rsi,%rdi,4), %esi
leaq (%rax,%rcx), %r15
addq $0x2, %r15
shlq $0x20, %rsi
orq %rdx, %rsi
movq %rsi, -0x88(%rbp)
xorl %ebx, %ebx
movl %ebx, %eax
movzwl (%r15,%rax), %ecx
movzwl %cx, %eax
shrl $0xd, %ecx
movl %ebx, %r14d
addl $0x2, %r14d
cmpl $0x6, %ecx
jne 0x29c7
movl %r14d, %ecx
movzbl (%r15,%rcx), %ebx
incl %ebx
jmp 0x2a30
cmpl $0x2000, %eax           # imm = 0x2000
setae %dl
cmpw $0x1, %cx
setne %sil
testb %sil, %dl
jne 0x29e6
movl %r14d, %edx
movzbl (%r15,%rdx), %r12d
jmp 0x2a26
movl $0x34, %edx
btl %ecx, %edx
jb 0x2a15
cmpw $0x3, %cx
je 0x2a1f
movzwl %cx, %edx
movl $0xffffffff, %r12d      # imm = 0xFFFFFFFF
cmpl $0x7, %edx
jne 0x2a26
movl %r14d, %edx
movl (%r15,%rdx), %r12d
movl $0xffffff, %edx         # imm = 0xFFFFFF
andl %edx, %r12d
jmp 0x2a26
movl %r14d, %edx
movzwl (%r15,%rdx), %r12d
jmp 0x2a26
movl %r14d, %edx
movl (%r15,%rdx), %r12d
leaq 0x16e3(%rip), %rdx      # 0x4110
movl (%rdx,%rcx,4), %ebx
cmpl $0x2403, %eax           # imm = 0x2403
setne %cl
cmpl $0x2416, %eax           # imm = 0x2416
setne %al
testb %al, %cl
jne 0x2a65
cmpl $0x1, %r12d
jne 0x2a65
movq -0x88(%rbp), %rax
movq %rax, -0x30(%rbp)
leaq -0xc8(%rbp), %rdi
leaq -0x30(%rbp), %rsi
callq 0x2be8
addl %r14d, %ebx
cmpl %r13d, %ebx
jb 0x29a2
movq -0x80(%rbp), %rdi
incq %rdi
movq -0x68(%rbp), %rcx
cmpq %rcx, %rdi
movq -0x70(%rbp), %rsi
jne 0x293f
movq -0x60(%rbp), %rdx
incq %rdx
cmpq -0x48(%rbp), %rdx
jne 0x28f5
movq -0xb0(%rbp), %r12
leaq -0xc0(%rbp), %r13
cmpq %r13, %r12
je 0x2b49
leaq -0xc8(%rbp), %r14
leaq -0x30(%rbp), %r15
movq %r12, %rdi
callq 0x1120
movq %rax, %rbx
cmpq %r13, %rax
je 0x2b30
movl 0x24(%r12), %eax
cmpl 0x20(%rbx), %eax
jne 0x2b30
movq 0x20(%r12), %rax
movq %rax, -0x30(%rbp)
movl 0x24(%rbx), %eax
movl %eax, -0x2c(%rbp)
movq %r14, %rdi
movq %r12, %rsi
callq 0x2d58
movq %r14, %rdi
movq %r15, %rsi
callq 0x2d9e
movq %r14, %rdi
movq %r15, %rsi
callq 0x2e6e
movq %rax, %r12
movq %rbx, %rdi
callq 0x1120
movq %rax, %r13
movq %r14, %rdi
movq %rbx, %rsi
callq 0x2d58
movq %r13, %rbx
leaq -0xc0(%rbp), %rax
cmpq %rax, %r13
jne 0x2acc
jmp 0x2b33
movq %rbx, %r13
movq %r13, %r12
leaq -0xc0(%rbp), %rax
cmpq %rax, %r13
movq %rax, %r13
jne 0x2abc
leaq -0xc8(%rbp), %rdi
callq 0x2b8a
movl -0x3c(%rbp), %eax
jmp 0x2b5c
xorl %eax, %eax
addq $0xa8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
jmp 0x2b72
jmp 0x2b72
movq %rax, %rbx
leaq -0xc8(%rbp), %rdi
callq 0x2b8a
movq %rbx, %rdi
callq 0x11a0
nop