How do you Deflate data and put it into a vector?

With zstr, a header-only C++ zlib wrapper library, I’m trying to Deflate a std::string and put it into a std::vector<unsigned char>.

zstr::ostream deflating_stream(std::cout);
deflating_stream.write(content.data(), content.size());

The above code works: it prints the Deflate’d. The problem is, I’m not familiar with C++ streams and I cannot get it into a std::vector. Tried several times in vain with std::ostringstream, std::ostream, std::istringstream, std::istreambuf_iterator, std::streambuf, .rdbuf(), et cetera, and the only thing that came out was an emptiness output (.tellp() == 0).

How do I Deflate a std::string and put it into a std::vector<unsigned char>?


The following is some of my tries. I have no idea how to access the Deflate’d data.

std::istringstream is;
std::ostream ss(is.rdbuf());
zstr::ostream deflating_stream(ss);
deflating_stream.write(
    uncompressed_string.data(),
    uncompressed_string.size()
);
the_vector.insert(
    the_vector.cend(),
    std::istreambuf_iterator<char>(is),
    std::istreambuf_iterator<char>()
);
std::ostringstream oss;
zstr::ostream deflating_stream(oss);
deflating_stream.write(
    uncompressed_string.data(),
    uncompressed_string.size()
);
const std::string deflated = oss.str();
the_vector.insert(
    the_vector.cend(),
    deflated.cbegin(),
    deflated.cend()
);
std::stringstream ss;
zstr::ostream deflating_stream(ss);
deflating_stream.write(
    uncompressed_string.data(),
    uncompressed_string.size()
);
std::string deflated = ss.str();
std::cout << deflated.size(); // Says 0.

Upvotes: 1

Views: 556

Answers (1)

Shawn
Shawn

Reputation: 52579

Something like this works:

#include <iostream>
#include <sstream>
#include <vector>
#include <string>
#include <algorithm>

#include "zstr.hpp"

int main() {
  std::string text{"some text\n"};
  std::stringbuf buffer;
  zstr::ostream compressor{&buffer};

  // Must flush to get complete gzip data in buffer
  compressor << text << std::flush;

  // It's probably easier to use just the string...
  auto compstr = buffer.str();
  std::vector<unsigned char> deflated;
  deflated.resize(compstr.size());
  std::copy(compstr.begin(), compstr.end(), deflated.begin());

  std::cout.write(reinterpret_cast<char *>(deflated.data()), deflated.size());
  return 0;
}

After compiling:

$ ./a.out | zcat
some text

Upvotes: 2

Related Questions