Esempio n. 1
0
static void remove_test_files()
{
    char filename[4096];
    int count = 0;

    while (1)
    {
        mxf_snprintf(filename, sizeof(filename), g_testFile, count);
        if (remove(filename) != 0)
        {
            break;
        }
        count++;
    }
}
Esempio n. 2
0
int64_t mxf_page_file_get_size(const char *filenameTemplate)
{
    int index = 0;
    char filename[4096];
    struct stat statBuf;
    int64_t size = 0;

    for(;;)
    {
        mxf_snprintf(filename, sizeof(filename), filenameTemplate, index);
        if (stat(filename, &statBuf) != 0)
            break;

        size += statBuf.st_size;

        index++;
    }

    return size;
}
Esempio n. 3
0
int mxf_page_file_remove(const char *filenameTemplate)
{
    int index = 0;
    char filename[4096];

    for(;;)
    {
        mxf_snprintf(filename, sizeof(filename), filenameTemplate, index);
        if (remove(filename) != 0)
        {
            break;
        }

        index++;
    }

    if (index == 0)
    {
        /* first file couldn't be removed or does not exist */
        return 0;
    }

    return 1;
}
Esempio n. 4
0
int mxf_page_file_forward_truncate(MXFPageFile *mxfPageFile)
{
    MXFFileSysData *sysData = mxfPageFile->mxfFile->sysData;
    int page = (int)(sysData->position / sysData->pageSize);
    int i;
    char filename[4096];
#if defined(_WIN32)
    int fileid;
#endif

    if (sysData->mode == READ_MODE)
    {
        mxf_log_error("Cannot forward truncate read-only mxf page file\n");
        return 0;
    }

    /* close and truncate to zero length page files before the current one */
    for (i = 0; i < page; i++)
    {
        if (sysData->pages[i].wasRemoved)
        {
            continue;
        }

        if (sysData->pages[i].fileDescriptor != NULL)
        {
            /* close the file */
            disk_file_close(sysData->pages[i].fileDescriptor);

            /* remove the file descriptor from the list */
            if (sysData->fileDescriptorHead == sysData->pages[i].fileDescriptor)
            {
                sysData->fileDescriptorHead = sysData->fileDescriptorHead->next;
            }
            else
            {
                sysData->pages[i].fileDescriptor->prev->next = sysData->pages[i].fileDescriptor->next;
            }
            if (sysData->fileDescriptorTail == sysData->pages[i].fileDescriptor)
            {
                sysData->fileDescriptorTail = sysData->fileDescriptorTail->prev;
            }
            else
            {
                sysData->pages[i].fileDescriptor->next->prev = sysData->pages[i].fileDescriptor->prev;
            }
            SAFE_FREE(sysData->pages[i].fileDescriptor);
        }

        /* truncate the file to zero length */
        mxf_snprintf(filename, sizeof(filename), sysData->filenameTemplate, sysData->pages[i].index);

#if defined(_WIN32)
        /* WIN32 does not have truncate() so open the file with _O_TRUNC then close it */
        if ((fileid = _open(filename, _O_CREAT | _O_TRUNC, _S_IWRITE)) == -1 ||
            _close(fileid) == -1)
#else
        if (truncate(filename, 0) != 0)
#endif
        {
            mxf_log_warn("Failed to truncate '%s' to zero length: %s\n", filename, strerror(errno));
        }
        sysData->pages[i].wasRemoved = 1;
    }

    return 1;
}
Esempio n. 5
0
int mxf_page_file_open_modify(const char *filenameTemplate, int64_t pageSize, MXFPageFile **mxfPageFile)
{
    MXFFile *newMXFFile = NULL;
    int pageCount;
    int allocatedPages;
    char filename[4096];
    FILE *file;
    int64_t fileSize;


    if (strstr(filenameTemplate, "%d") == NULL)
    {
        mxf_log_error("Filename template '%s' doesn't contain %%d\n", filenameTemplate);
        return 0;
    }

    /* count number of page files */
    pageCount = 0;
    for(;;)
    {
        mxf_snprintf(filename, sizeof(filename), filenameTemplate, pageCount);
        if ((file = fopen(filename, "rb")) == NULL)
        {
            break;
        }
        fclose(file);
        pageCount++;
    }

    if (pageCount == 0)
    {
        /* file not found */
        return 0;
    }

    /* check the size of the first file equals the pageSize */
    if (pageCount > 1)
    {
        mxf_snprintf(filename, sizeof(filename), filenameTemplate, 0);
        fileSize = disk_file_size(filename);
        if (fileSize < 0)
        {
            mxf_log_error("Failed to stat file '%s': %s\n", filename, strerror(errno));
            return 0;
        }
        if (pageSize != fileSize)
        {
            mxf_log_error("Size of first file '%s' (%"PRId64" does not equal page size %"PRId64"\n", filename, fileSize, pageSize);
            return 0;
        }
    }


    CHK_MALLOC_ORET(newMXFFile, MXFFile);
    memset(newMXFFile, 0, sizeof(*newMXFFile));

    newMXFFile->close           = page_file_close;
    newMXFFile->read            = page_file_read;
    newMXFFile->write           = page_file_write;
    newMXFFile->get_char        = page_file_getchar;
    newMXFFile->put_char        = page_file_putchar;
    newMXFFile->eof             = page_file_eof;
    newMXFFile->seek            = page_file_seek;
    newMXFFile->tell            = page_file_tell;
    newMXFFile->is_seekable     = page_file_is_seekable;
    newMXFFile->size            = page_file_size;
    newMXFFile->free_sys_data   = free_page_file;


    CHK_MALLOC_OFAIL(newMXFFile->sysData, MXFFileSysData);
    memset(newMXFFile->sysData, 0, sizeof(*newMXFFile->sysData));

    CHK_OFAIL((newMXFFile->sysData->filenameTemplate = strdup(filenameTemplate)) != NULL);
    newMXFFile->sysData->pageSize = pageSize;
    newMXFFile->sysData->mode = MODIFY_MODE;
    newMXFFile->sysData->mxfPageFile.mxfFile = newMXFFile;


    /* allocate pages */
    allocatedPages = (pageCount < PAGE_ALLOC_INCR) ? PAGE_ALLOC_INCR : pageCount;
    CHK_MALLOC_ARRAY_ORET(newMXFFile->sysData->pages, Page, allocatedPages);
    memset(newMXFFile->sysData->pages, 0, allocatedPages * sizeof(Page));
    newMXFFile->sysData->numPages = pageCount;
    newMXFFile->sysData->numPagesAllocated = allocatedPages;
    for (pageCount = 0; pageCount < newMXFFile->sysData->numPages; pageCount++)
    {
        newMXFFile->sysData->pages[pageCount].index = pageCount;
        newMXFFile->sysData->pages[pageCount].size = pageSize;
    }

    /* set the files size of the last file, which could have size < pageSize */
    mxf_snprintf(filename, sizeof(filename), filenameTemplate, newMXFFile->sysData->numPages - 1);
    fileSize = disk_file_size(filename);
    if (fileSize < 0)
    {
        mxf_log_error("Failed to stat file '%s': %s\n", filename, strerror(errno));
        goto fail;
    }
    newMXFFile->sysData->pages[newMXFFile->sysData->numPages - 1].size = fileSize;


    *mxfPageFile = &newMXFFile->sysData->mxfPageFile;
    return 1;

fail:
    if (newMXFFile != NULL)
    {
        mxf_file_close(&newMXFFile);
    }
    return 0;
}
Esempio n. 6
0
static int open_file(MXFFileSysData *sysData, Page *page)
{
    FILE *newFile = NULL;
    char filename[4096];
    FileDescriptor *newFileDescriptor = NULL;

    if (page->wasRemoved)
    {
        mxf_log_warn("Failed to open mxf page file which was removed after truncation\n");
        return 0;
    }

    /* move file descriptor to tail if already open, and return */
    if (page->fileDescriptor != NULL)
    {
        if (page->fileDescriptor == sysData->fileDescriptorTail)
        {
            return 1;
        }

        /* extract file descriptor */
        if (page->fileDescriptor->next != NULL)
        {
            page->fileDescriptor->next->prev = page->fileDescriptor->prev;
        }
        if (page->fileDescriptor->prev != NULL)
        {
            page->fileDescriptor->prev->next = page->fileDescriptor->next;
        }
        if (sysData->fileDescriptorHead == page->fileDescriptor)
        {
            sysData->fileDescriptorHead = page->fileDescriptor->next;
        }

        /* put file descriptor at tail */
        page->fileDescriptor->next = NULL;
        page->fileDescriptor->prev = sysData->fileDescriptorTail;
        if (sysData->fileDescriptorTail != NULL)
        {
            sysData->fileDescriptorTail->next = page->fileDescriptor;
        }
        sysData->fileDescriptorTail = page->fileDescriptor;

        return 1;
    }


    /* close the least used file descriptor (the head) if too many file descriptors are open */
    if (sysData->numFileDescriptors >= MAX_FILE_DESCRIPTORS)
    {
        if (sysData->fileDescriptorTail == sysData->fileDescriptorHead)
        {
            /* single file descriptor */

            sysData->fileDescriptorHead->page->fileDescriptor = NULL;
            disk_file_close(sysData->fileDescriptorHead);
            SAFE_FREE(sysData->fileDescriptorHead);

            sysData->fileDescriptorHead = NULL;
            sysData->fileDescriptorTail = NULL;
            sysData->numFileDescriptors--;
        }
        else
        {
            /* multiple file descriptors */

            FileDescriptor *newHead = sysData->fileDescriptorHead->next;

            sysData->fileDescriptorHead->page->fileDescriptor = NULL;
            disk_file_close(sysData->fileDescriptorHead);
            SAFE_FREE(sysData->fileDescriptorHead);

            sysData->fileDescriptorHead = newHead;
            newHead->prev = NULL;
            sysData->numFileDescriptors--;
        }
    }

    /* open the file */
    mxf_snprintf(filename, sizeof(filename), sysData->filenameTemplate, page->index);
    switch (sysData->mode)
    {
        case READ_MODE:
            newFile = fopen(filename, "rb");
            break;
        case WRITE_MODE:
            if (!page->wasOpenedBefore)
            {
                newFile = fopen(filename, "w+b");
            }
            else
            {
                newFile = fopen(filename, "r+b");
            }
            break;
        case MODIFY_MODE:
            newFile = fopen(filename, "r+b");
            if (newFile == NULL)
            {
                newFile = fopen(filename, "w+b");
            }
            break;
    }
    if (newFile == NULL)
    {
        mxf_log_error("Failed to open paged mxf file '%s': %s\n", filename, strerror(errno));
        return 0;
    }

    /* create the new file descriptor */
    CHK_MALLOC_OFAIL(newFileDescriptor, FileDescriptor);
    memset(newFileDescriptor, 0, sizeof(*newFileDescriptor));
    newFileDescriptor->file = newFile;
    newFile = NULL;
    newFileDescriptor->page = page;

    page->fileDescriptor = newFileDescriptor;
    page->wasOpenedBefore = 1;
    page->offset = 0;

    if (sysData->fileDescriptorTail != NULL)
    {
        sysData->fileDescriptorTail->next = newFileDescriptor;
    }
    newFileDescriptor->prev = sysData->fileDescriptorTail;
    sysData->fileDescriptorTail = newFileDescriptor;
    if (sysData->fileDescriptorHead == NULL)
    {
        sysData->fileDescriptorHead = newFileDescriptor;
    }
    sysData->numFileDescriptors++;


    return 1;

fail:
    if (newFile != NULL)
    {
        fclose(newFile);
    }
    return 0;
}