Search code examples
c++vectorbuffer

Insert contents of a vector into another vector at certain offest


Without context, here is the basic question: I want to insert the contents of a std::vector<uint8_t> a {0, 3, 6, 8} into a std::vector<uint8_t b {0, 3, 6} in a way so that it results into the vector {0, 3, 6, 8}.

And here is a bit more context to my specific situation: There is a std::vector<uint8_t> called data_file_data. I want to fill this vector with the data of different files, which I do in a for loop:

for (const FileSection &file_section : dict->file_array)
        RepackFile(data_file_data, file_section);

FileSection is a struct containing important information on the file I want to repack, like its offset in data_file_data.

Here is the function that repacks files:

void DictDataManager::RepackFile(std::vector<uint8_t> &data_file_data, const FileSection &file_section)
{
    std::vector<uint8_t> file_data;
    uint32_t file_data_size = is_compressed ? file_section.compressed_file_length : file_section.decompressed_file_length;
    file_data.resize(file_data_size);

    std::ifstream extracted_file(file_section.file_path);
    extracted_file.read(reinterpret_cast<char *>(file_data.data()), file_data_size);
    extracted_file.close();

    if (is_compressed)
        file_data = CompressDataBuffer(file_data, file_section.compressed_file_length);
    
    // What now?
}

The problem is, for example, that I have two files that start at offset 0, but one file has 37956 bytes and the other one has 53856 bytes. The data for both is the same in the first 37956 bytes, so I would be able to overwrite the data in data_file_data without problems after already inserting the data of the first file, and now wanting to insert the data of the second file.

I have been trying to use the insert() function in this manner data_file_data.insert(data_file_data.begin()+file_section.offset, file_data.begin(), file_data.end());, but unfortunately this doesn't overwrite any data, but well, just inserts it, which gives me a significantly larger vector than expected and doesn't reconstruct the original file of course.

So what simple alternative do I have to really just write data from a certain offset, and at the same time also have the vector dynamically allocate a new size, like insert() would do it?


Solution

  • You .resize() the vector to the correct size manually, then std::copy() or std::memcpy() the bytes.

    It might be a good idea to compute the final size once at the beginning, to avoid reallocating several times.

    Also a possible optimization is using std::unique_ptr and std::make_unique_for_overwrite() to avoid zeroing the memory.