#include "fs_private.h"

int32_t FS_Read(void *buffer, int32_t length, int32_t handle)
{
    unsigned char *cursor;
    uint32_t remaining;
    uint32_t bytesRead;
    int zeroByteRead;

    FS_CheckFileSystemStarted();

    if (handle == 0) {
        return 0;
    }

    /* ORIGINAL_BINARY_BUG: negative VM byte counts become the original
     * unsigned dword transfer extent; see
     * original-bugs/coduomp-vm-filesystem-negative-byte-count.md. */
    cursor = buffer;
    if (fs_handleFiles[handle].zipArchive != NULL) {
        return Unzip_ReadCurrentFile(
            FS_LoadZipIOFile(fs_handleFiles[handle].ioObject), buffer,
            (uint32_t)length);
    }

    remaining = (uint32_t)length;
    zeroByteRead = 0;
    while (remaining != 0) {
        bytesRead = (uint32_t)fread(
            cursor, 1, remaining,
            FS_LoadIOFile(fs_handleFiles[handle].ioObject));
        if (bytesRead == 0) {
            if (zeroByteRead) {
                return length - (int32_t)remaining;
            }
            zeroByteRead = 1;
        }

        if (bytesRead == UINT32_MAX) {
            if (handle > 50 && handle <= 63) {
                return -1;
            }
            Com_Error(0, "\x15" "FS_Read: -1 bytes read");
        }

        remaining -= bytesRead;
        cursor += bytesRead;
    }

    return length;
}
