status_t CameraMetadata::append(const camera_metadata_t* other) { if (mLocked) { ALOGE("%s: CameraMetadata is locked", __FUNCTION__); return INVALID_OPERATION; } size_t extraEntries = get_camera_metadata_entry_count(other); size_t extraData = get_camera_metadata_data_count(other); resizeIfNeeded(extraEntries, extraData); return append_camera_metadata(mBuffer, other); }
status_t CameraMetadata::resizeIfNeeded(size_t extraEntries, size_t extraData) { if (mBuffer == NULL) { mBuffer = allocate_camera_metadata(extraEntries * 2, extraData * 2); if (mBuffer == NULL) { ALOGE("%s: Can't allocate larger metadata buffer", __FUNCTION__); return NO_MEMORY; } } else { size_t currentEntryCount = get_camera_metadata_entry_count(mBuffer); size_t currentEntryCap = get_camera_metadata_entry_capacity(mBuffer); size_t newEntryCount = currentEntryCount + extraEntries; newEntryCount = (newEntryCount > currentEntryCap) ? newEntryCount * 2 : currentEntryCap; size_t currentDataCount = get_camera_metadata_data_count(mBuffer); size_t currentDataCap = get_camera_metadata_data_capacity(mBuffer); size_t newDataCount = currentDataCount + extraData; newDataCount = (newDataCount > currentDataCap) ? newDataCount * 2 : currentDataCap; if (newEntryCount > currentEntryCap || newDataCount > currentDataCap) { camera_metadata_t *oldBuffer = mBuffer; mBuffer = allocate_camera_metadata(newEntryCount, newDataCount); if (mBuffer == NULL) { ALOGE("%s: Can't allocate larger metadata buffer", __FUNCTION__); return NO_MEMORY; } append_camera_metadata(mBuffer, oldBuffer); free_camera_metadata(oldBuffer); } } return OK; }