Buffer DeflateFilter::process(const BufferRef& input) { //FIXME bool eof = input.empty(); /* if (input.empty()) { TRACE("process received empty input"); return Buffer(); } */ z_.total_out = 0; z_.next_in = reinterpret_cast<Bytef *>(input.begin()); z_.avail_in = input.size(); Buffer output(input.size() * 1.1 + 12 + 18); z_.next_out = reinterpret_cast<Bytef *>(output.end()); z_.avail_out = output.capacity(); do { if (output.size() > output.capacity() / 2) { z_.avail_out = Buffer::CHUNK_SIZE; output.reserve(output.capacity() + z_.avail_out); } int flushMethod; int expected; if (!eof) { flushMethod = Z_SYNC_FLUSH; // Z_NO_FLUSH expected = Z_OK; } else { flushMethod = Z_FINISH; expected = Z_STREAM_END; } int rv = deflate(&z_, flushMethod); //TRACE("deflate(): rv=%d, avail_in=%d, avail_out=%d, total_out=%ld", rv, z_.avail_in, z_.avail_out, z_.total_out); if (rv != expected) { TRACE("process: deflate() error (%d)", rv); return Buffer(); } } while (z_.avail_out == 0); assert(z_.avail_in == 0); output.resize(z_.total_out); //TRACE("process(%ld bytes, eof=%d) -> %ld", input.size(), eof, z_.total_out); return output; }
Buffer BZip2Filter::process(const BufferRef& input) { if (input.empty()) return Buffer(); int rv = BZ2_bzCompressInit(&bz_, level(), // compression level 0, // no output 0 // work factor ); if (rv != BZ_OK) return Buffer(); bz_.next_in = input.begin(); bz_.avail_in = input.size(); bz_.total_in_lo32 = 0; bz_.total_in_hi32 = 0; Buffer output(input.size() * 1.1 + 12); bz_.next_out = output.end(); bz_.avail_out = output.capacity(); bz_.total_out_lo32 = 0; bz_.total_out_hi32 = 0; rv = BZ2_bzCompress(&bz_, BZ_FINISH); if (rv != BZ_STREAM_END) { BZ2_bzCompressEnd(&bz_); return Buffer(); } if (bz_.total_out_hi32) return Buffer(); // file too large output.resize(bz_.total_out_lo32); rv = BZ2_bzCompressEnd(&bz_); if (rv != BZ_OK) return Buffer(); return output; }
inline bool url_decode(Buffer& value, BufferRef& url) { assert(url.belongsTo(value)); std::size_t left = url.begin() - value.begin(); std::size_t right = left + url.size(); std::size_t i = left; // read pos std::size_t d = left; // write pos while (i != right) { if (value[i] == '%') { if (i + 3 <= right) { int ival; if (hex2int(value.begin() + i + 1, value.begin() + i + 3, ival)) { value[d++] = static_cast<char>(ival); i += 3; } else { return false; } } else { return false; } } else if (value[i] == '+') { value[d++] = ' '; ++i; } else if (d != i) { value[d++] = value[i++]; } else { ++d; ++i; } } url = value.ref(left, d - left); return true; }