// File: /workspace/github_c_makefile_star2_O0/chriso[P]columnix/lib/reader.c
// Function: cx_row_group_reader_new
struct cx_row_group_reader *cx_row_group_reader_new(const char *path)
{
    struct cx_row_group_reader *reader = calloc(1, sizeof(*reader));
    if (!reader)
        return NULL;
    reader->file = fopen(path, "rb");
    if (!reader->file)
        goto error;

    // get file size
    int fd = fileno(reader->file);
    struct stat stat;
    if (fstat(fd, &stat))
        goto error;
    size_t file_size = stat.st_size;
    if (!file_size)
        goto error;
    reader->file_size = file_size;

    // mmap the file
    void *mmap_ptr = mmap(NULL, file_size, PROT_READ, MAP_PRIVATE, fd, 0);
    if (mmap_ptr == MAP_FAILED)
        goto error;
    reader->mmap_ptr = mmap_ptr;

    // check the footer
    if (file_size < sizeof(struct cx_footer))
        goto error;
    const struct cx_footer *footer =
        cx_row_group_reader_at(reader, file_size - sizeof(*footer));
    if (footer->magic != CX_FILE_MAGIC || footer->size < sizeof(*footer))
        goto error;

    // future extensions
    if (footer->version != CX_FILE_VERSION)
        goto error;

    // check the file contains the row group headers, column descriptors and
    // string repository
    size_t row_group_headers_size =
        footer->row_group_count * sizeof(struct cx_row_group_header);
    size_t descriptors_size =
        footer->column_count * sizeof(struct cx_column_descriptor);
    size_t headers_size =
        row_group_headers_size + descriptors_size + footer->size;
    if (file_size < headers_size)
        goto error;

    // load strings
    if (footer->strings_offset + footer->strings_size > file_size)
        goto error;
    const void *strings =
        cx_row_group_reader_at(reader, footer->strings_offset);
    reader->strings = cx_column_new_mmapped(CX_COLUMN_STR, CX_ENCODING_NONE,
                                            strings, footer->strings_size, 0);
    if (!reader->strings)
        goto error;

    // cache counts and header locations
    reader->row_count = footer->row_count;
    reader->columns.count = footer->column_count;
    reader->row_groups.count = footer->row_group_count;
    reader->columns.descriptors = cx_row_group_reader_at(
        reader, file_size - footer->size - descriptors_size);
    reader->row_groups.headers =
        cx_row_group_reader_at(reader, file_size - headers_size);
    reader->metadata = footer->metadata;

