// File: lemire[P]validateutf8-experiments/tests/unit.cpp
// Function: test()
void test() {

  // additional tests are from autobahn websocket testsuite https://github.com/crossbario/autobahn-testsuite/tree/master/autobahntestsuite/autobahntestsuite/case
  const char *goodsequences[] = {"a", "\xc3\xb1", "\xe2\x82\xa1", "\xf0\x90\x8c\xbc", "안녕하세요, 세상",
                            "\xc2\x80", // 6.7.2
                            "\xf0\x90\x80\x80", // 6.7.4
                            "\xee\x80\x80", // 6.11.2
                            "\xef\xbb\xbf"
                            };
  const char *badsequences[] = {"\xc3\x28",         // 0
                          "\xa0\xa1",         // 1
                          "\xe2\x28\xa1",     // 2
                          "\xe2\x82\x28",     // 3
                          "\xf0\x28\x8c\xbc", // 4
                          "\xf0\x90\x28\xbc", // 5
                          "\xf0\x28\x8c\x28", // 6
                          "\xc0\x9f",         // 7
                          "\xf5\xff\xff\xff", // 8
                          "\xed\xa0\x81", // 9
                          "\xf8\x90\x80\x80\x80", //10
                          "123456789012345\xed", //11
                          "123456789012345\xf1", //12
                          "123456789012345\xc2", //13
                          "\xC2\x7F", // 14
                          "\xce", // 6.6.1
                          "\xce\xba\xe1", // 6.6.3
                          "\xce\xba\xe1\xbd", // 6.6.4
                          "\xce\xba\xe1\xbd\xb9\xcf", // 6.6.6
                          "\xce\xba\xe1\xbd\xb9\xcf\x83\xce", // 6.6.8
                          "\xce\xba\xe1\xbd\xb9\xcf\x83\xce\xbc\xce", // 6.6.10
                          "\xdf", // 6.14.6
                          "\xef\xbf", // 6.14.7
                          "\x80", 
                          "\x91\x85\x95\x9e",
                          "\x6c\x02\x8e\x18"
                        };
  for (size_t i = 0; i < 9; i++) {
    size_t len = strlen(goodsequences[i]);
    if(active_fastvalidate::lookup2::validate(goodsequences[i], len) != fastvalidate::error_code::SUCCESS) {
        printf("bug goodsequences[%zu]\n", i);
        abort();
    }
    if(active_fastvalidate::lookup3::validate(goodsequences[i], len) != fastvalidate::error_code::SUCCESS) {
        printf("bug goodsequences[%zu]\n", i);
        abort();
    }
    if(active_fastvalidate::lookup4::validate(goodsequences[i], len) != fastvalidate::error_code::SUCCESS) {
        printf("bug goodsequences[%zu]\n", i);
        abort();
    }
  }
  for (size_t i = 0; i < 26; i++) {
    size_t len = strlen(badsequences[i]);
    if(active_fastvalidate::lookup2::validate(badsequences[i], len) != fastvalidate::error_code::UTF8_ERROR) {
        printf("bug lookup2 badsequences[%zu]\n", i);
        abort();
    }
    if(active_fastvalidate::lookup3::validate(badsequences[i], len) != fastvalidate::error_code::UTF8_ERROR) {
        printf("bug lookup3 badsequences[%zu]\n", i);
        abort();
    }
    if(active_fastvalidate::lookup4::validate(badsequences[i], len) != fastvalidate::error_code::UTF8_ERROR) {
        printf("bug lookup4 badsequences[%zu]\n", i);
        abort();
    }
  }
  printf("tests ok.\n");
}

// Assembly:
subq $0x138, %rsp            # imm = 0x138
leaq 0xf0(%rsp), %rdi
leaq 0xfdffa(%rip), %rsi     # 0x103ca0
movl $0x48, %edx
callq 0x2140
leaq 0x20(%rsp), %rdi
leaq 0xfe034(%rip), %rsi     # 0x103cf0
movl $0xd0, %edx
callq 0x2140
movq $0x0, 0x18(%rsp)
cmpq $0x9, 0x18(%rsp)
jae 0x5da3
movq 0x18(%rsp), %rax
movq 0xf0(%rsp,%rax,8), %rdi
callq 0x2090
movq %rax, 0x10(%rsp)
movq 0x18(%rsp), %rax
movq 0xf0(%rsp,%rax,8), %rdi
movq 0x10(%rsp), %rsi
callq 0x23e0
cmpl $0x0, %eax
je 0x5d26
movq 0x18(%rsp), %rsi
leaq 0xf9682(%rip), %rdi     # 0xff39c
movb $0x0, %al
callq 0x2030
callq 0x20d0
movq 0x18(%rsp), %rax
movq 0xf0(%rsp,%rax,8), %rdi
movq 0x10(%rsp), %rsi
callq 0x2440
cmpl $0x0, %eax
je 0x5d5a
movq 0x18(%rsp), %rsi
leaq 0xf964e(%rip), %rdi     # 0xff39c
movb $0x0, %al
callq 0x2030
callq 0x20d0
movq 0x18(%rsp), %rax
movq 0xf0(%rsp,%rax,8), %rdi
movq 0x10(%rsp), %rsi
callq 0x24a0
cmpl $0x0, %eax
je 0x5d8e
movq 0x18(%rsp), %rsi
leaq 0xf961a(%rip), %rdi     # 0xff39c
movb $0x0, %al
callq 0x2030
callq 0x20d0
jmp 0x5d90
movq 0x18(%rsp), %rax
addq $0x1, %rax
movq %rax, 0x18(%rsp)
jmp 0x5ccf
movq $0x0, 0x8(%rsp)
cmpq $0x1a, 0x8(%rsp)
jae 0x5e70
movq 0x8(%rsp), %rax
movq 0x20(%rsp,%rax,8), %rdi
callq 0x2090
movq %rax, (%rsp)
movq 0x8(%rsp), %rax
movq 0x20(%rsp,%rax,8), %rdi
movq (%rsp), %rsi
callq 0x23e0
cmpl $0x1, %eax
je 0x5dfb
movq 0x8(%rsp), %rsi
leaq 0xf95c5(%rip), %rdi     # 0xff3b4
movb $0x0, %al
callq 0x2030
callq 0x20d0
movq 0x8(%rsp), %rax
movq 0x20(%rsp,%rax,8), %rdi
movq (%rsp), %rsi
callq 0x2440
cmpl $0x1, %eax
je 0x5e2b
movq 0x8(%rsp), %rsi
leaq 0xf95b4(%rip), %rdi     # 0xff3d3
movb $0x0, %al
callq 0x2030
callq 0x20d0
movq 0x8(%rsp), %rax
movq 0x20(%rsp,%rax,8), %rdi
movq (%rsp), %rsi
callq 0x24a0
cmpl $0x1, %eax
je 0x5e5b
movq 0x8(%rsp), %rsi
leaq 0xf95a3(%rip), %rdi     # 0xff3f2
movb $0x0, %al
callq 0x2030
callq 0x20d0
jmp 0x5e5d
movq 0x8(%rsp), %rax
addq $0x1, %rax
movq %rax, 0x8(%rsp)
jmp 0x5dac
leaq 0xf959a(%rip), %rdi     # 0xff411
movb $0x0, %al
callq 0x2030
addq $0x138, %rsp            # imm = 0x138
retq
nopw %cs:(%rax,%rax)