// File: nmmmnu[P]HM3/test/test_blobref.cc
// Function: test_blobref()
int test_blobref(){
	constexpr size_t SIZE = 256;
	char mem[SIZE];

	for(size_t i = 0; i < SIZE; ++i)
		mem[i] = (char) i;

	BlobRef br{ mem };

	assert(*br.as<uint16_t>(0x00) == htobe16(0x0001)	);
	assert(*br.as<uint16_t>(0x0E) == htobe16(0x0E0F)	);
	assert(*br.as<uint32_t>(0x10) == htobe32(0x10111213)	);

	{
		const char *s = br.as<char>('a', 5);
		assert(strncmp(s, "abcde", 5) == 0);

		// relative
		assert(*br.as<char>(s + 5) == 'f');
	}

	{
		struct TestStruct{
			uint16_t	i;
			char		c;
			char		s[4];
		}__attribute__((__packed__));

		const TestStruct *st = br.as<TestStruct>(0x50);
		assert(st->i    == htobe16(0x5051)	);
		assert(st->c    == 0x52			);
		assert(st->s[0] == 0x53			);
		assert(st->s[1] == 0x54			);
		assert(st->s[2] == 0x55			);
		assert(st->s[3] == 0x56			);

		// relative
		const char *stc = (const char *) st;
		assert(*br.as<char>(stc + sizeof(TestStruct)) == 0x57);
	}

	{
		size_t const max = SIZE / sizeof(uint64_t);

		const uint64_t *u64 = br.as<uint64_t>(0, max);
		assert(u64 != nullptr	);
		assert(u64[      0] == htobe64(0x0001020304050607)	);
		assert(u64[max - 1] == htobe64(0xf8f9fafbFCFDFEFF)	);

		// relative
		const uint64_t *p = & u64[max - 2];
		assert(*br.as<uint64_t>(p + 1) == u64[max - 1]	);
	}

	{
		size_t const max = SIZE / sizeof(uint64_t) ;

		// after last
		assert(br.as<uint64_t>(0, max + 1 ) == nullptr		);
	}

	{
		size_t const max = SIZE / sizeof(uint64_t) ;

		const uint64_t *u64 = br.as<uint64_t>(0, max);

		// relative
		// after last
		const uint64_t *p = & u64[max - 1];
		assert(br.as<uint64_t>(p + 1) == nullptr	);
	}

	// zero size
	assert(br.as<char>(0x00, 0) == nullptr	);

	// nullptr
	assert(br.as<char>(nullptr) == nullptr	);

	return 0;
}