    return reader;
error:
    if (reader->mmap_ptr)
        munmap(reader->mmap_ptr, reader->file_size);
    if (reader->file)
        fclose(reader->file);
    if (reader->strings)
        cx_column_free(reader->strings);
    free(reader);
    return NULL;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xf0, %rsp
movq %rdi, -0x10(%rbp)
movl $0x1, %edi
movl $0x50, %esi
callq 0x54d0
movq %rax, -0x18(%rbp)
cmpq $0x0, -0x18(%rbp)
jne 0xc4a6
movq $0x0, -0x8(%rbp)
jmp 0xc7b7
movq -0x10(%rbp), %rdi
leaq 0x4b57(%rip), %rsi      # 0x11008
callq 0x5550
movq %rax, %rcx
movq -0x18(%rbp), %rax
movq %rcx, (%rax)
movq -0x18(%rbp), %rax
cmpq $0x0, (%rax)
jne 0xc4cf
jmp 0xc758
movq -0x18(%rbp), %rax
movq (%rax), %rdi
callq 0x55c0
movl %eax, -0x1c(%rbp)
movl -0x1c(%rbp), %edi
leaq -0xb0(%rbp), %rsi
callq 0x59a0
cmpl $0x0, %eax
je 0xc4f7
jmp 0xc758
movq -0x80(%rbp), %rax
movq %rax, -0xb8(%rbp)
cmpq $0x0, -0xb8(%rbp)
jne 0xc511
jmp 0xc758
movq -0xb8(%rbp), %rcx
movq -0x18(%rbp), %rax
movq %rcx, 0x10(%rax)
movq -0xb8(%rbp), %rsi
movl -0x1c(%rbp), %r8d
xorl %eax, %eax
movl %eax, %r9d
movl $0x1, %edx
movl $0x2, %ecx
movq %r9, %rdi
callq 0x55f0
movq %rax, -0xc0(%rbp)
movq $-0x1, %rax
cmpq %rax, -0xc0(%rbp)
jne 0xc55e
jmp 0xc758
movq -0xc0(%rbp), %rcx
movq -0x18(%rbp), %rax
movq %rcx, 0x8(%rax)
cmpq $0x38, -0xb8(%rbp)
jae 0xc57c
jmp 0xc758
movq -0x18(%rbp), %rdi
movq -0xb8(%rbp), %rsi
subq $0x38, %rsi
callq 0xc7d0
movq %rax, -0xc8(%rbp)
movq -0xc8(%rbp), %rax
movabsq $0x7863040378630201, %rcx # imm = 0x7863040378630201
cmpq %rcx, 0x30(%rax)
jne 0xc5be
movq -0xc8(%rbp), %rax
movl 0x28(%rax), %eax
cmpq $0x38, %rax
jae 0xc5c3
jmp 0xc758
movq -0xc8(%rbp), %rax
cmpl $0x1, 0x2c(%rax)
je 0xc5d5
jmp 0xc758
movq -0xc8(%rbp), %rax
movl 0x18(%rax), %eax
shlq $0x4, %rax
movq %rax, -0xd0(%rbp)
movq -0xc8(%rbp), %rax
movl 0x1c(%rax), %eax
imulq $0x18, %rax, %rax
movq %rax, -0xd8(%rbp)
movq -0xd0(%rbp), %rax
addq -0xd8(%rbp), %rax
movq -0xc8(%rbp), %rcx
movl 0x28(%rcx), %ecx
addq %rcx, %rax
movq %rax, -0xe0(%rbp)
movq -0xb8(%rbp), %rax
cmpq -0xe0(%rbp), %rax
jae 0xc636
jmp 0xc758
movq -0xc8(%rbp), %rax
movq (%rax), %rax
movq -0xc8(%rbp), %rcx
addq 0x8(%rcx), %rax
cmpq -0xb8(%rbp), %rax
jbe 0xc659
jmp 0xc758
movq -0x18(%rbp), %rdi
movq -0xc8(%rbp), %rax
movq (%rax), %rsi
callq 0xc7d0
movq %rax, -0xe8(%rbp)
movq -0xe8(%rbp), %rdx
movq -0xc8(%rbp), %rax
movq 0x8(%rax), %rcx
movl $0x5, %edi
xorl %esi, %esi
xorl %eax, %eax
movl %eax, %r8d
callq 0x5730
movq %rax, %rcx
movq -0x18(%rbp), %rax
movq %rcx, 0x20(%rax)
movq -0x18(%rbp), %rax
cmpq $0x0, 0x20(%rax)
jne 0xc6b1
jmp 0xc758
movq -0xc8(%rbp), %rax
movq 0x20(%rax), %rcx
movq -0x18(%rbp), %rax
movq %rcx, 0x18(%rax)
movq -0xc8(%rbp), %rax
movl 0x1c(%rax), %eax
movl %eax, %ecx
movq -0x18(%rbp), %rax
movq %rcx, 0x30(%rax)
movq -0xc8(%rbp), %rax
movl 0x18(%rax), %eax
movl %eax, %ecx
movq -0x18(%rbp), %rax
movq %rcx, 0x40(%rax)
movq -0x18(%rbp), %rdi
movq -0xb8(%rbp), %rsi
movq -0xc8(%rbp), %rax
movl 0x28(%rax), %eax
subq %rax, %rsi
subq -0xd8(%rbp), %rsi
callq 0xc7d0
movq %rax, %rcx
movq -0x18(%rbp), %rax
movq %rcx, 0x28(%rax)
movq -0x18(%rbp), %rdi
movq -0xb8(%rbp), %rsi
subq -0xe0(%rbp), %rsi
callq 0xc7d0
movq %rax, %rcx
movq -0x18(%rbp), %rax
movq %rcx, 0x38(%rax)
movq -0xc8(%rbp), %rax
movl 0x10(%rax), %ecx
movq -0x18(%rbp), %rax
movl %ecx, 0x48(%rax)
movq -0x18(%rbp), %rax
movq %rax, -0x8(%rbp)
jmp 0xc7b7
movq -0x18(%rbp), %rax
cmpq $0x0, 0x8(%rax)
je 0xc778
movq -0x18(%rbp), %rax
movq 0x8(%rax), %rdi
movq -0x18(%rbp), %rax
movq 0x10(%rax), %rsi
callq 0x5790
movq -0x18(%rbp), %rax
cmpq $0x0, (%rax)
je 0xc78e
movq -0x18(%rbp), %rax
movq (%rax), %rdi
callq 0x5220
movq -0x18(%rbp), %rax
cmpq $0x0, 0x20(%rax)
je 0xc7a6
movq -0x18(%rbp), %rax
movq 0x20(%rax), %rdi
callq 0x5990
movq -0x18(%rbp), %rdi
callq 0x50a0
movq $0x0, -0x8(%rbp)
movq -0x8(%rbp), %rax
addq $0xf0, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)