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); }
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; }