user: What is the c source code of the assembly code below?

```asm
<ei_get_type_internal>:
  endbr64
  push   %rbp
  mov    %rsp,%rbp
  mov    %rdi,-0x18(%rbp)
  mov    %rsi,-0x20(%rbp)
  mov    %rdx,-0x28(%rbp)
  mov    %rcx,-0x30(%rbp)
  mov    -0x20(%rbp),%rax
  mov    (%rax),%eax
  movslq %eax,%rdx
  mov    -0x18(%rbp),%rax
  add    %rdx,%rax
  mov    %rax,-0x8(%rbp)
  addq   $0x1,-0x8(%rbp)
  mov    -0x8(%rbp),%rax
  sub    $0x1,%rax
  movzbl (%rax),%eax
  movzbl %al,%edx
  mov    -0x28(%rbp),%rax
  mov    %edx,(%rax)
  mov    -0x28(%rbp),%rax
  mov    (%rax),%eax
  sub    $0x64,%eax
  cmp    $0xb,%eax
  ja     L50
  mov    %eax,%eax
  lea    0x0(,%rax,4),%rdx
  lea    D4(%rip),%rax
  mov    (%rdx,%rax,1),%eax
  cltq
  lea    D4(%rip),%rdx
  add    %rdx,%rax
  notrack jmp *%rax
  addq   $0x1,-0x8(%rbp)
  mov    -0x8(%rbp),%rax
  sub    $0x1,%rax
  movzbl (%rax),%eax
  movzbl %al,%edx
  mov    -0x30(%rbp),%rax
  mov    %edx,(%rax)
  jmp    L42
  addq   $0x2,-0x8(%rbp)
  mov    -0x8(%rbp),%rax
  sub    $0x2,%rax
  movzbl (%rax),%eax
  movzbl %al,%eax
  shl    $0x8,%eax
  mov    %eax,%edx
  mov    -0x8(%rbp),%rax
  sub    $0x1,%rax
  movzbl (%rax),%eax
  movzbl %al,%eax
  or     %edx,%eax
  movzwl %ax,%edx
  mov    -0x30(%rbp),%rax
  mov    %edx,(%rax)
  jmp    L42
  addq   $0x4,-0x8(%rbp)
  mov    -0x8(%rbp),%rax
  sub    $0x4,%rax
  movzbl (%rax),%eax
  movzbl %al,%eax
  shl    $0x18,%eax
  mov    %eax,%edx
  mov    -0x8(%rbp),%rax
  sub    $0x3,%rax
  movzbl (%rax),%eax
  movzbl %al,%eax
  shl    $0x10,%eax
  or     %eax,%edx
  mov    -0x8(%rbp),%rax
  sub    $0x2,%rax
  movzbl (%rax),%eax
  movzbl %al,%eax
  shl    $0x8,%eax
  or     %eax,%edx
  mov    -0x8(%rbp),%rax
  sub    $0x1,%rax
  movzbl (%rax),%eax
  movzbl %al,%eax
  or     %eax,%edx
  mov    -0x30(%rbp),%rax
  mov    %edx,(%rax)
  jmp    L42
  addq   $0x1,-0x8(%rbp)
  mov    -0x8(%rbp),%rax
  sub    $0x1,%rax
  movzbl (%rax),%eax
  movzbl %al,%eax
  add    $0x1,%eax
  mov    %eax,%edx
  shr    $0x1f,%edx
  add    %edx,%eax
  sar    %eax
  mov    %eax,%edx
  mov    -0x30(%rbp),%rax
  mov    %edx,(%rax)
  jmp    L42
  addq   $0x4,-0x8(%rbp)
  mov    -0x8(%rbp),%rax
  sub    $0x4,%rax
  movzbl (%rax),%eax
  movzbl %al,%eax
  shl    $0x18,%eax
  mov    %eax,%edx
  mov    -0x8(%rbp),%rax
  sub    $0x3,%rax
  movzbl (%rax),%eax
  movzbl %al,%eax
  shl    $0x10,%eax
  or     %eax,%edx
  mov    -0x8(%rbp),%rax
  sub    $0x2,%rax
  movzbl (%rax),%eax
  movzbl %al,%eax
  shl    $0x8,%eax
  or     %eax,%edx
  mov    -0x8(%rbp),%rax
  sub    $0x1,%rax
  movzbl (%rax),%eax
  movzbl %al,%eax
  or     %edx,%eax
  add    $0x1,%eax
  mov    %eax,%edx
  shr    $0x1f,%edx
  add    %edx,%eax
  sar    %eax
  mov    %eax,%edx
  mov    -0x30(%rbp),%rax
  mov    %edx,(%rax)
  jmp    L42
L50:
  mov    -0x30(%rbp),%rax
  movl   $0x0,(%rax)
  nop
L42:
  mov    $0x0,%eax
  pop    %rbp
  ret
```

assistant: ```c
int ei_get_type_internal(const char *buf, const int *index, int *type, int *len) {
  const char *s = buf + *index;
  *type = ((s) += 1, ((unsigned char *)(s))[-1] & 0xff);
  switch (*type) {
  case 'h':
    *len = ((s) += 1, ((unsigned char *)(s))[-1] & 0xff);
    break;
  case 'd':
  case 'k':
    *len = ((s) += 2, (((((unsigned char *)(s))[-2] << 8) | ((unsigned char *)(s))[-1])) & 0xffff);
    break;
  case 'i':
  case 'l':
  case 'm':
    *len = ((s) += 4, ((((unsigned char *)(s))[-4] << 24) | (((unsigned char *)(s))[-3] << 16) | (((unsigned char *)(s))[-2] << 8) | ((unsigned char *)(s))[-1]));
    break;
  case 'n':
    *len = (((s) += 1, ((unsigned char *)(s))[-1] & 0xff) + 1) / 2;
    break;
  case 'o':
    *len = (((s) += 4, ((((unsigned char *)(s))[-4] << 24) | (((unsigned char *)(s))[-3] << 16) | (((unsigned char *)(s))[-2] << 8) | ((unsigned char *)(s))[-1])) + 1) / 2;
    break;
  default:
    *len = 0;
    break;
  }
  return 0;
}
```