// File: /workspace/github_cpp_makefile_star2_O2/williewillus[P]panda_scratchpad/src/wrapper/DiskMod.cpp
// Function: wrapper::DiskMod::Deserialize(std::shared_ptr<char>, wrapper::DiskMod&)
int DiskMod::Deserialize(shared_ptr<char> data, DiskMod &res) {
  res.Reset();

  // Skip the first uint64 which is the size of this region. This is a blind
  // deserialization of the object!
  char *data_ptr = data.get();
  data_ptr += sizeof(uint64_t);

  uint16_t mod_type;
  uint16_t mod_opts;
  memcpy(&mod_type, data_ptr, sizeof(uint16_t));
  data_ptr += sizeof(uint16_t);
  res.mod_type = (DiskMod::ModType) be16toh(mod_type);

  memcpy(&mod_opts, data_ptr, sizeof(uint16_t));
  data_ptr += sizeof(uint16_t);
  res.mod_opts = (DiskMod::ModOpts) be16toh(mod_opts);

  if (res.mod_type == DiskMod::kCheckpointMod ||
    res.mod_type == DiskMod::kSyncMod) {
    // No more left to do here.
    return 0;
  }

  // Small buffer to read characters into so we aren't adding to a string one
  // character at a time until the end of the string.
  const unsigned int tmp_size = 128;
  char tmp[tmp_size];
  memset(tmp, 0, tmp_size);
  unsigned int chars_read = 0;
  while (data_ptr[0] != '\0') {
    // We still haven't seen a null terminator, so read another character.
    tmp[chars_read] = data_ptr[0];
    ++chars_read;
    if (chars_read == tmp_size - 1) {
      // Fall into this at one character short so that we have an automatic null
      // terminator
      res.path += tmp;
      chars_read = 0;
      // Required because we just add the char[] to the string and we don't want
      // extra junk. An alternative would be to make sure you always had a null
      // terminator the character after the one that was just assigned.
      memset(tmp, 0, tmp_size);
    }
    ++data_ptr;
  }
  // Add the remaining data that is in tmp.
  res.path += tmp;
  // Move past the null terminating character.
  ++data_ptr;

  res.directory_mod = (bool) data_ptr[0];
  ++data_ptr;

  if (res.mod_type == DiskMod::kFsyncMod ||
      res.mod_type == DiskMod::kCreateMod) {
    return 0;
  }

  uint64_t file_mod_location;
  uint64_t file_mod_len;
  memcpy(&file_mod_location, data_ptr, sizeof(uint64_t));
  data_ptr += sizeof(uint64_t);
  file_mod_location = be64toh(file_mod_location);
  res.file_mod_location = file_mod_location;

  memcpy(&file_mod_len, data_ptr, sizeof(uint64_t));
  data_ptr += sizeof(uint64_t);
  file_mod_len = be64toh(file_mod_len);
  res.file_mod_len = file_mod_len;

  // Some mods have file length and location, but no actual data associated with
  // them.
  if (res.mod_type == DiskMod::kSyncFileRangeMod ||
      res.mod_opts == DiskMod::kFallocateOpt ||
      res.mod_opts == DiskMod::kFallocateKeepSizeOpt ||
      res.mod_opts == DiskMod::kPunchHoleKeepSizeOpt ||
      res.mod_opts == DiskMod::kCollapseRangeOpt ||
      res.mod_opts == DiskMod::kZeroRangeOpt ||
      res.mod_opts == DiskMod::kZeroRangeKeepSizeOpt ||
      res.mod_opts == DiskMod::kInsertRangeOpt) {
    return 0;
  }

  if (res.file_mod_len > 0) {
    // Read the data for this mod.
    res.file_mod_data.reset(new (std::nothrow) char[res.file_mod_len],
        [](char *c) {delete[] c;});
    if (res.file_mod_data.get() == nullptr) {
      return -1;
    }
    memcpy(res.file_mod_data.get(), data_ptr, res.file_mod_len);
  }

  return 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0xa8, %rsp
movq %rsi, %rbx
movq %rdi, %r14
movq %rsi, %rdi
callq 0x8dcc
movq (%r14), %r14
movzwl 0x8(%r14), %eax
rolw $0x8, %ax
movzwl %ax, %eax
movl %eax, 0x20(%rbx)
movzwl 0xa(%r14), %ecx
rolw $0x8, %cx
movzwl %cx, %ecx
movl %ecx, 0x24(%rbx)
xorl %r15d, %r15d
cmpw $0x6, %ax
je 0x8d8a
cmpl $0x8, %eax
je 0x8d8a
addq $0xc, %r14
xorps %xmm0, %xmm0
leaq -0xb0(%rbp), %r15
movaps %xmm0, 0x70(%r15)
movaps %xmm0, 0x60(%r15)
movaps %xmm0, 0x50(%r15)
movaps %xmm0, 0x40(%r15)
movaps %xmm0, 0x30(%r15)
movaps %xmm0, 0x20(%r15)
movaps %xmm0, 0x10(%r15)
movaps %xmm0, (%r15)
xorl %eax, %eax
movb (%r14), %cl
testb %cl, %cl
je 0x8c75
movl %eax, %edx
movb %cl, -0xb0(%rbp,%rdx)
incl %eax
cmpl $0x7f, %eax
jne 0x8c70
movq %rbx, %rdi
movq %r15, %rsi
callq 0x5810
xorps %xmm0, %xmm0
movaps %xmm0, -0xb0(%rbp)
movaps %xmm0, -0xa0(%rbp)
movaps %xmm0, -0x90(%rbp)
movaps %xmm0, -0x80(%rbp)
movaps %xmm0, -0x70(%rbp)
movaps %xmm0, -0x60(%rbp)
movaps %xmm0, -0x50(%rbp)
movaps %xmm0, -0x40(%rbp)
xorl %eax, %eax
incq %r14
jmp 0x8c20
leaq -0xb0(%rbp), %rsi
movq %rbx, %rdi
callq 0x5810
cmpb $0x0, 0x1(%r14)
setne 0xb8(%rbx)
movl 0x20(%rbx), %eax
xorl %r15d, %r15d
testl %eax, %eax
je 0x8d8a
cmpl $0x7, %eax
je 0x8d8a
movq 0x2(%r14), %rcx
bswapq %rcx
movq %rcx, 0xd0(%rbx)
movq 0xa(%r14), %rcx
movq %rcx, %rdi
bswapq %rdi
movq %rdi, 0xd8(%rbx)
cmpl $0x9, %eax
je 0x8d8a
testq %rcx, %rcx
je 0x8d8a
movl 0x24(%rbx), %eax
addl $-0x2, %eax
cmpl $0x7, %eax
jb 0x8d8a
movq 0x112a2(%rip), %rsi     # 0x19f90
callq 0x5700
movq %rax, %r12
pushq $0x18
popq %rdi
callq 0x54a0
movq %rax, %r13
leaq -0x29(%rbp), %rax
leaq -0xd0(%rbp), %rdi
movq %rax, (%rdi)
movabsq $0x100000001, %rax      # imm = 0x100000001
movq %rax, 0x8(%r13)
leaq 0x10adc(%rip), %rax     # 0x19800
movq %rax, (%r13)
movq %r12, 0x10(%r13)
andq $0x0, 0x8(%rdi)
callq 0x8f06
movq 0xc0(%rbx), %rax
leaq -0xb8(%rbp), %rdi
movq %rax, -0x8(%rdi)
movq %r12, 0xc0(%rbx)
movq 0xc8(%rbx), %rax
movq %r13, 0xc8(%rbx)
movq %rax, (%rdi)
callq 0x7dbe
movq 0xc0(%rbx), %rdi
testq %rdi, %rdi
je 0x8d86
addq $0x12, %r14
movq 0xd8(%rbx), %rdx
movq %r14, %rsi
callq 0x53c0
jmp 0x8d8a
pushq $-0x1
popq %r15
movl %r15d, %eax
addq $0xa8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq %rax, %rdi
callq 0x51d0
movq %r12, %rdi
callq 0x8f1c
callq 0x5620
movq %rax, %rbx
callq 0x56f0
movq %rbx, %rdi
callq 0x5780
movq %rax, %rdi
callq 0x7562