0

I'm trying to read some variable-length-values from a file I created.

The file contains the following:

81 7F 81 01 2F F3 FF

There are two VLVs there, 81 7F and 81 01 which are 255 and 129 in decimal.

I also created some file-reader functions that go like this:

void read_byte_from_file_to(std::fstream& file, uint8_t& to) {
    file.read((char*)&to, 1);
}

unsigned long readVLV(std::fstream& t_midi_file) {
    unsigned long result = 0;
    static unsigned long sum = 0, depth = 0, count = 0;
    uint8_t c;
    read_byte_from_file_to(t_midi_file, c);

    ++count;
    if (c & 0x80) {
        readVLV(t_midi_file);
    }


    sum += (c & 0x7F) << (7 * depth++);

    if (count == depth) {
        result = sum;
        sum = 0;
        depth = 0;
        count = 0;
    }
    return result;
};

While running readVLV n times gives correct answers for the first n VLVs when reading from a file, I absolutely hate how I wrote it, which so much statics parameters and that ugly parameter reset. SO if someone could head me in the right direction I'd be very pleased.

Garmekain
  • 664
  • 5
  • 18

1 Answers1

0

A basic _readVLV which takes the positional state of the function could be done by writing

unsigned long _readVLV(
        std::fstream& t_midi_file,
        unsigned long sum,
        unsigned long depth) {
    uint8_t c;
    read_byte_from_file_to(t_midi_file, c);

    if (c & 0x80) {
        sum += _readVLV(t_midi_file, sum, depth);
        ++depth;
    }

    return (c & 0x7F) << (7 * depth);
}

and creating a global readVLV function that takes the positional information and the file like so

unsigned long readVLV(std::fstream& t_midi_file) {
    unsigned long sum = 0, depth = 0, count = 0;
    return _readVLV(t_midi_file, sum, depth, count);
}
Garmekain
  • 664
  • 5
  • 18