// File: /workspace/github_c_makefile_star2_O0/jsummers[P]deark/src/deark-dbuf.c
// Function: dbuf_read_string
struct de_stringreaderdata *dbuf_read_string(dbuf *f, i64 pos,
	i64 max_bytes_to_scan,
	i64 max_bytes_to_keep,
	unsigned int flags, de_ext_encoding ee)
{
	deark *c = f->c;
	struct de_stringreaderdata *srd;
	i64 foundpos = 0;
	int ret;
	i64 bytes_avail_to_read;
	i64 bytes_to_malloc;
	i64 x_strlen = 0;

	srd = de_malloc(c, sizeof(struct de_stringreaderdata));
	srd->str = ucstring_create(c);
	if(max_bytes_to_scan<0) max_bytes_to_scan = 0;
	if(max_bytes_to_keep<0) max_bytes_to_keep = 0;

	bytes_avail_to_read = max_bytes_to_scan;
	if(bytes_avail_to_read > f->len-pos) {
		bytes_avail_to_read = f->len-pos;
	}
	if(bytes_avail_to_read<0) bytes_avail_to_read = 0;

	srd->bytes_consumed = bytes_avail_to_read; // default

	// From here on, we can safely bail out ("goto done"). The
	// de_stringreaderdata struct is sufficiently valid.

	if(!(flags&DE_CONVFLAG_STOP_AT_NUL) &&
		(max_bytes_to_scan != max_bytes_to_keep))
	{
		// To reduce possible confusion, we require that
		// max_bytes_to_scan==max_bytes_to_keep in this case.
		srd->sz = de_malloc(c, max_bytes_to_keep+1);
		goto done;
	}

	if(flags&DE_CONVFLAG_STOP_AT_NUL) {
		ret = dbuf_search_byte(f, 0x00, pos, bytes_avail_to_read, &foundpos);
		if(ret) {
			srd->found_nul = 1;
		}
		else {
			// No NUL byte found. Could be an error in some formats, but in
			// others NUL is used as separator or as padding, not a terminator.
			foundpos = pos+bytes_avail_to_read;
		}

		x_strlen = foundpos-pos;
		srd->bytes_consumed = x_strlen+1;
	}
	else {
		x_strlen = max_bytes_to_keep;
		srd->bytes_consumed = x_strlen;
	}

	bytes_to_malloc = x_strlen+1;
	if(bytes_to_malloc>(max_bytes_to_keep+1)) {
		bytes_to_malloc = max_bytes_to_keep+1;
		srd->was_truncated = 1;
	}

	srd->sz = de_malloc(c, bytes_to_malloc);
	dbuf_read(f, (u8*)srd->sz, pos, bytes_to_malloc-1); // The last byte remains NUL

	ucstring_append_bytes(srd->str, (const u8*)srd->sz, bytes_to_malloc-1, 0, ee);

	if(flags&DE_CONVFLAG_WANT_UTF8) {
		srd->sz_utf8_strlen = (size_t)ucstring_count_utf8_bytes(srd->str);
		srd->sz_utf8 = de_malloc(c, (i64)srd->sz_utf8_strlen + 1);
		ucstring_to_sz(srd->str, srd->sz_utf8, srd->sz_utf8_strlen + 1, 0, DE_ENCODING_UTF8);
	}

done:
	if(!srd->sz) {
		// Always return a valid sz, even on failure.
		srd->sz = de_malloc(c, 1);
	}
	if((flags&DE_CONVFLAG_WANT_UTF8) && !srd->sz_utf8) {
		// Always return a valid sz_utf8 if it was requested, even on failure.
		srd->sz_utf8 = de_malloc(c, 1);
		srd->sz_utf8_strlen = 0;
	}
	srd->sz_strlen = (size_t)x_strlen;
	return srd;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x60, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movq %rcx, -0x20(%rbp)
movl %r8d, -0x24(%rbp)
movl %r9d, -0x28(%rbp)
movq -0x8(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x30(%rbp)
movq $0x0, -0x40(%rbp)
movq $0x0, -0x60(%rbp)
movq -0x30(%rbp), %rdi
movl $0x38, %esi
callq 0x15b780
movq %rax, -0x38(%rbp)
movq -0x30(%rbp), %rdi
callq 0x1711d0
movq %rax, %rcx
movq -0x38(%rbp), %rax
movq %rcx, 0x18(%rax)
cmpq $0x0, -0x18(%rbp)
jge 0x166531
movq $0x0, -0x18(%rbp)
cmpq $0x0, -0x20(%rbp)
jge 0x166540
movq $0x0, -0x20(%rbp)
movq -0x18(%rbp), %rax
movq %rax, -0x50(%rbp)
movq -0x50(%rbp), %rax
movq -0x8(%rbp), %rcx
movq 0x18(%rcx), %rcx
subq -0x10(%rbp), %rcx
cmpq %rcx, %rax
jle 0x16656d
movq -0x8(%rbp), %rax
movq 0x18(%rax), %rax
subq -0x10(%rbp), %rax
movq %rax, -0x50(%rbp)
cmpq $0x0, -0x50(%rbp)
jge 0x16657c
movq $0x0, -0x50(%rbp)
movq -0x50(%rbp), %rcx
movq -0x38(%rbp), %rax
movq %rcx, (%rax)
movl -0x24(%rbp), %eax
andl $0x1, %eax
cmpl $0x0, %eax
jne 0x1665bd
movq -0x18(%rbp), %rax
cmpq -0x20(%rbp), %rax
je 0x1665bd
movq -0x30(%rbp), %rdi
movq -0x20(%rbp), %rsi
addq $0x1, %rsi
callq 0x15b780
movq %rax, %rcx
movq -0x38(%rbp), %rax
movq %rcx, 0x8(%rax)
jmp 0x16672b
movl -0x24(%rbp), %eax
andl $0x1, %eax
cmpl $0x0, %eax
je 0x16661e
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rdx
movq -0x50(%rbp), %rcx
xorl %esi, %esi
leaq -0x40(%rbp), %r8
callq 0x1667a0
movl %eax, -0x44(%rbp)
cmpl $0x0, -0x44(%rbp)
je 0x1665f5
movq -0x38(%rbp), %rax
movl $0x1, 0x34(%rax)
jmp 0x166601
movq -0x10(%rbp), %rax
addq -0x50(%rbp), %rax
movq %rax, -0x40(%rbp)
movq -0x40(%rbp), %rax
subq -0x10(%rbp), %rax
movq %rax, -0x60(%rbp)
movq -0x60(%rbp), %rcx
addq $0x1, %rcx
movq -0x38(%rbp), %rax
movq %rcx, (%rax)
jmp 0x166631
movq -0x20(%rbp), %rax
movq %rax, -0x60(%rbp)
movq -0x60(%rbp), %rcx
movq -0x38(%rbp), %rax
movq %rcx, (%rax)
movq -0x60(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x58(%rbp)
movq -0x58(%rbp), %rax
movq -0x20(%rbp), %rcx
addq $0x1, %rcx
cmpq %rcx, %rax
jle 0x166665
movq -0x20(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x58(%rbp)
movq -0x38(%rbp), %rax
movl $0x1, 0x30(%rax)
movq -0x30(%rbp), %rdi
movq -0x58(%rbp), %rsi
callq 0x15b780
movq %rax, %rcx
movq -0x38(%rbp), %rax
movq %rcx, 0x8(%rax)
movq -0x8(%rbp), %rdi
movq -0x38(%rbp), %rax
movq 0x8(%rax), %rsi
movq -0x10(%rbp), %rdx
movq -0x58(%rbp), %rcx
subq $0x1, %rcx
callq 0x164d10
movq -0x38(%rbp), %rax
movq 0x18(%rax), %rdi
movq -0x38(%rbp), %rax
movq 0x8(%rax), %rsi
movq -0x58(%rbp), %rdx
subq $0x1, %rdx
movl -0x28(%rbp), %r8d
xorl %ecx, %ecx
callq 0x171fa0
movl -0x24(%rbp), %eax
andl $0x10, %eax
cmpl $0x0, %eax
je 0x166729
movq -0x38(%rbp), %rax
movq 0x18(%rax), %rdi
callq 0x172060
movq %rax, %rcx
movq -0x38(%rbp), %rax
movq %rcx, 0x28(%rax)
movq -0x30(%rbp), %rdi
movq -0x38(%rbp), %rax
movq 0x28(%rax), %rsi
addq $0x1, %rsi
callq 0x15b780
movq %rax, %rcx
movq -0x38(%rbp), %rax
movq %rcx, 0x20(%rax)
movq -0x38(%rbp), %rax
movq 0x18(%rax), %rdi
movq -0x38(%rbp), %rax
movq 0x20(%rax), %rsi
movq -0x38(%rbp), %rax
movq 0x28(%rax), %rdx
addq $0x1, %rdx
xorl %ecx, %ecx
movl $0x2, %r8d
callq 0x172200
jmp 0x16672b
movq -0x38(%rbp), %rax
cmpq $0x0, 0x8(%rax)
jne 0x16674f
movq -0x30(%rbp), %rdi
movl $0x1, %esi
callq 0x15b780
movq %rax, %rcx
movq -0x38(%rbp), %rax
movq %rcx, 0x8(%rax)
movl -0x24(%rbp), %eax
andl $0x10, %eax
cmpl $0x0, %eax
je 0x16678a
movq -0x38(%rbp), %rax
cmpq $0x0, 0x20(%rax)
jne 0x16678a
movq -0x30(%rbp), %rdi
movl $0x1, %esi
callq 0x15b780
movq %rax, %rcx
movq -0x38(%rbp), %rax
movq %rcx, 0x20(%rax)
movq -0x38(%rbp), %rax
movq $0x0, 0x28(%rax)
movq -0x60(%rbp), %rcx
movq -0x38(%rbp), %rax
movq %rcx, 0x10(%rax)
movq -0x38(%rbp), %rax
addq $0x60, %rsp
popq %rbp
retq