static int append_name_to_string_array(MXFMetadataSet* set, const mxfKey* itemKey, const mxfUTF16Char* name) { uint8_t* nameArray = NULL; uint16_t existingNameArraySize = 0; uint16_t nameArraySize = 0; MXFMetadataItem* namesItem = NULL; if (mxf_have_item(set, itemKey)) { CHK_ORET(mxf_get_item(set, itemKey, &namesItem)); existingNameArraySize = namesItem->length; } nameArraySize = existingNameArraySize + (uint16_t)(mxfUTF16Char_extlen * (wcslen(name) + 1)); CHK_MALLOC_ARRAY_ORET(nameArray, uint8_t, nameArraySize); if (existingNameArraySize > 0) { memcpy(nameArray, namesItem->value, existingNameArraySize); } mxf_set_utf16string(name, &nameArray[existingNameArraySize]); CHK_OFAIL(mxf_set_item(set, itemKey, nameArray, nameArraySize)); SAFE_FREE(&nameArray); return 1; fail: SAFE_FREE(&nameArray); return 0; }
static Page* open_page(MXFFileSysData *sysData, int64_t position) { int i; int page; page = (int)(position / sysData->pageSize); if (page > sysData->numPages) { /* only allowed to open pages 0 .. last + 1 */ return 0; } if (page == sysData->numPages) { if (sysData->mode == READ_MODE) { /* no more pages to open */ return 0; } if (sysData->numPages == sysData->numPagesAllocated) { /* reallocate the pages */ Page *newPages; CHK_MALLOC_ARRAY_ORET(newPages, Page, sysData->numPagesAllocated + PAGE_ALLOC_INCR); memcpy(newPages, sysData->pages, sizeof(Page) * sysData->numPagesAllocated); SAFE_FREE(sysData->pages); sysData->pages = newPages; sysData->numPagesAllocated += PAGE_ALLOC_INCR; /* reset the link back from file descriptors to the new pages */ for (i = 0; i < sysData->numPages; i++) { if (sysData->pages[i].fileDescriptor != NULL) { sysData->pages[i].fileDescriptor->page = &sysData->pages[i]; } } } /* set new page data */ memset(&sysData->pages[sysData->numPages], 0, sizeof(Page)); sysData->pages[sysData->numPages].index = sysData->numPages; sysData->numPages++; } /* open the file */ if (!open_file(sysData, &sysData->pages[page])) { return 0; } return &sysData->pages[page]; }
int mxf_read_item(MXFFile* mxfFile, MXFMetadataItem* item, uint16_t len) { uint8_t buffer[65536]; CHK_ORET(mxf_file_read(mxfFile, buffer, len) == len); CHK_MALLOC_ARRAY_ORET(item->value, uint8_t, len); memcpy(item->value, buffer, len); item->length = len; return 1; }
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; }