/* * Copyright (C) 2020-2022 Intel Corporation * * SPDX-License-Identifier: MIT * */ #include "shared/source/device_binary_format/ar/ar_encoder.h" #include "shared/source/helpers/debug_helpers.h" #include "shared/source/helpers/string.h" #include namespace NEO { namespace Ar { ArFileEntryHeader *ArEncoder::appendFileEntry(const ConstStringRef fileName, const ArrayRef fileData) { if (fileName.size() > sizeof(ArFileEntryHeader::identifier) - 1) { return nullptr; // encoding long identifiers is not supported } if (fileName.empty()) { return nullptr; } auto alignedFileSize = fileData.size() + (fileData.size() & 1U); ArFileEntryHeader header = {}; if (padTo8Bytes && (0 != ((fileEntries.size() + sizeof(ArFileEntryHeader)) % 8))) { ArFileEntryHeader paddingHeader = {}; auto paddingName = "pad_" + std::to_string(paddingEntry++); UNRECOVERABLE_IF(paddingName.length() > sizeof(paddingHeader.identifier)); memcpy_s(paddingHeader.identifier, sizeof(paddingHeader.identifier), paddingName.c_str(), paddingName.size()); paddingHeader.identifier[paddingName.size()] = SpecialFileNames::fileNameTerminator; size_t paddingSize = 8U - ((fileEntries.size() + 2 * sizeof(ArFileEntryHeader)) % 8); auto padSizeString = std::to_string(paddingSize); memcpy_s(paddingHeader.fileSizeInBytes, sizeof(paddingHeader.fileSizeInBytes), padSizeString.c_str(), padSizeString.size()); this->fileEntries.reserve(this->fileEntries.size() + sizeof(paddingHeader) + paddingSize + sizeof(header) + alignedFileSize); this->fileEntries.insert(this->fileEntries.end(), reinterpret_cast(&paddingHeader), reinterpret_cast(&paddingHeader + 1)); this->fileEntries.resize(this->fileEntries.size() + paddingSize, ' '); } memcpy_s(header.identifier, sizeof(header.identifier), fileName.begin(), fileName.size()); header.identifier[fileName.size()] = SpecialFileNames::fileNameTerminator; auto sizeString = std::to_string(fileData.size()); UNRECOVERABLE_IF(sizeString.length() > sizeof(header.fileSizeInBytes)); memcpy_s(header.fileSizeInBytes, sizeof(header.fileSizeInBytes), sizeString.c_str(), sizeString.size()); this->fileEntries.reserve(this->fileEntries.size() + sizeof(header) + alignedFileSize); auto newFileHeaderOffset = this->fileEntries.size(); this->fileEntries.insert(this->fileEntries.end(), reinterpret_cast(&header), reinterpret_cast(&header + 1)); this->fileEntries.insert(this->fileEntries.end(), fileData.begin(), fileData.end()); this->fileEntries.resize(this->fileEntries.size() + alignedFileSize - fileData.size(), 0U); // implicit 2-byte alignment return reinterpret_cast(this->fileEntries.data() + newFileHeaderOffset); } std::vector ArEncoder::encode() const { std::vector ret; ret.reserve(arMagic.size() + 1); ret.insert(ret.end(), reinterpret_cast(arMagic.begin()), reinterpret_cast(arMagic.end())); ret.insert(ret.end(), this->fileEntries.begin(), this->fileEntries.end()); return ret; } } // namespace Ar } // namespace NEO