1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
|
/*
* 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 <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.reserve(arMagic.size() + 1);
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
|