// Assembly:
subq $0x198, %rsp            # imm = 0x198
movq $0x100, 0x190(%rsp) # imm = 0x100
movq $0x0, 0x88(%rsp)
cmpq $0x100, 0x88(%rsp) # imm = 0x100
jae 0x120c
movq 0x88(%rsp), %rax
movb %al, %cl
movq 0x88(%rsp), %rax
movb %cl, 0x90(%rsp,%rax)
movq 0x88(%rsp), %rax
addq $0x1, %rax
movq %rax, 0x88(%rsp)
jmp 0x11cf
leaq 0x78(%rsp), %rdi
leaq 0x90(%rsp), %rsi
callq 0x1950
leaq 0x78(%rsp), %rdi
xorl %esi, %esi
movl $0x1, %edx
callq 0x1980
movzwl (%rax), %eax
movl %eax, 0x24(%rsp)
movl $0x1, %edi
callq 0x17a0
movw %ax, %cx
movl 0x24(%rsp), %eax
movzwl %cx, %ecx
cmpl %ecx, %eax
jne 0x1250
jmp 0x126f
leaq 0xdad(%rip), %rdi       # 0x2004
leaq 0xdd0(%rip), %rsi       # 0x202e
movl $0x15, %edx
leaq 0xdd9(%rip), %rcx       # 0x2043
callq 0x1040
leaq 0x78(%rsp), %rdi
movl $0xe, %esi
movl $0x1, %edx
callq 0x1980
movzwl (%rax), %eax
movl %eax, 0x20(%rsp)
movl $0xe0f, %edi            # imm = 0xE0F
callq 0x17a0
movw %ax, %cx
movl 0x20(%rsp), %eax
movzwl %cx, %ecx
cmpl %ecx, %eax
jne 0x12a4
jmp 0x12c3
leaq 0xdab(%rip), %rdi       # 0x2056
leaq 0xd7c(%rip), %rsi       # 0x202e
movl $0x16, %edx
leaq 0xd85(%rip), %rcx       # 0x2043
callq 0x1040
leaq 0x78(%rsp), %rdi
movl $0x10, %esi
movl $0x1, %edx
callq 0x19d0
movl (%rax), %eax
movl %eax, 0x1c(%rsp)
movl $0x10111213, %edi       # imm = 0x10111213
callq 0x17d0
movl %eax, %ecx
movl 0x1c(%rsp), %eax
cmpl %ecx, %eax
jne 0x12f3
jmp 0x1312
leaq 0xd86(%rip), %rdi       # 0x2080
leaq 0xd2d(%rip), %rsi       # 0x202e
movl $0x17, %edx
leaq 0xd36(%rip), %rcx       # 0x2043
callq 0x1040
leaq 0x78(%rsp), %rdi
movl $0x61, %esi
movl $0x5, %edx
callq 0x1a20
movq %rax, 0x70(%rsp)
movq 0x70(%rsp), %rdi
leaq 0xd77(%rip), %rsi       # 0x20ae
movl $0x5, %edx
callq 0x1030
cmpl $0x0, %eax
jne 0x1348
jmp 0x1367
leaq 0xd65(%rip), %rdi       # 0x20b4
leaq 0xcd8(%rip), %rsi       # 0x202e
movl $0x1b, %edx
leaq 0xce1(%rip), %rcx       # 0x2043
callq 0x1040
movq 0x70(%rsp), %rsi
addq $0x5, %rsi
leaq 0x78(%rsp), %rdi
movl $0x1, %edx
callq 0x1a70
movsbl (%rax), %eax
cmpl $0x66, %eax
jne 0x1389
jmp 0x13a8
leaq 0xd40(%rip), %rdi       # 0x20d0
leaq 0xc97(%rip), %rsi       # 0x202e
movl $0x1e, %edx
leaq 0xca0(%rip), %rcx       # 0x2043
callq 0x1040
leaq 0x78(%rsp), %rdi
movl $0x50, %esi
movl $0x1, %edx
callq 0x1810
movq %rax, 0x68(%rsp)
movq 0x68(%rsp), %rax
movzwl (%rax), %eax
movl %eax, 0x18(%rsp)
movl $0x5051, %edi           # imm = 0x5051
callq 0x17a0
movw %ax, %cx
movl 0x18(%rsp), %eax
movzwl %cx, %ecx
cmpl %ecx, %eax
jne 0x13e7
jmp 0x1406
leaq 0xcfd(%rip), %rdi       # 0x20eb
leaq 0xc39(%rip), %rsi       # 0x202e
movl $0x29, %edx
leaq 0xc42(%rip), %rcx       # 0x2043
callq 0x1040
movq 0x68(%rsp), %rax
movsbl 0x2(%rax), %eax
cmpl $0x52, %eax
jne 0x1416
jmp 0x1435
leaq 0xce7(%rip), %rdi       # 0x2104
leaq 0xc0a(%rip), %rsi       # 0x202e
movl $0x2a, %edx
leaq 0xc13(%rip), %rcx       # 0x2043
callq 0x1040
movq 0x68(%rsp), %rax
movsbl 0x3(%rax), %eax
cmpl $0x53, %eax
jne 0x1445
jmp 0x1464
leaq 0xcc6(%rip), %rdi       # 0x2112
leaq 0xbdb(%rip), %rsi       # 0x202e
movl $0x2b, %edx
leaq 0xbe4(%rip), %rcx       # 0x2043
callq 0x1040
movq 0x68(%rsp), %rax
movsbl 0x4(%rax), %eax
cmpl $0x54, %eax
jne 0x1474
jmp 0x1493
leaq 0xca8(%rip), %rdi       # 0x2123
leaq 0xbac(%rip), %rsi       # 0x202e
movl $0x2c, %edx
leaq 0xbb5(%rip), %rcx       # 0x2043
callq 0x1040
movq 0x68(%rsp), %rax
movsbl 0x5(%rax), %eax
cmpl $0x55, %eax
jne 0x14a3
jmp 0x14c2
leaq 0xc8a(%rip), %rdi       # 0x2134
leaq 0xb7d(%rip), %rsi       # 0x202e
movl $0x2d, %edx
leaq 0xb86(%rip), %rcx       # 0x2043
callq 0x1040
movq 0x68(%rsp), %rax
movsbl 0x6(%rax), %eax
cmpl $0x56, %eax
jne 0x14d2
jmp 0x14f1
leaq 0xc6c(%rip), %rdi       # 0x2145
leaq 0xb4e(%rip), %rsi       # 0x202e
movl $0x2e, %edx
leaq 0xb57(%rip), %rcx       # 0x2043
callq 0x1040
movq 0x68(%rsp), %rax
movq %rax, 0x60(%rsp)
movq 0x60(%rsp), %rsi
addq $0x7, %rsi
leaq 0x78(%rsp), %rdi
movl $0x1, %edx
callq 0x1a70
movsbl (%rax), %eax
cmpl $0x57, %eax
jne 0x151d
jmp 0x153c
leaq 0xc32(%rip), %rdi       # 0x2156
leaq 0xb03(%rip), %rsi       # 0x202e
movl $0x32, %edx
leaq 0xb0c(%rip), %rcx       # 0x2043
callq 0x1040
movq $0x20, 0x58(%rsp)
leaq 0x78(%rsp), %rdi
xorl %esi, %esi
movl $0x20, %edx
callq 0x1aa0
movq %rax, 0x50(%rsp)
cmpq $0x0, 0x50(%rsp)
je 0x1565
jmp 0x1584
leaq 0xc19(%rip), %rdi       # 0x2185
leaq 0xabb(%rip), %rsi       # 0x202e
movl $0x39, %edx
leaq 0xac4(%rip), %rcx       # 0x2043
callq 0x1040
movq 0x50(%rsp), %rax
movq (%rax), %rax
movq %rax, 0x10(%rsp)
movabsq $0x1020304050607, %rdi  # imm = 0x1020304050607
callq 0x1860
movq %rax, %rcx
movq 0x10(%rsp), %rax
cmpq %rcx, %rax
jne 0x15af
jmp 0x15ce
leaq 0xbde(%rip), %rdi       # 0x2194
leaq 0xa71(%rip), %rsi       # 0x202e
movl $0x3a, %edx
leaq 0xa7a(%rip), %rcx       # 0x2043
callq 0x1040
movq 0x50(%rsp), %rax
movq 0xf8(%rax), %rax
movq %rax, 0x8(%rsp)
movabsq $-0x706050403020101, %rdi # imm = 0xF8F9FAFBFCFDFEFF
callq 0x1860
movq %rax, %rcx
movq 0x8(%rsp), %rax
cmpq %rcx, %rax
jne 0x15fd
jmp 0x161c
leaq 0xbb7(%rip), %rdi       # 0x21bb
leaq 0xa23(%rip), %rsi       # 0x202e
movl $0x3b, %edx
leaq 0xa2c(%rip), %rcx       # 0x2043
callq 0x1040
movq 0x50(%rsp), %rax
addq $0xf0, %rax
movq %rax, 0x48(%rsp)
movq 0x48(%rsp), %rsi
addq $0x8, %rsi
leaq 0x78(%rsp), %rdi
movl $0x1, %edx
callq 0x1af0
movq (%rax), %rax
movq 0x50(%rsp), %rcx
cmpq 0xf8(%rcx), %rax
jne 0x1657
jmp 0x1676
leaq 0xb89(%rip), %rdi       # 0x21e7
leaq 0x9c9(%rip), %rsi       # 0x202e
movl $0x3f, %edx
leaq 0x9d2(%rip), %rcx       # 0x2043
callq 0x1040
movq $0x20, 0x40(%rsp)
leaq 0x78(%rsp), %rdi
xorl %esi, %esi
movl $0x21, %edx
callq 0x1aa0
cmpq $0x0, %rax
jne 0x1698
jmp 0x16b7
leaq 0xb70(%rip), %rdi       # 0x220f
leaq 0x988(%rip), %rsi       # 0x202e
movl $0x46, %edx
leaq 0x991(%rip), %rcx       # 0x2043
callq 0x1040
movq $0x20, 0x38(%rsp)
leaq 0x78(%rsp), %rdi
xorl %esi, %esi
movl $0x20, %edx
callq 0x1aa0
movq %rax, 0x30(%rsp)
movq 0x30(%rsp), %rax
addq $0xf8, %rax
movq %rax, 0x28(%rsp)
movq 0x28(%rsp), %rsi
addq $0x8, %rsi
leaq 0x78(%rsp), %rdi
movl $0x1, %edx
callq 0x1af0
cmpq $0x0, %rax
jne 0x1706
jmp 0x1725
leaq 0xb2a(%rip), %rdi       # 0x2237
leaq 0x91a(%rip), %rsi       # 0x202e
movl $0x51, %edx
leaq 0x923(%rip), %rcx       # 0x2043
callq 0x1040
leaq 0x78(%rsp), %rdi
xorl %esi, %esi
xorl %eax, %eax
movl %eax, %edx
callq 0x1a20
cmpq $0x0, %rax
jne 0x173d
jmp 0x175c
leaq 0xb15(%rip), %rdi       # 0x2259
leaq 0x8e3(%rip), %rsi       # 0x202e
movl $0x55, %edx
leaq 0x8ec(%rip), %rcx       # 0x2043
callq 0x1040
leaq 0x78(%rsp), %rdi
xorl %eax, %eax
movl %eax, %esi
movl $0x1, %edx
callq 0x1a70
cmpq $0x0, %rax
jne 0x1777
jmp 0x1796
leaq 0xafb(%rip), %rdi       # 0x2279
leaq 0x8a9(%rip), %rsi       # 0x202e
movl $0x58, %edx
leaq 0x8b2(%rip), %rcx       # 0x2043
callq 0x1040
xorl %eax, %eax
addq $0x198, %rsp            # imm = 0x198
retq