// File: /workspace/github_c_makefile_star2_O0/icebert[P]pblat/lib/udc.c
// Function: udcRead
bits64 udcRead(struct udcFile *file, void *buf, bits64 size)
/* Read a block from file.  Return amount actually read. */
{
file->ios.udc.numReads++;
// if not caching, just fetch the data
if (!udcCacheEnabled() && !sameString(file->protocol, "transparent"))
    {
    int actualSize = file->prot->fetchData(file->url, file->offset, size, buf, file);
    file->offset += actualSize;
    file->ios.udc.bytesRead += actualSize;
    return actualSize;
    }
file->ios.udc.bytesRead += size;

/* Figure out region of file we're going to read, and clip it against file size. */
bits64 start = file->offset;
if (start > file->size)
    return 0;
bits64 end = start + size;
if (end > file->size)
    end = file->size;
size = end - start;
char *cbuf = buf;

/* use read-ahead buffer if present */
bits64 bytesRead = 0;

bits64 raStart;
bits64 raEnd;
while(TRUE)
    {
    if (file->sparseReadAhead)
	{
	raStart = file->sparseRAOffset;
	raEnd = raStart+READAHEADBUFSIZE;
	if (start >= raStart && start < raEnd)
	    {
	    // copy bytes out of rabuf
	    bits64 endInBuf = min(raEnd, end);
	    bits64 sizeInBuf = endInBuf - start;
	    memcpy(cbuf, file->sparseReadAheadBuf + (start-raStart), sizeInBuf);
	    cbuf += sizeInBuf;
	    bytesRead += sizeInBuf;
	    start = raEnd;
	    size -= sizeInBuf;
	    file->offset += sizeInBuf;
	    if (size == 0)
		break;
	    }
	file->sparseReadAhead = FALSE;
	ourMustLseek(&file->ios.sparse,file->fdSparse, start, SEEK_SET);
	}

    bits64 saveEnd = end;
    if (size < READAHEADBUFSIZE)
	{
	file->sparseReadAhead = TRUE;
	if (!file->sparseReadAheadBuf)
	    file->sparseReadAheadBuf = needMem(READAHEADBUFSIZE);
	file->sparseRAOffset = start;
	size = READAHEADBUFSIZE;
	end = start + size;
	if (end > file->size)
	    {
	    end = file->size;
	    size = end - start;
	    }
	}


    /* If we're outside of the window of file we already know is good, then have to
     * consult cache on disk, and maybe even fetch data remotely! */
    if (start < file->startData || end > file->endData)
	{

	if (!udcCachePreload(file, start, size))
	    {
	    verbose(4, "udcCachePreload failed");
	    bytesRead = 0;
	    break;
	    }

	/* Currently only need fseek here.  Would be safer, but possibly
	 * slower to move fseek so it is always executed in front of read, in
	 * case other code is moving around file pointer. */

	ourMustLseek(&file->ios.sparse,file->fdSparse, start, SEEK_SET);
	}

    if (file->sparseReadAhead)
	{
	ourMustRead(&file->ios.sparse,file->fdSparse, file->sparseReadAheadBuf, size);
	end = saveEnd;
	size = end - start;
	}
    else
	{
	ourMustRead(&file->ios.sparse,file->fdSparse, cbuf, size);
	file->offset += size;
	bytesRead += size;
	break;
	}
    }

return bytesRead;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x80, %rsp
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movq %rdx, -0x20(%rbp)
movq -0x10(%rbp), %rax
movq 0x110(%rax), %rcx
addq $0x1, %rcx
movq %rcx, 0x110(%rax)
callq 0x5f810
cmpb $0x0, %al
jne 0x5c401
movq -0x10(%rbp), %rax
movq 0x10(%rax), %rdi
leaq 0x82895(%rip), %rsi     # 0xdec2a
callq 0x6a40
cmpl $0x0, %eax
je 0x5c401
movq -0x10(%rbp), %rax
movq 0x18(%rax), %rax
movq 0x8(%rax), %rax
movq -0x10(%rbp), %rcx
movq 0x8(%rcx), %rdi
movq -0x10(%rbp), %rcx
movq 0x30(%rcx), %rsi
movq -0x20(%rbp), %rcx
movl %ecx, %edx
movq -0x18(%rbp), %rcx
movq -0x10(%rbp), %r8
callq *%rax
movl %eax, -0x24(%rbp)
movslq -0x24(%rbp), %rcx
movq -0x10(%rbp), %rax
addq 0x30(%rax), %rcx
movq %rcx, 0x30(%rax)
movslq -0x24(%rbp), %rcx
movq -0x10(%rbp), %rax
addq 0x118(%rax), %rcx
movq %rcx, 0x118(%rax)
movslq -0x24(%rbp), %rax
movq %rax, -0x8(%rbp)
jmp 0x5c71d
movq -0x20(%rbp), %rcx
movq -0x10(%rbp), %rax
addq 0x118(%rax), %rcx
movq %rcx, 0x118(%rax)
movq -0x10(%rbp), %rax
movq 0x30(%rax), %rax
movq %rax, -0x30(%rbp)
movq -0x30(%rbp), %rax
movq -0x10(%rbp), %rcx
cmpq 0x28(%rcx), %rax
jbe 0x5c43e
movq $0x0, -0x8(%rbp)
jmp 0x5c71d
movq -0x30(%rbp), %rax
addq -0x20(%rbp), %rax
movq %rax, -0x38(%rbp)
movq -0x38(%rbp), %rax
movq -0x10(%rbp), %rcx
cmpq 0x28(%rcx), %rax
jbe 0x5c464
movq -0x10(%rbp), %rax
movq 0x28(%rax), %rax
movq %rax, -0x38(%rbp)
movq -0x38(%rbp), %rax
subq -0x30(%rbp), %rax
movq %rax, -0x20(%rbp)
movq -0x18(%rbp), %rax
movq %rax, -0x40(%rbp)
movq $0x0, -0x48(%rbp)
movq -0x10(%rbp), %rax
cmpl $0x0, 0x5c(%rax)
je 0x5c58d
movq -0x10(%rbp), %rax
movq 0x68(%rax), %rax
movq %rax, -0x50(%rbp)
movq -0x50(%rbp), %rax
addq $0x1000, %rax           # imm = 0x1000
movq %rax, -0x58(%rbp)
movq -0x30(%rbp), %rax
cmpq -0x50(%rbp), %rax
jb 0x5c561
movq -0x30(%rbp), %rax
cmpq -0x58(%rbp), %rax
jae 0x5c561
movq -0x58(%rbp), %rax
cmpq -0x38(%rbp), %rax
jae 0x5c4d8
movq -0x58(%rbp), %rax
movq %rax, -0x78(%rbp)
jmp 0x5c4e0
movq -0x38(%rbp), %rax
movq %rax, -0x78(%rbp)
movq -0x78(%rbp), %rax
movq %rax, -0x60(%rbp)
movq -0x60(%rbp), %rax
subq -0x30(%rbp), %rax
movq %rax, -0x68(%rbp)
movq -0x40(%rbp), %rdi
movq -0x10(%rbp), %rax
movq 0x60(%rax), %rsi
movq -0x30(%rbp), %rax
subq -0x50(%rbp), %rax
addq %rax, %rsi
movq -0x68(%rbp), %rdx
callq 0x6570
movq -0x68(%rbp), %rax
addq -0x40(%rbp), %rax
movq %rax, -0x40(%rbp)
movq -0x68(%rbp), %rax
addq -0x48(%rbp), %rax
movq %rax, -0x48(%rbp)
movq -0x58(%rbp), %rax
movq %rax, -0x30(%rbp)
movq -0x68(%rbp), %rcx
movq -0x20(%rbp), %rax
subq %rcx, %rax
movq %rax, -0x20(%rbp)
movq -0x68(%rbp), %rcx
movq -0x10(%rbp), %rax
addq 0x30(%rax), %rcx
movq %rcx, 0x30(%rax)
cmpq $0x0, -0x20(%rbp)
jne 0x5c55f
jmp 0x5c715
jmp 0x5c561
movq -0x10(%rbp), %rax
movl $0x0, 0x5c(%rax)
movq -0x10(%rbp), %rdi
addq $0xb8, %rdi
addq $0x28, %rdi
movq -0x10(%rbp), %rax
movl 0x58(%rax), %esi
movq -0x30(%rbp), %rdx
xorl %ecx, %ecx
callq 0x5e3b0
movq -0x38(%rbp), %rax
movq %rax, -0x70(%rbp)
cmpq $0x1000, -0x20(%rbp)    # imm = 0x1000
jae 0x5c612
movq -0x10(%rbp), %rax
movl $0x1, 0x5c(%rax)
movq -0x10(%rbp), %rax
cmpq $0x0, 0x60(%rax)
jne 0x5c5ca
movl $0x1000, %edi           # imm = 0x1000
callq 0x40c50
movq %rax, %rcx
movq -0x10(%rbp), %rax
movq %rcx, 0x60(%rax)
movq -0x30(%rbp), %rcx
movq -0x10(%rbp), %rax
movq %rcx, 0x68(%rax)
movq $0x1000, -0x20(%rbp)    # imm = 0x1000
movq -0x30(%rbp), %rax
addq -0x20(%rbp), %rax
movq %rax, -0x38(%rbp)
movq -0x38(%rbp), %rax
movq -0x10(%rbp), %rcx
cmpq 0x28(%rcx), %rax
jbe 0x5c610
movq -0x10(%rbp), %rax
movq 0x28(%rax), %rax
movq %rax, -0x38(%rbp)
movq -0x38(%rbp), %rax
subq -0x30(%rbp), %rax
movq %rax, -0x20(%rbp)
jmp 0x5c612
movq -0x30(%rbp), %rax
movq -0x10(%rbp), %rcx
cmpq 0x78(%rcx), %rax
jb 0x5c631
movq -0x38(%rbp), %rax
movq -0x10(%rbp), %rcx
cmpq 0x80(%rcx), %rax
jbe 0x5c688
movq -0x10(%rbp), %rdi
movq -0x30(%rbp), %rsi
movq -0x20(%rbp), %rdx
callq 0x5e3f0
cmpl $0x0, %eax
jne 0x5c667
movl $0x4, %edi
leaq 0x82715(%rip), %rsi     # 0xded68
movb $0x0, %al
callq 0x60040
movq $0x0, -0x48(%rbp)
jmp 0x5c715
movq -0x10(%rbp), %rdi
addq $0xb8, %rdi
addq $0x28, %rdi
movq -0x10(%rbp), %rax
movl 0x58(%rax), %esi
movq -0x30(%rbp), %rdx
xorl %ecx, %ecx
callq 0x5e3b0
movq -0x10(%rbp), %rax
cmpl $0x0, 0x5c(%rax)
je 0x5c6cf
movq -0x10(%rbp), %rdi
addq $0xb8, %rdi
addq $0x28, %rdi
movq -0x10(%rbp), %rax
movl 0x58(%rax), %esi
movq -0x10(%rbp), %rax
movq 0x60(%rax), %rdx
movq -0x20(%rbp), %rcx
callq 0x5e4f0
movq -0x70(%rbp), %rax
movq %rax, -0x38(%rbp)
movq -0x38(%rbp), %rax
subq -0x30(%rbp), %rax
movq %rax, -0x20(%rbp)
jmp 0x5c710
movq -0x10(%rbp), %rdi
addq $0xb8, %rdi
addq $0x28, %rdi
movq -0x10(%rbp), %rax
movl 0x58(%rax), %esi
movq -0x40(%rbp), %rdx
movq -0x20(%rbp), %rcx
callq 0x5e4f0
movq -0x20(%rbp), %rcx
movq -0x10(%rbp), %rax
addq 0x30(%rax), %rcx
movq %rcx, 0x30(%rax)
movq -0x20(%rbp), %rax
addq -0x48(%rbp), %rax
movq %rax, -0x48(%rbp)
jmp 0x5c715
jmp 0x5c480
movq -0x48(%rbp), %rax
movq %rax, -0x8(%rbp)
movq -0x8(%rbp), %rax
addq $0x80, %rsp
popq %rbp
retq
nopw (%rax,%rax)