user: Translate the below assembly code into C programming language:

```asm
<ts_sdt_add_service_descriptor>:
  endbr64
  push   %r15
  push   %r14
  push   %r13
  push   %r12
  push   %rbp
  push   %rbx
  sub    $0x18,%rsp
  mov    %rdi,(%rsp)
  mov    %rcx,%rbp
  mov    $0x0,%eax
  mov    %r8,%rcx
  or     %rbp,%rcx
  je     L104
  mov    %esi,%r14d
  mov    %edx,%r15d
  mov    %r8,%rbx
  test   %rbp,%rbp
  je     L41
  mov    %rbp,%rdi
  call   <strlen@plt>
  lea    0x4(%rax),%r12d
  mov    $0x1,%r13d
  test   %rbx,%rbx
  je     L151
L82:
  mov    %rbx,%rdi
  call   <strlen@plt>
  lea    0x1(%rax),%r13d
L151:
  add    %r12d,%r13d
  mov    %r13d,0xc(%rsp)
  cmp    $0x101,%r13d
  jg     L42
  mov    %r13d,%esi
  mov    $0x1,%edi
  call   <calloc@plt>
  mov    %rax,%r12
  movb   $0x48,(%rax)
  sub    $0x2,%r13d
  mov    %r13b,0x1(%rax)
  cmp    $0x1,%r15b
  mov    $0x1,%eax
  adc    $0x0,%al
L46:
  mov    %al,0x2(%r12)
  test   %rbp,%rbp
  je     L80
  mov    %rbp,%rdi
  call   <strlen@plt>
  mov    %al,0x3(%r12)
  movzbl 0x0(%rbp),%edx
  mov    $0x5,%r13d
  test   %dl,%dl
  je     L59
  mov    $0x5,%eax
L139:
  mov    %eax,%r13d
  mov    %dl,-0x1(%r12,%rax,1)
  add    $0x1,%rax
  movzbl -0x5(%rbp,%rax,1),%edx
  test   %dl,%dl
  jne    L139
L59:
  test   %rbx,%rbx
  je     L54
L21:
  cmpb   $0x0,(%rbx)
  je     L54
  mov    %rbx,%rdi
  call   <strlen@plt>
  mov    %rax,%rdx
  lea    0x1(%r13),%eax
  movslq %r13d,%r13
  mov    %dl,(%r12,%r13,1)
  movzbl (%rbx),%edx
  test   %dl,%dl
  je     L54
  cltq
  sub    %r13,%rbx
L135:
  mov    %dl,(%r12,%rax,1)
  add    $0x1,%rax
  movzbl -0x1(%rbx,%rax,1),%edx
  test   %dl,%dl
  jne    L135
L54:
  mov    0xc(%rsp),%ecx
  mov    %r12,%rdx
  mov    %r14d,%esi
  mov    (%rsp),%rdi
  call   <ts_sdt_add_stream@plt>
L104:
  add    $0x18,%rsp
  pop    %rbx
  pop    %rbp
  pop    %r12
  pop    %r13
  pop    %r14
  pop    %r15
  ret
L42:
  mov    %r13d,%esi
  lea    D0(%rip),%rdi
  call   <ts_LOGf@plt>
  mov    $0x0,%eax
  jmp    L104
L41:
  mov    $0x4,%r12d
  test   %r8,%r8
  jne    L82
  mov    $0x5,%esi
  mov    $0x1,%edi
  call   <calloc@plt>
  mov    %rax,%r12
  movb   $0x48,(%rax)
  movb   $0x3,0x1(%rax)
  test   %r15b,%r15b
  jne    L110
  movl   $0x5,0xc(%rsp)
  mov    $0x2,%eax
  jmp    L46
L110:
  movb   $0x1,0x2(%r12)
  movl   $0x5,0xc(%rsp)
L80:
  movb   $0x0,0x3(%r12)
  mov    $0x5,%r13d
  jmp    L21
```

tool_calls: name: parse_data
arguments: label: D0
type: string

tool: D0: SDT service_descriptor size > 255 is not supported (%d)!


assistant: ```c
int ts_sdt_add_service_descriptor(struct ts_sdt *sdt, uint16_t service_id, uint8_t video, char *provider_name, char *service_name) {
  char *name;
  if (!service_name && !provider_name)
    return 0;
  int desc_size = 2 + 1;
  desc_size += 1 + (provider_name ? strlen(provider_name) : 0);
  desc_size += 1 + (service_name ? strlen(service_name) : 0);
  if (desc_size > 257) {
    ts_LOGf("SDT service_descriptor size > 255 is not supported (%d)!\n", desc_size);
    return 0;
  }
  int dpos = 0;
  uint8_t *desc = calloc(1, desc_size);
  desc[dpos + 0] = 0x48;
  desc[dpos + 1] = desc_size - 2;
  desc[dpos + 2] = video ? 0x01 : 0x02;
  desc[dpos + 3] = (provider_name ? strlen(provider_name) : 0);
  dpos += 4;
  if (!provider_name || strlen(provider_name) == 0) {
    dpos++;
  } else {
    name = provider_name;
    while (name[0]) {
      desc[dpos++] = name[0];
      name++;
    }
  }
  if (!service_name || strlen(service_name) == 0) {
    dpos++;
  } else {
    desc[dpos++] = (service_name ? strlen(service_name) : 0);
    name = service_name;
    while (name[0]) {
      desc[dpos++] = name[0];
      name++;
    }
  }
  return ts_sdt_add_stream(sdt, service_id, desc, desc_size);
}
```