dimanche 26 avril 2015

Function template: read file into std::vector

Problem: I'm trying to read a file into a std::vector with a template function: the reading into the vector doesn't work.

The file format I have to parse has some parts where all fields are guaranteed to have the same size: some parts of the file will contain an array of uint16_t fields, while some others will only be an array of uint32_t, or uint64_t, etc.

The base idea is to have a template function that reads into a std::vector passed as reference.

I tried to use std::vector.insert or std::copy but that doesn't work: the vector is always empty (I can guarantee that the file is accessible and can be read). I also checked the documentation about std::istream_iterator.

That's probably just a trivial mistake, but I can't see what's wrong in the below code.

Problem repro code:

#include <iostream>
#include <fstream>
#include <vector>
#include <cstdint>
#include <iterator>

template<typename T, typename A>
void read_vec(std::ifstream& file, std::ifstream::pos_type offset, size_t count, std::vector<T, A>& vec)
{
    file.seekg(offset, std::ios::beg);
    //file.unsetf(std::ios::skipws);

    /* Just test if we can read and dump the file
    T* p = new T[count];

    file.read(reinterpret_cast<char*>(p), count * sizeof(T));
    for (unsigned int i = 0; i < count; ++i){
        T elem = p[i];
        std::cout << "e: " << std::hex << elem << std::endl;
    }
    delete(p);
    */


    /* //method #1
    file.seekg(offset, std::ios::beg);    
    vec.resize(count);

    vec.insert(vec.begin(),
        std::istream_iterator<T>(file),
        std::istream_iterator<T>());
    */

    // method #2
    file.seekg(offset, std::ios::beg);            
    vec.reserve(count);
    std::copy(std::istream_iterator<T>(file),
        std::istream_iterator<T>(),
        std::back_inserter(vec));

}

void parse_file_header(std::ifstream& f)
{
    std::vector<uint16_t> vec;

    read_vec(f, 0x40, 8, vec);

    for (const auto& elem : vec) {
        std::cout << "e: " << std::hex << elem << std::endl;
    }
}

void parse_file(std::string file_path)
{
    std::ifstream file(file_path, std::ios::binary);

    parse_file_header(file);
}


int main(void){

    parse_file("c:\\tmp\\t512_f.dexp");

    return 0;
}

Aucun commentaire:

Enregistrer un commentaire