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

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

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;
  }
}
```