compute-runtime/shared/source/device_binary_format/ar/ar_encoder.cpp

65 lines
3.1 KiB
C++

/*
* Copyright (C) 2020 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "device_binary_format/ar/ar_encoder.h"
#include "helpers/debug_helpers.h"
#include "helpers/string.h"
#include <vector>
namespace NEO {
namespace Ar {
ArFileEntryHeader *ArEncoder::appendFileEntry(const ConstStringRef fileName, const ArrayRef<const uint8_t> 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<uint8_t *>(&paddingHeader), reinterpret_cast<uint8_t *>(&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<uint8_t *>(&header), reinterpret_cast<uint8_t *>(&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<ArFileEntryHeader *>(this->fileEntries.data() + newFileHeaderOffset);
}
std::vector<uint8_t> ArEncoder::encode() const {
std::vector<uint8_t> ret;
ret.insert(ret.end(), reinterpret_cast<const uint8_t *>(arMagic.begin()), reinterpret_cast<const uint8_t *>(arMagic.end()));
ret.insert(ret.end(), this->fileEntries.begin(), this->fileEntries.end());
return ret;
}
} // namespace Ar
} // namespace NEO