// File: DoubleString[P]RtConverter/src/Json/json_writer.cpp
// Function: Json::utf8ToCodepoint(char const*&, char const*)
static unsigned int utf8ToCodepoint(const char*& s, const char* e) {
  const unsigned int REPLACEMENT_CHARACTER = 0xFFFD;

  unsigned int firstByte = static_cast<unsigned char>(*s);

  if (firstByte < 0x80)
    return firstByte;

  if (firstByte < 0xE0) {
    if (e - s < 2)
      return REPLACEMENT_CHARACTER;

    unsigned int calculated =
        ((firstByte & 0x1F) << 6) | (static_cast<unsigned int>(s[1]) & 0x3F);
    s += 1;
    // oversized encoded characters are invalid
    return calculated < 0x80 ? REPLACEMENT_CHARACTER : calculated;
  }

  if (firstByte < 0xF0) {
    if (e - s < 3)
      return REPLACEMENT_CHARACTER;

    unsigned int calculated = ((firstByte & 0x0F) << 12) |
                              ((static_cast<unsigned int>(s[1]) & 0x3F) << 6) |
                              (static_cast<unsigned int>(s[2]) & 0x3F);
    s += 2;
    // surrogates aren't valid codepoints itself
    // shouldn't be UTF-8 encoded
    if (calculated >= 0xD800 && calculated <= 0xDFFF)
      return REPLACEMENT_CHARACTER;
    // oversized encoded characters are invalid
    return calculated < 0x800 ? REPLACEMENT_CHARACTER : calculated;
  }

  if (firstByte < 0xF8) {
    if (e - s < 4)
      return REPLACEMENT_CHARACTER;

    unsigned int calculated = ((firstByte & 0x07) << 18) |
                              ((static_cast<unsigned int>(s[1]) & 0x3F) << 12) |
                              ((static_cast<unsigned int>(s[2]) & 0x3F) << 6) |
                              (static_cast<unsigned int>(s[3]) & 0x3F);
    s += 3;
    // oversized encoded characters are invalid
    return calculated < 0x10000 ? REPLACEMENT_CHARACTER : calculated;
  }

  return REPLACEMENT_CHARACTER;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movl $0xfffd, -0x1c(%rbp)    # imm = 0xFFFD
movq -0x10(%rbp), %rax
movq (%rax), %rax
movzbl (%rax), %eax
movl %eax, -0x20(%rbp)
cmpl $0x80, -0x20(%rbp)
jae 0x31124
movl -0x20(%rbp), %eax
movl %eax, -0x4(%rbp)
jmp 0x312e9
cmpl $0xe0, -0x20(%rbp)
jae 0x3119b
movq -0x18(%rbp), %rax
movq -0x10(%rbp), %rcx
movq (%rcx), %rcx
subq %rcx, %rax
cmpq $0x2, %rax
jge 0x3114d
movl $0xfffd, -0x4(%rbp)     # imm = 0xFFFD
jmp 0x312e9
movl -0x20(%rbp), %eax
andl $0x1f, %eax
shll $0x6, %eax
movq -0x10(%rbp), %rcx
movq (%rcx), %rcx
movsbl 0x1(%rcx), %ecx
andl $0x3f, %ecx
orl %ecx, %eax
movl %eax, -0x24(%rbp)
movq -0x10(%rbp), %rax
movq (%rax), %rcx
addq $0x1, %rcx
movq %rcx, (%rax)
cmpl $0x80, -0x24(%rbp)
jae 0x3118a
movl $0xfffd, %eax           # imm = 0xFFFD
movl %eax, -0x30(%rbp)
jmp 0x31190
movl -0x24(%rbp), %eax
movl %eax, -0x30(%rbp)
movl -0x30(%rbp), %eax
movl %eax, -0x4(%rbp)
jmp 0x312e9
cmpl $0xf0, -0x20(%rbp)
jae 0x31247
movq -0x18(%rbp), %rax
movq -0x10(%rbp), %rcx
movq (%rcx), %rcx
subq %rcx, %rax
cmpq $0x3, %rax
jge 0x311c8
movl $0xfffd, -0x4(%rbp)     # imm = 0xFFFD
jmp 0x312e9
movl -0x20(%rbp), %eax
andl $0xf, %eax
shll $0xc, %eax
movq -0x10(%rbp), %rcx
movq (%rcx), %rcx
movsbl 0x1(%rcx), %ecx
andl $0x3f, %ecx
shll $0x6, %ecx
orl %ecx, %eax
movq -0x10(%rbp), %rcx
movq (%rcx), %rcx
movsbl 0x2(%rcx), %ecx
andl $0x3f, %ecx
orl %ecx, %eax
movl %eax, -0x28(%rbp)
movq -0x10(%rbp), %rax
movq (%rax), %rcx
addq $0x2, %rcx
movq %rcx, (%rax)
cmpl $0xd800, -0x28(%rbp)    # imm = 0xD800
jb 0x31223
cmpl $0xdfff, -0x28(%rbp)    # imm = 0xDFFF
ja 0x31223
movl $0xfffd, -0x4(%rbp)     # imm = 0xFFFD
jmp 0x312e9
cmpl $0x800, -0x28(%rbp)     # imm = 0x800
jae 0x31236
movl $0xfffd, %eax           # imm = 0xFFFD
movl %eax, -0x34(%rbp)
jmp 0x3123c
movl -0x28(%rbp), %eax
movl %eax, -0x34(%rbp)
movl -0x34(%rbp), %eax
movl %eax, -0x4(%rbp)
jmp 0x312e9
cmpl $0xf8, -0x20(%rbp)
jae 0x312e2
movq -0x18(%rbp), %rax
movq -0x10(%rbp), %rcx
movq (%rcx), %rcx
subq %rcx, %rax
cmpq $0x4, %rax
jge 0x31271
movl $0xfffd, -0x4(%rbp)     # imm = 0xFFFD
jmp 0x312e9
movl -0x20(%rbp), %eax
andl $0x7, %eax
shll $0x12, %eax
movq -0x10(%rbp), %rcx
movq (%rcx), %rcx
movsbl 0x1(%rcx), %ecx
andl $0x3f, %ecx
shll $0xc, %ecx
orl %ecx, %eax
movq -0x10(%rbp), %rcx
movq (%rcx), %rcx
movsbl 0x2(%rcx), %ecx
andl $0x3f, %ecx
shll $0x6, %ecx
orl %ecx, %eax
movq -0x10(%rbp), %rcx
movq (%rcx), %rcx
movsbl 0x3(%rcx), %ecx
andl $0x3f, %ecx
orl %ecx, %eax
movl %eax, -0x2c(%rbp)
movq -0x10(%rbp), %rax
movq (%rax), %rcx
addq $0x3, %rcx
movq %rcx, (%rax)
cmpl $0x10000, -0x2c(%rbp)   # imm = 0x10000
jae 0x312d4
movl $0xfffd, %eax           # imm = 0xFFFD
movl %eax, -0x38(%rbp)
jmp 0x312da
movl -0x2c(%rbp), %eax
movl %eax, -0x38(%rbp)
movl -0x38(%rbp), %eax
movl %eax, -0x4(%rbp)
jmp 0x312e9
movl $0xfffd, -0x4(%rbp)     # imm = 0xFFFD
movl -0x4(%rbp), %eax
popq %rbp
retq
nop