int mfs_write (int fd, void *clnt_buf, int size)
{
    int ret;

    if (fds[fd] == -1 || buf_mode[fd] == 'r')
    {
        /* Either the file is not open or it is opened for reading only */

        ret = -1;
        errno = EBADF;
    }
    else if (buf_mode[fd] == 'w')
    {
        /* Write */

        if (buf_off[fd] + size > buf_size[fd])
        {
            extend_mem_file (fd, buf_off[fd] + size);
            buf_size[fd] = (buf_off[fd] + size);
        }

        memcpy ((buf[fd] + buf_off[fd]), clnt_buf, size);
        buf_off[fd] = buf_off[fd] + size;

        ret = size;
    }
    else
    {
        /* Append */

        if (buf_off[fd] != buf_size[fd])
            buf_off[fd] = buf_size[fd];

        extend_mem_file (fd, buf_off[fd] + size);
        buf_size[fd] += size;

        memcpy ((buf[fd] + buf_off[fd]), clnt_buf, size);
        buf_off[fd] = buf_off[fd] + size;

        ret = size;
    }

    return (ret);
}
int mfs_lseek (int fd, int offset, int whence)
{
    int ret;
    long test_off;

    if (fds[fd] == -1)	/* Not open */
    {
        ret = -1;
        errno = EBADF;
    }
    else if (offset < 0 && whence == SEEK_SET)
    {
        ret = -1;
        errno = EINVAL;
    }
    else
    {
        switch (whence)
        {
        case SEEK_SET:
            if (offset > buf_size[fd])
                extend_mem_file (fd, offset);
            buf_off[fd] = offset;
            ret = offset;
            break;

        case SEEK_CUR:
            test_off = buf_off[fd] + offset;

            if (test_off < 0)
            {
                ret = -1;
                errno = EINVAL;
            }
            else
            {
                if (test_off > buf_size[fd])
                    extend_mem_file (fd, test_off);
                buf_off[fd] = test_off;
                ret = test_off;
            }
            break;

        case SEEK_END:
            test_off = buf_size[fd] + offset;

            if (test_off < 0)
            {
                ret = -1;
                errno = EINVAL;
            }
            else
            {
                if (test_off > buf_size[fd])
                    extend_mem_file (fd, test_off);
                buf_off[fd] = test_off;
                ret = test_off;
            }
            break;

        default:
            errno = EINVAL;
            ret = -1;
            break;
        }
    }

    return (ret);
}
Example #3
0
static uint32_t mem_file_write(MXFFileSysData *sysData, const uint8_t *data, uint32_t count)
{
    uint32_t totalWrite = 0;
    size_t posChunkIndex;
    int64_t posChunkPos;
    int64_t numWrite;
    int64_t fileSize;

    if (count == 0 || sysData->readOnly)
        return 0;

    fileSize = mxf_mem_file_get_size(&sysData->mxfMemFile);
    if (sysData->position + count > fileSize) {
        if (sysData->position + count - fileSize > UINT32_MAX ||
            !extend_mem_file(sysData, (uint32_t)(sysData->position + count - fileSize)))
        {
            return 0;
        }

        /* add data from fileSize to sysData->position */
        if (sysData->position > fileSize) {
            size_t endPosChunkIndex;
            int64_t endPosChunkPos;
            int64_t chunkRemainder;
            int64_t originalPos = sysData->position;

            sysData->position = fileSize;
            get_chunk_pos(sysData, &endPosChunkIndex, &endPosChunkPos);
            sysData->position = originalPos;
            assert(endPosChunkPos == sysData->chunks[endPosChunkIndex].size);

            while (1) {
                chunkRemainder = sysData->chunks[endPosChunkIndex].allocSize - sysData->chunks[endPosChunkIndex].size;
                if (fileSize + chunkRemainder >= sysData->position) {
                    sysData->chunks[endPosChunkIndex].size = sysData->position - fileSize;
                    fileSize = sysData->position;
                    break;
                }
                sysData->chunks[endPosChunkIndex].size = sysData->chunks[endPosChunkIndex].allocSize;
                fileSize += chunkRemainder;
                endPosChunkIndex++;
            }
        }
    }


    get_chunk_pos(sysData, &posChunkIndex, &posChunkPos);

    while (totalWrite < count) {
        numWrite = sysData->chunks[posChunkIndex].allocSize - posChunkPos;
        if (numWrite > 0) {
            if (numWrite > count - totalWrite)
                numWrite = count - totalWrite;
            memcpy(&sysData->chunks[posChunkIndex].data[posChunkPos], &data[totalWrite], (uint32_t)numWrite);
            totalWrite += (uint32_t)numWrite;
            sysData->position += numWrite;
            posChunkPos += numWrite;
            if (posChunkPos > sysData->chunks[posChunkIndex].size)
                sysData->chunks[posChunkIndex].size = posChunkPos;
        }

        if (posChunkPos >= sysData->chunks[posChunkIndex].allocSize) {
            posChunkIndex++;
            posChunkPos = 0;
        }
    }

    return totalWrite;
}