user: 请从给定的汇编指令推导出C源代码:

```asm
<calculate_packet_size>:
  endbr64
  mov    %rdi,%rax
  mov    $0x0,%edx
  cmpb   $0x0,(%rdi)
  jne    L163
  cmpb   $0x0,0x1(%rdi)
  jne    L163
  cmpb   $0x1,0x2(%rdi)
  jne    L163
  movzbl 0x3(%rdi),%esi
  lea    0x4d(%rsi),%edx
  cmp    $0x3c,%dl
  ja     L62
  movzbl %dl,%edx
  lea    D7(%rip),%rcx
  movslq (%rcx,%rdx,4),%rdx
  add    %rcx,%rdx
  notrack jmp *%rdx
L62:
  mov    $0x0,%edx
  jmp    L163
  movzbl 0x4(%rdi),%edx
  mov    %edx,%ecx
  and    $0xffffffc4,%ecx
  cmp    $0x44,%cl
  je     L128
  mov    %edx,%ecx
  and    $0xfffffff1,%ecx
  mov    $0x0,%edx
  cmp    $0x21,%cl
  jne    L163
  testb  $0x1,0x6(%rdi)
  je     L163
  testb  $0x1,0x8(%rdi)
  je     L163
  cmpb   $0x0,0x9(%rdi)
  jns    L163
  movzbl 0xb(%rdi),%edx
  shl    $0x1f,%edx
  sar    $0x1f,%edx
  and    $0xc,%edx
  jmp    L163
L128:
  mov    $0x0,%edx
  testb  $0x4,0x6(%rdi)
  je     L163
  testb  $0x4,0x8(%rdi)
  je     L163
  testb  $0x1,0x9(%rdi)
  je     L163
  movzbl 0xc(%rdi),%ecx
  and    $0x3,%ecx
  cmp    $0x3,%cl
  jne    L163
  movzbl 0xd(%rdi),%eax
  and    $0x7,%eax
  lea    0xe(%rax),%edx
  jmp    L163
  mov    $0x0,%edx
  testb  $0x20,0xa(%rdi)
  je     L163
  movzbl 0xb(%rdi),%eax
  and    $0x3,%eax
  cmp    $0x1,%al
  sbb    %edx,%edx
  and    $0xffffffc0,%edx
  add    $0x4c,%edx
  jmp    L163
  movzbl 0x4(%rdi),%edx
  mov    %edx,%ecx
  and    $0xfffffff0,%ecx
  cmp    $0x10,%cl
  je     L41
  and    $0xfffffff1,%edx
  cmp    $0x20,%dl
  je     L112
  cmp    $0x21,%dl
  jne    L183
  mov    $0xc,%edx
  testb  $0x2,0x9(%rdi)
  je     L183
  jmp    L163
L41:
  movzbl 0x7(%rdi),%edx
  shl    $0x1f,%edx
  sar    $0x1f,%edx
  and    $0xa,%edx
  jmp    L163
L112:
  mov    $0x9,%edx
  testb  $0x2,0x6(%rdi)
  jne    L163
L183:
  mov    $0x0,%edx
  cmp    $0x40,%cl
  jne    L163
  movzbl 0x8(%rax),%eax
  and    $0x40,%eax
  cmp    $0x1,%al
  sbb    %edx,%edx
  and    $0xfffffffe,%edx
  add    $0xb,%edx
  jmp    L163
  movzbl 0x5(%rdi),%edx
  shr    $0x6,%dl
  and    $0x1,%edx
  shl    $0x3,%edx
L163:
  mov    %edx,%eax
  ret
  movzbl 0x4(%rdi),%edx
  shl    $0x8,%edx
  movzbl 0x5(%rdi),%eax
  lea    0x6(%rdx,%rax,1),%edx
  jmp    L163
  movzbl 0x4(%rdi),%edx
  shl    $0x8,%edx
  movzbl 0x5(%rdi),%eax
  lea    0x6(%rdx,%rax,1),%edx
  jmp    L163
  mov    $0x4,%edx
  jmp    L163
```

assistant: ```c
unsigned int calculate_packet_size(const unsigned char *buffer) {
  if (buffer[0] != 0 || buffer[1] != 0 || buffer[2] != 1)
    return 0;
  switch (buffer[3]) {
  case 0xBA:
    if ((buffer[4] & 0xc4) == 0x44 && (buffer[6] & 4) == 4 && (buffer[8] & 4) == 4 && (buffer[9] & 1) == 1 && (buffer[12] & 3) == 3)
      return (buffer[13] & 0x7) + 14;
    if ((buffer[4] & 0xF1) == 0x21 && (buffer[6] & 1) == 1 && (buffer[8] & 1) == 1 && (buffer[9] & 0x80) == 0x80 && (buffer[11] & 1) == 1)
      return 12;
    return 0;
  case 0xB3:
    if ((buffer[10] & 0x20) == 0x20) {
      if ((buffer[11] & 3) != 0)
        return 12 + 64;
      return 12;
    }
    return 0;
  case 0xB5:
    if ((buffer[4] & 0xF0) == 0x10 && (buffer[7] & 1) == 1)
      return 10;
    if ((buffer[4] & 0xF0) == 0x20 && (buffer[4] & 1) == 0 && (buffer[6] & 2) == 2)
      return 9;
    if ((buffer[4] & 0xF0) == 0x20 && (buffer[4] & 1) == 1 && (buffer[9] & 2) == 2)
      return 12;
    if ((buffer[4] & 0xF0) == 0x40) {
      if ((buffer[8] & 0x40) == 0)
        return 9;
      else
        return 11;
    }
    return 0;
  case 0xB8:
    if ((buffer[5] & 0x40) == 0x40)
      return 8;
    return 0;
  case 0xB9:
    return 4;
  case 0xBD:
  case 0xC0 ... 0xDF:
  case 0xE0 ... 0xEF:
    return (buffer[4] << 8) + buffer[5] + 6;
  case 0xBB:
  case 0xBE:
  case 0xBF:
    return (buffer[4] << 8) + buffer[5] + 6;
  case 0:
    return 0;
  default:
    return 0;
  }
}
```